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的更多相关文章

  1. 查看mysql主从配置的状态及修正 slave不启动问题

    1.查看master的状态 mysql> show master status;  //Position不应该为0 mysql> show processlist;  //state状态应 ...

  2. MySQL Replication 优化和技巧、常见故障解决方法

    MySQL 主从同步错误(error)解决(转) sql_slave_skip_counter参数 附: 一些错误信息的处理,主从服务器上的命令,及状态信息. 在从服务器上使用show slave s ...

  3. mysql主从数据库复制

    http://blog.csdn.net/lgh1117/article/details/8786274 http://blog.csdn.net/libraworm/article/details/ ...

  4. MySQL show slave status命令参数

    ? Slave_IO_State SHOW PROCESSLIST输出的State字段的拷贝.SHOW PROCESSLIST用于从属I/O线程.如果线程正在试图连接到主服务器,正在等待来自主服务器的 ...

  5. canal mysql slave

    [mysqld] log-bin=mysql-bin #添加这一行就ok binlog-format=ROW #选择row模式 server_id=1 #配置mysql replaction需要定义, ...

  6. Mysql主从同步问题汇总

    data-1-1主机是master,data-1-2是slave Last_IO_Errno: 1236 slave查看show slave status\G; 显示Last_IO_Errno: 12 ...

  7. Mysql主从---删除master.info和relya-log.info实验

    relay-log.info, master.info 这连个文件时在建立复制时产生的,现在主要说明以下问题: 1.如果修改删除master.info文件,复制会中断么? 不会,如果stop slav ...

  8. MySQL面试宝典

    ==============================================# 参数==============================================auto ...

  9. Mysql 主从主主复制总结(详细)

    环境:Centos 6.9,Mysql 8.0 配置准备:1.为Centos配置好网络,使用远程工具连接. 2.安装mysql,途径不限.mysql8.0和5.7区别不大,8.0在配置主从的时候默认开 ...

随机推荐

  1. docker OCI runtime

    Open Container Initiative(OCI)目前有2个标准:runtime-spec以及image-spec.前者规定了如何运行解压过的filesystem bundle.OCI规定了 ...

  2. HTML5本地储存sessionStorage的销毁数据问题

    前几天项目中用到了本地储存,虽然说也就是几个api,但之前有一个问题一直没有去想,我们知道本地储存分为两种,一种是临时储存,关闭浏览器后数据就会销毁,另外一种是没有时间限制的储存,我们做的这个页面比较 ...

  3. 开启linux远程访问权限

    摘要:今天在Linux服务器上安装了msyql数据库,在本地访问的时候可以访问,但是我想通过远程的方式访问的时候就不能访问了,查询资料后发现,Linux下MySQL默认安装完成后只有本地访问的权限,没 ...

  4. MySQL主主复制以及使用keepalived保证高可用

    1:准备工作 MySQL的安装步骤在此处省略:安装完成一定要做以下准备工作,初始化MySQL,/usr/bin/mysql_secure_installation,设置root密码,删除无效账户以及t ...

  5. python 常用算法学习(1)

    算法就是为了解决某一个问题而采取的具体有效的操作步骤 算法的复杂度,表示代码的运行效率,用一个大写的O加括号来表示,比如O(1),O(n) 认为算法的复杂度是渐进的,即对于一个大小为n的输入,如果他的 ...

  6. Java JDBC的基础知识(四)

    之前学习了如何创建一个数据库工具类,如下: import java.sql.Connection; import java.sql.DriverManager; import java.sql.Res ...

  7. [转载] MySQL的四种事务隔离级别

    本文实验的测试环境:Windows 10+cmd+MySQL5.6.36+InnoDB 一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做 ...

  8. 消息推送SignalR简单实例

    消息推送SignalR:一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信. 功能:当所连接的客户端变得可用时服务器代码可以立即向其推送内容,而不是让服务器等待客户端请 ...

  9. 【 js 性能优化】【源码学习】underscore throttle 与 debounce 节流

    在看 underscore.js 源码的时候,接触到了这样两个方法,很有意思: 我先把实现的代码撂在下面,看不懂的可以先跳过,但是跳过可不是永远跳过哦- 一个是 throttle: _.throttl ...

  10. Code Signal_练习题_differentSymbolsNaive

    Given a string, find the number of different characters in it. Example For s = "cabca", th ...