开发者社区> zhaiwx_yinfeng> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

[MySQL源码] 在复制线程事务提交与更新relay-log.info之间crash导致的复制不一致

简介:
+关注继续查看

——————————————-

最近发现一种情况,在xid event和flush_relay_log_info中间crash,可能会导致数据不一致。

即事务提交了,但relay-log.info文件还没更新,这会造成重启crash recovery后事务被重复执行一次。
幸好,在innodb层记录了这些信息。并且Percona也提供了一个选项来利用这些信息。
1.相关全局变量
在trx/trx0sys.c文件中定义了如下变量
最后一个commit的事务的slave信息:
trx_sys_mysql_master_log_name
trx_sys_mysql_master_log_pos
trx_sys_mysql_relay_log_name
trx_sys_mysql_relay_log_pos
最后一个commit的binlog信息:
trx_sys_mysql_bin_log_name
trx_sys_mysql_bin_log_pos
2.写入信息
那么在什么时候会记录这些信息呢?
在函数mysql_bin_log_commit_pos中,确定写入innodb的binlog位置,backtrace如下
#0  mysql_bin_log_commit_pos
#1  0x00000000007c88d4 in innobase_commit_ordered_low
#2  0x00000000007cca97 in innobase_commit_ordered
#3  0x000000000071efc5 in run_commit_ordered
#4  MYSQL_BIN_LOG::trx_group_commit_leader
#5  0x000000000071f49d in MYSQL_BIN_LOG::write_transaction_to_binlog_events
#6  0x000000000071f681 in MYSQL_BIN_LOG::write_transaction_to_binlog
#7  0x000000000071ff6b in binlog_flush_cache
#8  binlog_commit_flush_trx_cache
#9  MYSQL_BIN_LOG::log_and_order
#10 0x000000000068a112 in ha_commit_trans
#11 0x000000000062f2fd in trans_commit_stmt
#12 0x000000000057c6bc in mysql_execute_command
在函数innobase_commit_ordered_low中先调用mysql_bin_log_commit_pos确定位置
再调用innobase_commit_low,如果是slave线程,直接访问active_mi->rli,将当前执行完的relay log坐标及对应binlog坐标拷贝到trx的成员变量中。然后调用trx_commit_for_mysql->trx_commit_off_kernel
当有对数据做更改时,及insert_undo和update_undo不为空时,调用trx_write_serialisation_history
这里会先更新undo,然后调用trx_sys_update_mysql_binlog_offset来更新ibdata中的relaylog/binlog里的坐标信息。这些都是在一个mtr中提交。
3.
重启后,会在完成crash recovery后,打印相关信息。
innobase_init
   –>innobase_start_or_create_for_mysql
         –>recv_recovery_from_checkpoint_finish
             –>trx_sys_print_mysql_master_log_pos 打印relay log信息,并将其拷贝到上述变量中
             –>trx_sys_print_mysql_binlog_offset  打印binlog信息
然后如果变量将相关信息记录到以上几个变量中。
在回到innobase_init函数后,会根据innobase_overwrite_relay_log_info来重写relay-log.info文件。
2977     if(innobase_overwrite_relay_log_info) {
……
直接重写relay-log.info文件
}
innobase_overwrite_relay_log_info 对应的MySQL选项是innodb_recovery_update_relay_log。
我们只要开启该参数,就会进入这部分代码逻辑。
因此,最好开启skip-slave-start,并需要关注err log中打印出来的信息与relay-log.info中的信息是否一致。当然,如果你使用了别的引擎,这些信息就没什么作用了。
关于该选项的文档:
相关链接:

 


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
JavaScript+TensorFlow.js让你在视频中瞬间消失
JavaScript+TensorFlow.js让你在视频中瞬间消失
41 0
通用的进程监控重拉起bash脚本
 process_monitor.zip    #!/bin/sh # http://code.google.com/p/mooon # 进程监控脚本,当指定进程不存在时,执行重启脚本将它拉起 # 特色: # 1.
701 0
+关注
zhaiwx_yinfeng
MySQL内核开发者, 《高性能MySQL 第三版》译者之一,活跃于MySQL社区,BugList,etc...
224
文章
5
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载