——————————————-
最近发现一种情况,在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中的信息是否一致。当然,如果你使用了别的引擎,这些信息就没什么作用了。
关于该选项的文档:
相关链接:
http://bugs.mysql.com/bug.php?id=34058
https://bugs.launchpad.net/percona-server/+bug/937852