【SQL开源代码栏目提醒】:网学会员,鉴于大家对SQL开源代码十分关注,论文会员在此为大家搜集整理了“MySQL源码学习:ib_logfile、bin-log与主从同步 - 综合课件”一文,供大家参考学习!
今天研究MySQL主从同步的同事问了一个问题如果InnoDB写完ib_logfile后服务异常关闭。
会不会由于主库能够根据ib_logfile恢复数据而由于bin-log没写导致从库同步时少了这个事务或者反之bin-log写成功而ib_logfile没有写完导致从库执行事务而主库不执行 这会导致主从不一致。
本文简要说明下这个问题。
1、 写入流程 源码
sql/handler.cc: ha_commit_trans … if err ht-prepareht thd all … tc_log-log_xidthd xid … errorha_commit_one_phasethd all … 说明 实际上ib_logfile的两步写策略避免了上述的两个问题。
流程大致如下 a ib_logfile 写入当前事务的更新数据并标志为事务准备trx_prepare. b 写入bin-log。
c ib_logfile 当前事务提交结束trx_commit 2、 恢复流程 实际上若ib_logfile已经写入trx_prepare则在恢复过程中会根据bin-log中该事务是否存在来恢复数据见函数xarecover_handlerton。
流程如下
sql/handler.cc xarecover_handlerton
sql_print_informationFound d prepared transactions in s got ha_resolve_storage_engine_namehton foreach trx If found in bin-log
sql_print_informationcommit xid s xid_to_strbuf info-listi hton-commit_by_xidhton info-listi Else
sql_print_informationrollback xid sxid_to_strbuf info-listi hton-rollback_by_xidhton info-listi 说明从启动日志中能够看到上述
代码输出的日志。
☆ 假设在阶段a结束之后程序异常 此时没有写入bin-log。
则从库不会同步这个事务。
主库上在重启之后从恢复日志中这个事务没有trx_commit因此会被回滚。
逻辑上主从库都不会执行这个事务。
☆ 假设在阶段b结束后程序异常此时bin-log已经写入则从库会同步这个事务。
主库上根据恢复日志和bin-log也能够正常恢复此事务。
也就是说若bin-log写入完成则主从库都会正常完成事务bin-log没有写入则主从库都完成事务。
不会出现主从不一致的问题。
3、 操作系统崩溃造成的不一致 上述的流程并不是天衣无缝的。
ib_logfile的写盘是能够被设置成非实时flush的。
假设在bin-log写入完成后系统崩溃则可能出现这样的情况bin-log写入所以从库能够执行事务。
但主库中trx_prepare的日志没有被写入到ib_logifle中导致主库不执行事务。
这样就会出现主从不一致的情况。
解决方案增加启动检测将ib_logfile中不存在的事务从bin-log删除掉。
这样主从库都不执行此事务。