照理说现在都8102年了,sql_slave_skip_counter应该不再是一个热门的讨论点了,但作为一个经典的容易误导的知识点,不去纸上谈兵,用实验总结一下还是很有必要的。
以下实验是在MySQL 5.6的基于行的主从复制下展开。
主库如下建表,并插入两行记录:
mysql> CREATE TABLE `rpl_test1` (`id` int(11) NOT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
mysql> insert into rpl_test1 select 1;
mysql> insert into rpl_test1 select 2;
除此之外,从库另外插入一条记录:
mysql> insert into rpl_test1 select 4;
此时,主从已经数据不一致。
#主库:
mysql> select * from rpl_test1;
+----+
| id |
+----+
| 1 |
| 2 |
+----+
2 rows in set (0.00 sec)
#从库:
mysql> select * from rpl_test1;
+----+
| id |
+----+
| 1 |
| 2 |
| 4 |
+----+
3 rows in set (0.00 sec)
现在,在主库上执行两个事务:
TR1:插入3、4、5、6,并commit
TR2:插入7、8、9,并commit
在binlog中,对应的event信息如下
+------------+------+-------------+-----------+-------------+---------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------+------+-------------+-----------+-------------+---------------------------------------+
| bin.000018 | 321 | Query | 237303306 | 396 | BEGIN |
| bin.000018 | 396 | Table_map | 237303306 | 451 | table_id: 73 (testdb1.rpl_test1) |
| bin.000018 | 451 | Write_rows | 237303306 | 491 | table_id: 73 flags: STMT_END_F |
| bin.000018 | 491 | Table_map | 237303306 | 546 | table_id: 73 (testdb1.rpl_test1) |
| bin.000018 | 546 | Write_rows | 237303306 | 586 | table_id: 73 flags: STMT_END_F |
| bin.000018 | 586 | Table_map | 237303306 | 641 | table_id: 73 (testdb1.rpl_test1) |
| bin.000018 | 641 | Write_rows | 237303306 | 681 | table_id: 73 flags: STMT_END_F |
| bin.000018 | 681 | Table_map | 237303306 | 736 | table_id: 73 (testdb1.rpl_test1) |
| bin.000018 | 736 | Write_rows | 237303306 | 776 | table_id: 73 flags: STMT_END_F |
| bin.000018 | 776 | Xid | 237303306 | 807 | COMMIT /* xid=176 */ |
| bin.000018 | 807 | Query | 237303306 | 882 | BEGIN |
| bin.000018 | 882 | Table_map | 237303306 | 937 | table_id: 73 (testdb1.rpl_test1) |
| bin.000018 | 937 | Write_rows | 237303306 | 977 | table_id: 73 flags: STMT_END_F |
| bin.000018 | 977 | Table_map | 237303306 | 1032 | table_id: 73 (testdb1.rpl_test1) |
| bin.000018 | 1032 | Write_rows | 237303306 | 1072 | table_id: 73 flags: STMT_END_F |
| bin.000018 | 1072 | Table_map | 237303306 | 1127 | table_id: 73 (testdb1.rpl_test1) |
| bin.000018 | 1127 | Write_rows | 237303306 | 1167 | table_id: 73 flags: STMT_END_F |
| bin.000018 | 1167 | Xid | 237303306 | 1198 | COMMIT /* xid=182 */ |
从库势必在执行到插入4的时候会报错。
Last_SQL_Error: Could not execute Write_rows event on table testdb1.rpl_test1; Duplicate entry '4' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log bin.000018, end_log_pos 586
后面分别讨论 sql_slave_skip_counter 在设置不同的N值时,最后的从库数据情况。
一、sql_slave_skip_counter <= 8
mysql> select * from rpl_test1;
+----+
| id |
+----+
| 1 |
| 2 |
| 4 |
| 7 |
| 8 |
| 9 |
+----+
6 rows in set (0.00 sec)
二、sql_slave_skip_counter = 9