Another reason why SQL_SLAVE_SKIP_COUNTER is bad in MySQL
It is everywhere in the world of MySQL that if your replication is broken because an event caused a duplicate key or a row was not found and it cannot be updated or deleted, then you can use ‘STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; START SLAVE; ‘ and be done with it. In some cases this is fine and you can repair the offending row or statements later on. But what if the statement is part of a multi-statement transaction? Well, then it becomes more interesting, because skipping the offending statement will cause the whole transaction to be skipped. This is well documented in the manual by the way. So here’s a quick example.
3 rows on the master:
Shell
|
1
2
3
4
5
6
7
8
9
|
master> select * from t;
+----+-----+
| id | pid |
+----+-----+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+----+-----+
3 rows in set (0.00 sec)
|
2 on the slave:
Shell
|
1
2
3
4
5
6
7
8
|
slave> select * from t;
+----+-----+
| id | pid |
+----+-----+
| 1 | 1 |
| 3 | 3 |
+----+-----+
2 rows in set (0.00 sec)
|
Execute a transaction on the master to break replication:
Shell
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
master> BEGIN;
Query OK, 0 rows affected (0.00 sec)
master> DELETE FROM t WHERE id = 1;
Query OK, 1 row affected (0.00 sec)
master> DELETE FROM t WHERE id = 2;
Query OK, 1 row affected (0.00 sec)
master> DELETE FROM t WHERE id = 3;
Query OK, 1 row affected (0.00 sec)
master> COMMIT;
Query OK, 0 rows affected (0.01 sec)
|
Broken slave:
Shell
|
1
2
3
4
5
6
7
|
slave> show slave status G
*************************** 1. row ***************************
...
Last_SQL_Errno: 1032
Last_SQL_Error: Could not execute Delete_rows event on table test.t; Can't find record in 't', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000002, end_log_pos 333
...
1 row in set (0.00 sec)
|
An attempt to fix replication only caused bigger inconsistencies on slave:
Shell
|
1
2
3
4
5
6
7
8
9
10
11
|
slave> STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; START SLAVE;
Query OK, 0 rows affected (0.00 sec)
slave> select * from t;
+----+-----+
| id | pid |
+----+-----+
| 1 | 1 |
| 3 | 3 |
+----+-----+
2 rows in set (0.00 sec)
|
This happens because the replication honors transaction boundaries, and is definitely something you should consider the next time you try to use this workaround on a broken slave. Of course, there is pt-table-checksum and pt-table-sync to rescue you when inconsistencies occur, however, prevention is always better than cure. Make sure to put safeguards in place to prevent your slaves from drifting.
Lastly, the example above is for ROW-based replication as my colleague pointed out, but can similarly happen with STATEMENT for example with a duplicate key error. You can optionally fix the error above by temporarily setting slave_exec_mode to IDEMPOTENT so errors because of missing rows are skipped, but then again, it does not apply in all cases like an UPDATE statement that cannot be applied because the row on the slave is missing.
Here is a demonstration of the problem with STATEMENT-based replication:
Shell
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
master> select * from t;
+----+-----+
| id | pid |
+----+-----+
| 4 | 1 |
| 6 | 3 |
+----+-----+
2 rows in set (0.00 sec)
slave> select * from t;
+----+-----+
| id | pid |
+----+-----+
| 4 | 1 |
| 5 | 2 |
| 6 | 3 |
+----+-----+
3 rows in set (0.00 sec)
master> BEGIN;
Query OK, 0 rows affected (0.00 sec)
master> delete from t where id = 4;
Query OK, 1 row affected (0.00 sec)
master> insert into t values (5,2);
Query OK, 1 row affected (0.00 sec)
master> delete from t where id = 6;
Query OK, 1 row affected (0.00 sec)
master> COMMIT;
Query OK, 0 rows affected (0.15 sec)
slave> show slave status G
*************************** 1. row ***************************
...
Last_SQL_Errno: 1062
Last_SQL_Error: Error 'Duplicate entry '5' for key 'PRIMARY'' on query. Default database: 'test'. Query: 'insert into t values (5,2)'
...
1 row in set (0.00 sec)
slave> stop slave; set global sql_slave_skip_counter = 1; start slave;
Query OK, 0 rows affected (0.05 sec)
slave> select * from t;
+----+-----+
| id | pid |
+----+-----+
| 4 | 1 |
| 5 | 2 |
| 6 | 3 |
+----+-----+
3 rows in set (0.00 sec)
|
https://www.percona.com/blog/2013/07/23/another-reason-why-sql_slave_skip_counter-is-bad-in-mysql/
Another reason why SQL_SLAVE_SKIP_COUNTER is bad in MySQL的更多相关文章
- 查看mysql主从配置的状态及修正 slave不启动问题
1.查看master的状态 mysql> show master status; //Position不应该为0 mysql> show processlist; //state状态应 ...
- MySQL Replication 优化和技巧、常见故障解决方法
MySQL 主从同步错误(error)解决(转) sql_slave_skip_counter参数 附: 一些错误信息的处理,主从服务器上的命令,及状态信息. 在从服务器上使用show slave s ...
- mysql主从数据库复制
http://blog.csdn.net/lgh1117/article/details/8786274 http://blog.csdn.net/libraworm/article/details/ ...
- MySQL show slave status命令参数
? Slave_IO_State SHOW PROCESSLIST输出的State字段的拷贝.SHOW PROCESSLIST用于从属I/O线程.如果线程正在试图连接到主服务器,正在等待来自主服务器的 ...
- canal mysql slave
[mysqld] log-bin=mysql-bin #添加这一行就ok binlog-format=ROW #选择row模式 server_id=1 #配置mysql replaction需要定义, ...
- Mysql主从同步问题汇总
data-1-1主机是master,data-1-2是slave Last_IO_Errno: 1236 slave查看show slave status\G; 显示Last_IO_Errno: 12 ...
- Mysql主从---删除master.info和relya-log.info实验
relay-log.info, master.info 这连个文件时在建立复制时产生的,现在主要说明以下问题: 1.如果修改删除master.info文件,复制会中断么? 不会,如果stop slav ...
- MySQL面试宝典
==============================================# 参数==============================================auto ...
- Mysql 主从主主复制总结(详细)
环境:Centos 6.9,Mysql 8.0 配置准备:1.为Centos配置好网络,使用远程工具连接. 2.安装mysql,途径不限.mysql8.0和5.7区别不大,8.0在配置主从的时候默认开 ...
随机推荐
- 对html中iframe的研究
虽然平时不怎么用iframe,但经常在网上听一些前辈说iframe怎样怎样,今天索性对iframe来个大研究,那样就不必去记那些条条框框了,自己体验一遍比看什么都好. 创建两个文件一个index.ht ...
- Java中带包(创建及引用)的类的编译
Java中带包(创建及引用)的类的编译与调试 java源程序的编译大家都知道,也就是cmd中到源文件所在目录下javac **.java即可,当程序中有包声明还能简简单单的直接javac **.jav ...
- psql工具使用(二)
所有psql命令都以 \ 开头 一.使用psql -l查看有哪些数据库: -bash-4.2$ psql -l List of databases Name | Owner | Encodin ...
- Netty——高级内置解码器、编码器、ByteBuf
netty通讯需要对数据进行编码,解码,于是我们需要用到netty的编码器.解码器 netty 提供的解码器 DelimiterBasedFrameDecoder 解决TCP的粘包解码器 Stri ...
- Centos下安装最新版Mono并为windwos服务配置开机启动项
一:安装Mono,此步骤参照官网 1:配置Yum仓库 #Centos 7yum install yum-utils rpm --import "http://keyserver.ubuntu ...
- js写的一个简单的手风琴菜单
1 <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&q ...
- k8s一点
1.kubectl get secret -n kube-system|grep admin-token kubernetes-dashboard-admin-token-9q757 2.kubec ...
- python的Web框架,Django模板标签及模板的继承
模板标签 在传递数据的时候,会有大量的数据展示在浏览器上,而数据会是动态变化的,在html的编写中,数据也是需要动态的,而不能是写死的,如果动态展示呢. 给定的例子数据 views传递数据给html ...
- SqlDataAdapter 对datagridview进行增删改(A)
这种方法主要是双击datagridview单元格,直接进行添加,修改,删除,在实际开发中并不太常用,另一种方法下一次在具体陈述. using System; using System.Collecti ...
- winform 窗体中 Time 控件的用法
作用: 用于背景进程中.通过引发Timer事件,Timer控件可以有规律的隔一段时间执行一次代码.也就是,你可以根据你自己的需要,给Timer控件设置时间,Timer每隔这段时间,就执行一次代码. 属 ...