【SQL开源代码栏目提醒】:网学会员为需要SQL开源代码的朋友们搜集整理了MySQL源码学习:ib_logfile、bin-log与主从同步 - 其它资料相关资料,希望对各位网友有所帮助!
MySQL 源码学习:ib_logfile、bin-log 与主从同步v 今天研究 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_commit2、 恢复流程 实际上,若 ib_logfile 已经写入 trx_prepare,则在恢复过程中,会根据 bin-log 中该事务是否存在来恢复数据(见函数 xarecover_handlerton)。
流程如下(
sql/handler.cc)xarecover_handlerton
sql_print_informationFound d prepared transactionsin s gotha_resolve_storage_engine_namehton foreach trx If found in bin-log
sql_print_informationcommit xid s xid_to_strbufinfo-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 删除掉。
这样主 从库都不执行此事务。
上一篇:
基于开源类库OGR的空间数据互操作研究
下一篇:
教养就是细节