【MySQL】【复制】利用slave_exec_mode处理复制过程中出现的1062与1032错误
【MySQL】【复制】利用slave_exec_mode参数处理复制过程中出现的1062与1032错误
背景:
今天张师兄在群里问了主从之间出现1032错误后,使用pt-slave-restart跳过后又出现了1062错误,该如何快速处理。
问题解析:
1032错误:主库传递过来的binlog中包含了删除某些数据的语句,但在从库中部分数据或者全部这些数据被提前手工删除了,或者根本就不存在。
1062错误:主库传递过来的binlog中包含了更新(或插入)某些数据的语句,但在从库中部分数据已经存在,或者被其他的数据占据了唯一性索引的入口。
问题出在binlog重放时是以一个事务作为一个原子单位进行重放。正如原子中是由三个夸克组成一样,一个事务一般也会由若干个event组成。一个event视为一条语句。
若主库传过来一个包含删除三行数据(r1,r2,r3)的事务,但在从库中只有两个个对应的行(r1,r2)。
begin;delete from t1 where row=r3; #假设row列为唯一性索引delete from t1 where row=r2;delete from t1 where row=r1;commit;
那么当执行第一条的时候,从库就会报1032 delete a not exist row错误。使用Pt-slave-restart --error-numbers=1032
就会把这整个事务都跳过去,导致该。下一次若从主库传来
begin;insert into t1(row) values(r1,r2)commit;
那么从库执行插入的时候肯定会报1062 duplicate entry错误。
问题处理:
方法一:
使用Pt-table-sync进行主从数据同步,但是在双主条件或者主库相关表不停的更新的状况下,这种数据同步会导致比较致命的数据混乱。
方法二:
使用slave_exec_mode参数。
先看下官方手册描述:
参数名称: | slave_exec_mode |
---|---|
变量范围: | 全局 |
动态修改: | 是 |
默认值: | NDB集群默认IDEMPOTENT,其他模式STRICT |
有效值: | STRICT/IDEMPOTENT |
设置方式: | SET GLOBAL slave_exec_mode = 'IDEMPOTENT' |
Controls how a slave thread resolves conflicts and errors during replication. IDEMPOTENT mode
causes suppression of duplicate-key and no-key-found errors; STRICT means no such suppression
takes place.
IDEMPOTENT mode is intended for use in multi-master replication, circular replication, and some
other special replication scenarios for NDB Cluster Replication
此参数最初作为在NDB模式中被引进,后来在多主和环形复制都有用武之地。主要的作用就是在slave_exec_mode='IDEMPOTENT时,slave会忽略在插入时的遇到重复的唯一性索引节点和删除时的未发现对应记录的复制错误即1062和1032。但是,当从库从 主库接收到了一条尝试update一条自己不存在的记录时还是会报错1032。
问题到此就很简单了,应进行如下步骤:
stop slave;SET GLOBAL slave_exec_mode = 'IDEMPOTENT'start slave;
再次show slave status\G
应该可以看到从库的复制SQL线程已经恢复正常。
但是这毕竟是非常规手段,在执行完后且主从一致后,应抽空进行数据校验。且不推荐作为默认参数直接打开。
附:
5.7.0以后可以将idempotent作为mysqld启动参数调用,即:mysqld --defaults-file =my.cnf --indempotent&
当然,也可以将其写入my.cnf中。
• --idempotent
Tell the MySQL Server to use idempotent mode while processing updates; this causes suppression
of any duplicate-key or key-not-found errors that the server encounters in the current session while
processing updates. This option may prove useful whenever it is desirable or necessary to replay
one or more binary logs to a MySQL Server which may not contain all of the data to which the logs
refer.
The scope of effect for this option includes the current mysqlbinlog client and session only.
The --idempotent option was introduced in MySQL 5.7.0.
5.7.1以后可以引入了此参数的会话级别版 rbr_exec_mode,只对当前会话生效,且限制行复制模式。
• rbr_exec_mode
This variable switches the server between IDEMPOTENT mode and STRICT mode. IDEMPOTENT
mode causes suppression of duplicate-key and no-key-found errors. This mode is useful when
replaying a row-based binary log on a server that causes conflicts with existing data. mysqlbinlog
uses this mode when you set the --idempotent option by writing the following to the output:
SET SESSION RBR_EXEC_MODE=IDEMPOTENT;
pt_slave_restart和skip_slave_errors跳过的结果不一样
skip_slave_errors跳过时只跳过有问题的语句
而pt_slave_restart跳过整个事务