昨天不少同学讨论《小心,前方有雷 —— sql_slave_skip_counter》,有说作者在玩文字游戏,扯了那么多sql_slave_skip_counter=1不还是跳过一个事务嘛。自己看了几遍原文,好像是那么回事,但又没明白slave_exec_mode参数如何影响。只能说一百个读者有一百种见解,甚至随着读者的切入点、知识的变化而改变。
计划用两篇文章写写跳过复制错误相关的三个参数sql_slave_skip_counter、slave_skip_errors、slave_exec_mode
一、基本环境
VMware10.0+CentOS6.9+MySQL5.7.19
| ROLE | HOSTNAME | BASEDIR | DATADIR | IP | PORT |
| Master | ZST1 | /usr/local/mysql | /data/mysql/mysql3306/data | 192.168.85.132 | 3306 |
| Slave | ZST2 | /usr/local/mysql | /data/mysql/mysql3306/data | 192.168.85.133 | 3306 |
基于Row+Position搭建的一主一从异步复制结构:Master->{Slave}
二、sql_slave_skip_counter官方解释
https://dev.mysql.com/doc/refman/5.7/en/set-global-sql-slave-skip-counter.htmlThis statement skips the next N events from the master. This is useful for recovering from replication stops caused by a statement.SET GLOBAL sql_slave_skip_counter = N
When using this statement, it is important to understand that the binary log is actually organized as a sequence of groups known as event groups. Each event group consists of a sequence of events.
• For transactional tables, an event group corresponds to a transaction.
• For nontransactional tables, an event group corresponds to a single SQL statement.
When you use SET GLOBAL sql_slave_skip_counter to skip events and the result is in the middle of a group, the slave continues to skip events until it reaches the end of the group. Execution then starts with the next event group.
三、测试案例
从官方解释我们知道, sql_slave_skip_counter以event为单位skip,直到skip完第N个event所在的event group才停止。对于事务表,一个event group对应一个事务;对于非事务表,一个event group对应一条SQL语句。一个event group包含多个events。
这里我只针对显式事务模拟insert遇到Duplicate entry(1062错误),知道了问题本质,delete/update中的1032错误类似去分析
3.1、测试数据
主库创建一个事务表和一个非事务表,然后从库往各表写入id=1的记录
# 主库创建测试表 mydba@192.168.85.132,3306 [replcrash]> create table repl_innodb(id int primary key,name1 char(10),name2 char(10)) engine=innodb; mydba@192.168.85.132,3306 [replcrash]> create table repl_myisam(id int primary key,name1 char(10),name2 char(10)) engine=myisam; # 从库往测试表中添加数据,不记入binlog mydba@192.168.85.133,3306 [replcrash]> set sql_log_bin=0; mydba@192.168.85.133,3306 [replcrash]> insert into repl_innodb(id,name1,name2) values(1,'s1062-1','s1062-1'); mydba@192.168.85.133,3306 [replcrash]> insert into repl_myisam(id,name1,name2) values(1,'s1062-1','s1062-1'); mydba@192.168.85.133,3306 [replcrash]> set sql_log_bin=1;