MySQL参数sql_slave_skip_counter和slave_exec_mode进一步认识

在mysql主从集群维护中,有时候从库可能会出现因为主从数据导致的无法执行的SQL语句,那么此时如果临时解决主从关系,可能会在从库上执行set global sql_slave_skip_counter=1|N以跳过无法执行的命令;
那么设置此参数的值1或者N是什么意思呢?
sql_slave_skip_counter:The number of events from the master that a slave server should skip. Setting the option has no immediate effect. The variable applies to the next START SLAVE statement; the next START SLAVE statement also changes the value back to 0. When this variable is set to a non-zero value and there are multiple replication channels configured, the START SLAVE statement can only be used with the FOR CHANNEL channel clause.
Important
If skipping the number of events specified by setting this variable would cause the slave to begin in the middle of an event group, the slave continues to skip until it finds the beginning of the next event group and begins from that point.

即为在start slave时,从当前位置起,跳过N个event。每跳过一个event,则N–.
实际上这里还有两个策略:

  • 若N=1且当前event为BEGIN, 则N不变,跳过当前event继续。
  • 若N=1且当前event处于一个事务之内(BEGIN之后,COMMIT之前),则N不变,跳过当前event继续。

可以理解为:

  • set global sql_slave_skip_counter=N中的N是指跳过N个event
  • 最好记的是N被设置为1时,效果跳过下一个事务。
  • 跳过第N个event后,位置若刚好落在一个事务内部,则会跳过这整个事务(the slave continues to skip events until it reaches the end of the group)

现在主从数据如下:

M S
+—-+
| test |
+—-+
| 1 |
| 2 |
| 3 |
+—-+
+—-+
| test |
+—-+
| 1 |
| 3 |
+—-+

由于主从数据已然不一致,这时若在主上执行下面的SQL:
执行下面SQL:

BEGIN;
INSERT INTO Z SELECT 4;
DELETE FROM Z WHERE a = 2;
INSERT INTO Z SELECT 5;
COMMIT;

从机显然会报错,提示1032错误,因为记录2这条记录并没有找到。那么如果此时设置set global sql_slave_skip_counter=1的话,然而,这样的处理会导致INSERT 5这条记录不被执行。因为跳过DELETE 2这个操作后,事务没有结束,会继续跳过接下去的event(the slave continues to skip events until it reaches the end of the group)

那么此时想要从库只跳过一个event,而不跳过整个事务的方法就是设置从库参数slave_exec_mode为IDEMPOTENT即可;
slave_exec_mode: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.

针对slave_exec_mode参数,它可以影响跳过1062和1032等错误的行为;该参数默认为strict时,从库无法跳过这种从库SQL执行错误,参数为IDEMPOTENT(幂等)时,它可以跳过1062和1032的错误并且不影响同一个事务中正常的数据执行。如果是多个SQL组成的事务,则可以跳过有问题的event。

参考:
http://www.cnblogs.com/zhoujinyi/p/8035413.html
https://mp.weixin.qq.com/s/rZZbLmN0Klq0o0bvnijizw
http://dinglin.iteye.com/blog/1236330

猜你喜欢

转载自blog.csdn.net/poxiaonie/article/details/79003371