跳过复制错误——sql_slave_skip_counter
昨天不少同学讨论《小心,前方有雷 —— 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.html
SET GLOBAL sql_slave_skip_counter = NThis statement skips the next N events from the master. This is useful for recovering from replication stops caused by a statement.
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;
3.2、transactional tables
主库往事务表中添加数据
# 主库往事务表中添加数据
mydba@192.168.85.132,3306 [replcrash]> begin;
mydba@192.168.85.132,3306 [replcrash]> insert into repl_innodb(id,name1,name2) values(1,'m1062-1','m1062-1');
mydba@192.168.85.132,3306 [replcrash]> insert into repl_innodb(id,name1,name2) values(2,'m1062-2','m1062-2');
mydba@192.168.85.132,3306 [replcrash]> commit;
mydba@192.168.85.132,3306 [replcrash]> select * from repl_innodb;
+----+---------+---------+
| id | name1 | name2 |
+----+---------+---------+
| 1 | m1062-1 | m1062-1 |
| 2 | m1062-2 | m1062-2 |
+----+---------+---------+
很明显,从库先写入数据占用id=1,主库再写入数据,复制将主库id=1的写入记录传递到从库,造成从库key冲突(1062错误)
我们尝试使用sql_slave_skip_counter跳过错误(实际遇到1062写入key冲突,我们应该根据 Duplicate entry 删除从库对应记录)
# 从库跳过“1个”错误,并启动sql_thread
mydba@192.168.85.133,3306 [replcrash]> set global sql_slave_skip_counter=1;
mydba@192.168.85.133,3306 [replcrash]> start slave sql_thread;
mydba@192.168.85.133,3306 [replcrash]> select * from repl_innodb;
+----+---------+---------+
| id | name1 | name2 |
+----+---------+---------+
| 1 | s1062-1 | s1062-1 |
+----+---------+---------+
从库不仅跳过了id=1的记录,还跳过了id=2的记录
分析:主库上的begin..commit之间对事务表的操作记录为一个事务,对应一个event group。id=1应用于从库遇到Duplicate entry错误,我们使用sql_slave_skip_counter跳过这个event之后,还在此group内,需要继续跳过此group中的后续events。因此在从库不会有id=2的记录~
[root@ZST1 logs]# mysqlbinlog -v --base64-output=decode-rows mysql-bin. --start-position=
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at
# :: server id end_log_pos CRC32 0x3a86cd44 Anonymous_GTID last_committed= sequence_number= rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at
# :: server id end_log_pos CRC32 0x83c239df Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
SET @@session.pseudo_thread_id=/*!*/;
SET @@session.foreign_key_checks=, @@session.sql_auto_is_null=, @@session.unique_checks=, @@session.autocommit=/*!*/;
SET @@session.sql_mode=/*!*/;
SET @@session.auto_increment_increment=, @@session.auto_increment_offset=/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=,@@session.collation_connection=,@@session.collation_server=/*!*/;
SET @@session.lc_time_names=/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
==================== repl_innodb表写入id=、2的记录,在一个事务中Start ====================
BEGIN
/*!*/;
# at
# :: server id end_log_pos CRC32 0x0f3612fe Table_map: `replcrash`.`repl_innodb` mapped to number
# at
# :: server id end_log_pos CRC32 0x01de5dbd Write_rows: table id flags: STMT_END_F
### INSERT INTO `replcrash`.`repl_innodb`
### SET
### @=
### @='m1062-1'
### @='m1062-1'
# at
# :: server id end_log_pos CRC32 0xf838b054 Table_map: `replcrash`.`repl_innodb` mapped to number
# at
# :: server id end_log_pos CRC32 0xbd9ae02a Write_rows: table id flags: STMT_END_F
### INSERT INTO `replcrash`.`repl_innodb`
### SET
### @=
### @='m1062-2'
### @='m1062-2'
# at
# :: server id end_log_pos CRC32 0x0292df6a Xid =
COMMIT/*!*/;
==================== repl_innodb表写入id=、2的记录,在一个事务中End ====================
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@ZST1 logs]#
View Binlog
3.3、nontransactional tables
主库往非事务表中添加数据
# 主库往非事务表中添加数据
mydba@192.168.85.132,3306 [replcrash]> begin;
mydba@192.168.85.132,3306 [replcrash]> insert into repl_myisam(id,name1,name2) values(1,'m1062-1','m1062-1');
mydba@192.168.85.132,3306 [replcrash]> insert into repl_myisam(id,name1,name2) values(2,'m1062-2','m1062-2');
mydba@192.168.85.132,3306 [replcrash]> commit;
mydba@192.168.85.132,3306 [replcrash]> select * from repl_myisam;
+----+---------+---------+
| id | name1 | name2 |
+----+---------+---------+
| 1 | m1062-1 | m1062-1 |
| 2 | m1062-2 | m1062-2 |
+----+---------+---------+
同理,从库先写入数据占用id=1,主库再写入数据,复制将主库id=1的写入记录传递到从库,造成从库key冲突(1062错误)
我们尝试使用sql_slave_skip_counter跳过错误(实际遇到1062写入key冲突,我们应该根据 Duplicate entry 删除从库对应记录)
# 从库跳过“1个”错误,并启动sql_thread
mydba@192.168.85.133,3306 [replcrash]> set global sql_slave_skip_counter=1;
mydba@192.168.85.133,3306 [replcrash]> start slave sql_thread;
mydba@192.168.85.133,3306 [replcrash]> select * from repl_myisam;
+----+---------+---------+
| id | name1 | name2 |
+----+---------+---------+
| 1 | s1062-1 | s1062-1 |
| 2 | m1062-2 | m1062-2 |
+----+---------+---------+
从库跳过了id=1的记录,但复制了id=2的记录
分析:主库上的begin..commit之间对非事务表的操作记录为多个事务,每一条SQL语句对应一个event group。id=1应用于从库遇到Duplicate entry错误,我们使用sql_slave_skip_counter跳过这个event之后,已经到了此group的末尾。SQL thread直接从下一个event group开始,这里就是repl_myisam.id=2的那条语句。因此在从库会有id=2的记录~
实际它在执行第一条insert语句后,从库就报1062错误;前面的transactional tables需要在事务commit后从库才报错
[root@ZST1 logs]# mysqlbinlog -v --base64-output=decode-rows mysql-bin. --start-position=
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at
# :: server id end_log_pos CRC32 0x5d208979 Anonymous_GTID last_committed= sequence_number= rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at
# :: server id end_log_pos CRC32 0xe4ce4da8 Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
SET @@session.pseudo_thread_id=/*!*/;
SET @@session.foreign_key_checks=, @@session.sql_auto_is_null=, @@session.unique_checks=, @@session.autocommit=/*!*/;
SET @@session.sql_mode=/*!*/;
SET @@session.auto_increment_increment=, @@session.auto_increment_offset=/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=,@@session.collation_connection=,@@session.collation_server=/*!*/;
SET @@session.lc_time_names=/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
==================== repl_myisam表写入id=1的记录Start ====================
BEGIN
/*!*/;
# at
# :: server id end_log_pos CRC32 0x76a45e15 Table_map: `replcrash`.`repl_myisam` mapped to number
# at
# :: server id end_log_pos CRC32 0xd187097a Write_rows: table id flags: STMT_END_F
### INSERT INTO `replcrash`.`repl_myisam`
### SET
### @=
### @='m1062-1'
### @='m1062-1'
# at
# :: server id end_log_pos CRC32 0xc8210551 Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
COMMIT
/*!*/;
# at
==================== repl_myisam表写入id=1的记录End ====================
# :: server id end_log_pos CRC32 0x22b268fd Anonymous_GTID last_committed= sequence_number= rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at
# :: server id end_log_pos CRC32 0x43061ce5 Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
==================== repl_myisam表写入id=2的记录Start ====================
BEGIN
/*!*/;
# at
# :: server id end_log_pos CRC32 0xe1c084b9 Table_map: `replcrash`.`repl_myisam` mapped to number
# at
# :: server id end_log_pos CRC32 0x56bacb73 Write_rows: table id flags: STMT_END_F
### INSERT INTO `replcrash`.`repl_myisam`
### SET
### @=
### @='m1062-2'
### @='m1062-2'
# at
# :: server id end_log_pos CRC32 0x6527c3b6 Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
COMMIT
/*!*/;
==================== repl_myisam表写入id=2的记录End ====================
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@ZST1 logs]#
View Binlog
3.4、一个事务中包含事务表和非事务表操作
为了方便,我将表中数据置为初始状态,主库两表为空,从库两表各有id=1的记录
主库往事务表和非事务表中添加数据
# 主库往事务表、非事务表中添加数据
mydba@192.168.85.132,3306 [replcrash]> begin;
mydba@192.168.85.132,3306 [replcrash]> insert into repl_innodb(id,name1,name2) values(1,'m1062-1','m1062-1');
mydba@192.168.85.132,3306 [replcrash]> insert into repl_innodb(id,name1,name2) values(2,'m1062-2','m1062-2');
mydba@192.168.85.132,3306 [replcrash]> insert into repl_myisam(id,name1,name2) values(1,'m1062-1','m1062-1');
mydba@192.168.85.132,3306 [replcrash]> insert into repl_myisam(id,name1,name2) values(2,'m1062-2','m1062-2');
mydba@192.168.85.132,3306 [replcrash]> commit;
mydba@192.168.85.132,3306 [replcrash]> select * from repl_innodb;
+----+---------+---------+
| id | name1 | name2 |
+----+---------+---------+
| 1 | m1062-1 | m1062-1 |
| 2 | m1062-2 | m1062-2 |
+----+---------+---------+
mydba@192.168.85.132,3306 [replcrash]> select * from repl_myisam;
+----+---------+---------+
| id | name1 | name2 |
+----+---------+---------+
| 1 | m1062-1 | m1062-1 |
| 2 | m1062-2 | m1062-2 |
+----+---------+---------+
根据前面的分析,我们知道从库上的repl_innodb、repl_myisam表都存在key冲突(1062错误)
我们尝试使用sql_slave_skip_counter跳过错误(实际遇到1062写入key冲突,我们应该根据 Duplicate entry 删除从库对应记录)
# 从库跳过“1个”错误,并启动sql_thread
mydba@192.168.85.133,3306 [replcrash]> set global sql_slave_skip_counter=1;
mydba@192.168.85.133,3306 [replcrash]> start slave sql_thread;
mydba@192.168.85.133,3306 [replcrash]> select * from repl_innodb;
+----+---------+---------+
| id | name1 | name2 |
+----+---------+---------+
| 1 | s1062-1 | s1062-1 |
+----+---------+---------+
mydba@192.168.85.133,3306 [replcrash]> select * from repl_myisam;
+----+---------+---------+
| id | name1 | name2 |
+----+---------+---------+
| 1 | s1062-1 | s1062-1 |
| 2 | m1062-2 | m1062-2 |
+----+---------+---------+
从库repl_innodb表暂时没有操作;从库repl_myisam表跳过id=1的记录,复制了id=2的记录
注意:此时跳过的是replcrash.repl_myisam上的Duplicate entry错误,对于非事务表一条SQL语句对应一个event group,SQL thread直接从下一个event group开始,这里就是repl_myisam.id=2的那条语句。因此从库repl_myisam表会有id=2的记录~
紧接着复制又会报key冲突(1062错误),因为还有repl_innodb.id=1这个key,我们继续跳过
# 从库跳过“1个”错误,并启动sql_thread
mydba@192.168.85.133,3306 [replcrash]> set global sql_slave_skip_counter=1;
mydba@192.168.85.133,3306 [replcrash]> start slave sql_thread;
mydba@192.168.85.133,3306 [replcrash]> select * from repl_innodb;
+----+---------+---------+
| id | name1 | name2 |
+----+---------+---------+
| 1 | s1062-1 | s1062-1 |
+----+---------+---------+
mydba@192.168.85.133,3306 [replcrash]> select * from repl_myisam;
+----+---------+---------+
| id | name1 | name2 |
+----+---------+---------+
| 1 | s1062-1 | s1062-1 |
| 2 | m1062-2 | m1062-2 |
+----+---------+---------+
从库repl_innodb表跳过id=1的记录,还跳过了id=2的记录;从库repl_myisam表暂时没有操作
主库上执行的语句明明是先insert repl_innodb,再insert repl_myisam,为什么sql_slave_skip_counter是先跳过repl_myisam表上的错误,再跳过repl_innodb上的错误?
这就要从事务表和非事务表的区别去分析,主库显式的在一个事务中操作事务表+非事务表,实际上所有对事务表的操作是在同一个显式事务中;所有对非事务表的操作,每条SQL语句单独对应一个事务。因此主库上的操作可理解成下面操作:
开启显式事务1,往repl_innodb表写入id=1、2两条记录-->开启事务2,往repl_myisam表写入id=1记录,提交事务2-->开启事务3,往repl_myisam表写入id=2记录,提交事务3-->提交显式事务1
当事务2提交后,从库报repl_myisam上的Duplicate entry错误;我们跳过这个错误,当事务3提交后,从库写入repl_myisam.id=2的记录;当事务1提交后,从库报repl_innodb上的Duplicate entry错误;我们再跳过这个错误,复制就正常了~
我们看下对应的binlog
[root@ZST1 logs]# mysqlbinlog -v --base64-output=decode-rows mysql-bin. --start-position=
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at
# :: server id end_log_pos CRC32 0x9a009a72 Anonymous_GTID last_committed= sequence_number= rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at
# :: server id end_log_pos CRC32 0x9738837a Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
SET @@session.pseudo_thread_id=/*!*/;
SET @@session.foreign_key_checks=, @@session.sql_auto_is_null=, @@session.unique_checks=, @@session.autocommit=/*!*/;
SET @@session.sql_mode=/*!*/;
SET @@session.auto_increment_increment=, @@session.auto_increment_offset=/*!*/;
/*!\C utf8 *//*!*/;
SET @@session.character_set_client=,@@session.collation_connection=,@@session.collation_server=/*!*/;
SET @@session.lc_time_names=/*!*/;
SET @@session.collation_database=DEFAULT/*!*/;
==================== repl_myisam表写入id=1的记录Start ====================
BEGIN
/*!*/;
# at
# :: server id end_log_pos CRC32 0x8c4283c5 Table_map: `replcrash`.`repl_myisam` mapped to number
# at
# :: server id end_log_pos CRC32 0xd8953aae Write_rows: table id flags: STMT_END_F
### INSERT INTO `replcrash`.`repl_myisam`
### SET
### @=
### @='m1062-1'
### @='m1062-1'
# at
# :: server id end_log_pos CRC32 0x218fdb23 Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
COMMIT
/*!*/;
# at
==================== repl_myisam表写入id=1的记录End ====================
# :: server id end_log_pos CRC32 0x0ba119ad Anonymous_GTID last_committed= sequence_number= rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at
# :: server id end_log_pos CRC32 0x9bcdeee5 Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
==================== repl_myisam表写入id=2的记录Start ====================
BEGIN
/*!*/;
# at
# :: server id end_log_pos CRC32 0xd52491e6 Table_map: `replcrash`.`repl_myisam` mapped to number
# at
# :: server id end_log_pos CRC32 0x23bcd75d Write_rows: table id flags: STMT_END_F
### INSERT INTO `replcrash`.`repl_myisam`
### SET
### @=
### @='m1062-2'
### @='m1062-2'
# at
# :: server id end_log_pos CRC32 0x3ba9a1a1 Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
COMMIT
/*!*/;
# at
==================== repl_myisam表写入id=2的记录End ====================
# :: server id end_log_pos CRC32 0x122cdb79 Anonymous_GTID last_committed= sequence_number= rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at
# :: server id end_log_pos CRC32 0x68d45d7b Query thread_id= exec_time= error_code=
SET TIMESTAMP=/*!*/;
==================== repl_innodb表写入id=、2的记录,在一个事务中Start ====================
BEGIN
/*!*/;
# at
# :: server id end_log_pos CRC32 0xf4359a8d Table_map: `replcrash`.`repl_innodb` mapped to number
# at
# :: server id end_log_pos CRC32 0x9975aac8 Write_rows: table id flags: STMT_END_F
### INSERT INTO `replcrash`.`repl_innodb`
### SET
### @=
### @='m1062-1'
### @='m1062-1'
# at
# :: server id end_log_pos CRC32 0xc5ac7f71 Table_map: `replcrash`.`repl_innodb` mapped to number
# at
# :: server id end_log_pos CRC32 0x1ad72c78 Write_rows: table id flags: STMT_END_F
### INSERT INTO `replcrash`.`repl_innodb`
### SET
### @=
### @='m1062-2'
### @='m1062-2'
# at
# :: server id end_log_pos CRC32 0x4f265b37 Xid =
COMMIT/*!*/;
==================== repl_innodb表写入id=、2的记录,在一个事务中End ====================
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@ZST1 logs]#
View Binlog
可以看到binlog和我们的分析一致,也从侧面说明binlog是按事务提交顺序写入的(Redo按事务发生顺序写入)
3.5、N应该设多大
# 主库往非事务表中添加数据
mydba@192.168.85.132,3306 [replcrash]> insert into repl_myisam(id,name1,name2) values(1,'m1062-1','m1062-1');
我们习惯性在skip错误的时候,将N设成1。潜移默化地认为1就是跳过一个错误,管它一个event、一个event group、一条SQL语句、一个事务,反正它就是跳过去了。
根据官方解释,这条对非事务表的insert操作语句,对应一个event group,它里面实际有多个events,而不是只有一个event!
使用set global sql_slave_skip_counter=1,跳过一个event,由于它还在event group中,它会继续跳过此group中的后续events!如果只看表象的话,还真以为它在binlog中只有一个event(⊙_⊙)
可以用下面方法验证,它不只对应一个event
# 从库设置sql_slave_skip_counter
mydba@192.168.85.133,3306 [replcrash]> stop slave sql_thread;
mydba@192.168.85.133,3306 [replcrash]> set global sql_slave_skip_counter=100;
mydba@192.168.85.133,3306 [replcrash]> start slave sql_thread; # 主库往非事务表中添加数据(主库空表,从库存在id=1的记录)
mydba@192.168.85.132,3306 [replcrash]> insert into repl_myisam(id,name1,name2) values(1,'m1062-1','m1062-1'); # 从库查看Skip_Counter计数
mydba@192.168.85.133,3306 [replcrash]> pager grep Skip_Counter;
mydba@192.168.85.133,3306 [replcrash]> show slave status\G
Skip_Counter: 95
在从库设置跳过100个events,然后在主库执行这条语句,再到从库查看show slave status\G返回的Skip_Counter列,你会发现它并不是由100变成99,至于一条语句到底对应多少个events,得自行脑补●-●
不要以为在3.4中set global sql_slave_skip_counter=3;就能跳过repl_myisam.id=1、repl_myisam.id=2、repl_innodb.id=1对应的三条SQL语句
四、总结
写了那么多,感觉也在玩文字游戏。 sql_slave_skip_counter以event为单位skip,直到skip完第N个event所在的event group才停止。对于事务表,一个event group对应一个事务;对于非事务表,一个event group对应一条SQL语句。一个event group包含多个events。
delete在从库找不到对应行,sql_slave_skip_counter可能省事,但极有可能跳过其他events,导致主从数据不一致。对于1032、1062错误尽量修补数据,让复制进程在从库应用变更。
跳过复制错误——sql_slave_skip_counter的更多相关文章
- mysql主从复制跳过复制错误【转】
跳过复制错误 mysql因为binlog机制问题,有些时候会出现从库重放sql执行失败的情况,特别是旧的STATEMENT模式最容易出现这种情况(因为函数和存储过程等原因),这也是为什么强调使用mix ...
- MySQL-Utilities:mysqldbcompare及跳过复制错误
mysqldbcompare也是MySQL-Utilities工具集的一个脚本.mysqldbcompare从两个数据库比较对象和数据的不同.数据库中的对象包括:表.视图.触发器.存储过程.函数和事件 ...
- 跳过复制错误——slave_skip_errors、slave_exec_mode
这一篇写写复制错误处理相关的另两个参数slave_skip_errors.slave_exec_mode,基本环境参考<复制错误处理——sql_slave_skip_counter> 一. ...
- MySQL Replication--跳过复制错误
在MySQL中,有两种跳过复制错误的方法:1.对于未使用GTID的复制,可以使用sql_slave_skip_counter来跳过错误2.对于使用GTID的复制,可以使用GTID_NEXT模拟空事务来 ...
- 【转】如何使用slave_exec_mode优雅的跳过1032 1062的复制错误
今天线上的主从复制发生1062的错误,使用sql_slave_skip_counter跳过之后,由于后面的事务需要对刚刚的数据进行update,后续造成了新的1032的错误. 后来,无意中发现还有更好 ...
- mysql 5.6在gtid复制模式下复制错误,如何跳过??
mysql 5.6在gtid复制模式下复制错误,如何跳过?? http://www.xuchanggang.cn/archives/918.html
- replicate-do-db参数引起的MySQL复制错误及处理办法
replicate-do-db配置在MySQL从库的my.cnf文件中,可以指定只复制哪个库的数据.但是这个参数有个问题就是主库如果在其他的schema环境下操作,其binlog不会被从库应用,从而出 ...
- JSP中,当页面为404或者500时。设置跳转到错误提示页面
最好的就是在WEB.XML文件中配置错误代码的跳转页面,首先建立个 出现500错误的页面,提示出错了,然后再WEB.XML文件中配置,配置如下 一. 通过错误码来配置error-page <er ...
- MySQL复制错误1837的相关缺陷一例
故障现象 主从gtid报错,复制错误1837,这个复制故障可以说是第一次遇到. Last_Errno: 1837 Last_Error: Error 'When @@SESSION.GTID_NEXT ...
随机推荐
- 如何在一个电脑上同时使用两个Git的账号
前言 又需要登录公司的账号,又想在电脑上使用自己的账号. 实现 首先是git config方面的设置,要取消掉原本对于git账号的全局设置. git config --global --unset u ...
- PAT甲题题解-1036. Boys vs Girls (25)-找最大最小,大水题
题意:给出n个人的姓名.性别.ID.分数,让你找出其中哪个妹纸分数最高.哪个汉子分数最低.以及他们的差如果没有妹纸或者汉子,则对应输出Absent,差用NA代替. 就是for一遍找最大最小值,水题 # ...
- 1089. Insert or Merge (25)-判断插入排序还是归并排序
判断插入排序很好判断,不是的话那就是归并排序了. 由于归并排序区间是2.4.8开始递增的,所以要判断给出的归并排序执行到哪一步,就要k从2开始枚举. 然后再对每个子区间进行一下sort即可. #inc ...
- Linux内核分析— —计算机是如何工作的(20135213林涵锦)
实验部分 (以下命令为实验楼64位Linux虚拟机环境下适用,32位Linux环境可能会稍有不同) 使用 gcc –S –o main.s main.c -m32 命令编译成汇编代码, int g(i ...
- 每日Scrum(8)
今天:在程序中嵌入剖面图,进行美化 明天:测试分析,找学弟学妹来体验我们的软件 任务看板: 燃尽图:
- 班级博客与coding地址
队名 队长 成员1 成员2 成员3 成员4 成员5 团队博客地址 奥特曼小分队 李全清 胡林状 王栋 孙杏子 孙乐 刘泽良 http://www.cnblogs.com/atmxfd/ 蜗牛上天队 仝 ...
- 使用Samba服务程序,让linux系统之间共享文件
yum install -y cifs-utils mkdir /database 创建挂载目录 在root家目录创建认证文件(依次为SMB用户名.SMB用户密码.SMB共享域) v ...
- PSP(3.13——3.15)以及周记录
3.13 0:00 4:00 10 230 Cordova插件1,的尝试 N min 10:50 11:30 10 30 英语百词斩 N min 18:00 22:55 20 275 写博客 Y mi ...
- linux客户端WinSCP
WinSCP是一个Windows环境下使用SSH的开源图形化SFTP客户端.同时支持SCP协议.它的主要功能就是在本地与远程计算机间安全的复制文件. 这是一个中文版的介绍.从这里链接出去的大多数文 ...
- Java之List使用场景
1.List使用场景 特点: ①在 List集合中允许出现 重复元素 <通过元素的equals方法,来比较是否为重复的元素.> ②所有元素是以一种 线性方式进行存储 ③List集合还有一个 ...