[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中的信息是否一致。当然,如果你使用了别的引擎,这些信息就没什么作用了。

关于该选项的文档:

http://www.percona.com/doc/percona-server/5.5/reliability/innodb_recovery_update_relay_log.html?id=percona-server:features:innodb_recovery_update_relay_log&redirect=1

相关链接:

http://bugs.mysql.com/bug.php?id=34058

https://bugs.launchpad.net/percona-server/+bug/937852

 

时间: 2024-10-22 02:22:14

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

MySQL · 源码分析 · MySQL 半同步复制数据一致性分析

简介 MySQL Replication为MySQL用户提供了高可用性和可扩展性解决方案.本文介绍了MySQL Replication的主要发展历程,然后通过三个参数rpl_semi_sync_master_wait_point.sync_binlog.sync_relay_log的配置简要分析了MySQL半同步的数据一致性. MySQL Replication的发展 在2000年,MySQL 3.23.15版本引入了Replication.Replication作为一种准实时同步方式,得到广泛

Linux下mysql源码安装笔记_Mysql

1.假设已经有mysql-5.5.10.tar.gz以及cmake-2.8.4.tar.gz两个源文件 (1)先安装cmake(mysql5.5以后是通过cmake来编译的) [root@ rhel5 local]#tar -zxv -f cmake-2.8.4.tar.gz [root@ rhel5 local]#cd cmake-2.8.4 [root@ rhel5 cmake-2.8.4]#./configure [root@ rhel5 cmake-2.8.4]#make [root@

MySQL源码安装总结(r12笔记第12天)

作为一个DBA, MySQL源码安装还是要做做的,虽然不是推荐线上批量安装部署,但是自己作为了解MySQL的一个学习过程,还是值得的. 相比商业软件来说,开源的这一点上就让人很羡慕,商业软件我们总是使用各种工具和底层原理去反推,探测,但是离代码还是有一定的距离.当然商业有商业的好,开源有开源的乐,不能一概而论. 值得推荐的安装镜像 对于MySQL的安装部署来说,总是存在各种版本和子版本,其实整理起来非常繁杂,今天看到竟然我狐已经提供了非常的镜像站点 http://mirrors.sohu.com

MYSQL源码编译的变动

Mysql的安装,对于mysql不同版本的mysql源码编译方式不一样 5.6.2的版本开始编译方式已经由 configure 变成了cmake方式 ,相关的新的 编译方式在mysql官网已经提供 http://dev.mysql.com/doc/refman/5.6/en/source-configuration-options.html 源码下载地址如下 http://dev.mysql.com/downloads/mysql/ 网上相关mysql5.6的源码编译方式 http://www.

MySQL源码:Range优化相关的数据结构

1. 背景知识 在开始介绍Range的主要数据结构之前,我们先看Range优化的一些概念和背景.依旧建议先阅读参考文件的[1-8],Sergey Petrunya写的PPT和文档质量都很高,很多图示,非常直观的展示了原理. (1) 什么是Range条件? 参考Range Optimization@MySQL Manual 单列Range和多列Range (2) 给定一个KEY(key1)对应的WHERE条件,如何将其转化成一个Range,下面是"简述",详细参考单列Range: SEL

mysql源码安装

我准备学下mysql的源码,所以编译和调试源码是很重要的一部分. 好了废话不多说. 我的环境是 CentOS-6.9-x86_64-minimal,这个可以在阿里的源中直接下.阿里云CentOS6.9下载地址 然后是安装之前的准备工作 先装好环境 yum update yum -y install cmake yum -y install bison yum -y install library* yum -y install libncurses5-dev yum -y install g++

Linux下MySQL源码编译安装(eg:mysql-5.6.27.tar.gz )

Linux下MySQL源码安装(eg:mysql-5.6.27.tar.gz ): 1:准备MySQL源码安装包: mysql-5.6.27.tar.gz.cmake-3.3.2.tar.gz.ncurses-6.0.tar.gz 注:centos请安装: yum install -y ncurses-devel yum install -y perl-Module-Install.noarch 网址: https://cmake.org/download/ ftp://invisible-is

MySQL源码:索引相关的数据结构(前篇)

1. MySQL如何描述某个数据表的索引 MySQL使用TABLE对象来描述一个数据表,那么数据表的索引是如何描述,索引的统计信息又是如何存储的呢? 例如我们有如下数据表: CREATE TABLE `users` ( `id` int(11) NOT NULL, `nick` varchar(32) DEFAULT NULL, `reg_date` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `IND_NICK` (`nick`), KEY `

Linux CentOS6.6系统中安装mysql源码包的方法_Linux

这里以CentOS6.6系统中安装MySQL的源码包,进行讲解. 1. mysql源码包的下载 mysql安装包的官方下载地址为:http://dev.mysql.com/downloads/mysql/5.6.html 打开该下载地址后,在 "Select Version:"处,选择要下载的mysql的版本,我选择的是5.6.34:在"Select Platform:"处,选择适用的操作系统类型,由于是下载源码包,故这里我们要选择Source Code. 之后,会