由于复制配置的原因,执行relaylog中的事务的顺序可能产生不一致。
不一致的类型:
1.应用部分事务
事务中包含支持事务的表和非事务型的表。
2.空隙(gap)
事务gap只会发生在多线程复制。为了避免发生事务gap,要设置slave_preserve_commit_order=1、slave_parallel_type=LOGICAL_CLOCK、 log-bin、log-slave-updates。但是slave_preserve_commit_order=1并不能保证非事务性dml的顺序,从而产生事务gap。
3.主库二进制日志位置延迟
即使没有发生gap,也会发生Exec_master_log_pos后面的事务被应用。也就是说时间点N之前的事务已经被应用了,时间点N后的事务都没有被应用。但是Exec_master_log_pos的值小于N。这种情况下,Exec_master_log_pos是已经被应用事务的低水位标记,lag发生在之后。这种情况只会发生在多线程复制环境。slave_preserve_commit_order=1也不能避免这种主库日志位置延迟。
以下是发生不一致的场景:
1.复制线程正常运行,但是发生了gaps和事务部分被应用
2.mysqld被shutdown,无论是干净、非干净的关闭,都可能导致gaps和事务部分被应用
3.kill了复制线程(sql thread、coordinator thread),这会abort在进行的事务,可能会导致gaps和事务部分被应用
4.applier线程发生了错误,这会导致gaps。如果error发生在一个mixed事务,事务会部分被应用。如果使用多线程复制,没有接收到error的worker线程会完成他们的队列,故可能需要时间来停止所有的线程。
5.多线程复制环境stop slave。执行stop slave后,复制会等待gap被填充,然后更新Exec_master_log_pos。这样可以确保没有gap或者主库二进制日志延迟。在stop slave完成之前,如果发生了错误,或其它线程被kill,或者重启,就会发生上面的不一致。
6.如果relaylog中的最后一个事务日志只是接收了一半且多线程复制协调线程已经调度给一个worker线程,stop slave会等待60秒。超时后,协调线程会放弃并中止事务。如果事务是mixed,就可能会出现事务被部分应用。
7.单线程复制执行stop slave。如果在执行的事务只是更新事务性表,事务会回滚、stop slave立即停止。如果事务是mixed,stop slave会等待60秒,让事务结束。超时后,就可能会出现事务被部分应用。
如果channel有了延迟,会有以下的后果:
1.从库可能处于主库不曾出现过的状态
2.Exec_master_log_pos处于低水位标记状态。
3.change master to语句会发生错误
4.如果mysqld开启了--relay-log-recovery,无法执行recovery,并打印出警告信息
5.如果mysqldump时开启了--dump-slave,不会记录已经存在的gaps;Exec_master_log_pos处于低水位标记状态