Heim  >  Artikel  >  Datenbank  >  MySQL5.6新特性之crash-safe

MySQL5.6新特性之crash-safe

WBOY
WBOYOriginal
2016-06-07 15:21:27905Durchsuche

MySQL 5.6 针对复制功能提供了新特性: slave支持crash-safe. 该功能可以解决之前版本中系统异常断电可能导致的SQL thread 信息不

一 介绍

MySQL 5.6 针对复制功能提供了新特性: slave支持crash-safe. 该功能可以解决之前版本中系统异常断电可能导致的SQL thread 信息不准确的问题。本文从原理方面对该特性进行介绍。

二 原理

在了解crash-safe slave 之前,我们先分析一下MySQL 5.6 之前的版本出现 crash-unsafe 的原因。在slave上,复制包含两个线程:即replication中的IO thread和SQL thread。

IO thread负责从master拷贝binlog文件并保存到本地,拷贝过来的binlog称为relay-log.

SQL thread负责执行relay-log.

两个线程的执行进度(偏移量)都保存在文件中.IO thread的执行状态信息保存在master.info文件,SQL thread的执行状态信息保存在relay-log.info文件。系统运行正常的情况下,这种模式到目前为止还没有问题。需要注意的是这些文件被修改后不是同步写入磁盘的,每当系统发生crash,存储的偏移量可能都不准确.MySQL 5.5通过两个参数修复了该问题,使用sync_master_info=1和sync_replay_log_info=1 来保证Slave 的两个线程每次写一个事务就分别向两个文件同步一次 IO thread和SQL thread当前执行的信息。当然同步操作不是免费的,频繁更新磁盘文件需要消耗性能,如果你的RAID设备的IO策略设置为WRITEBACK 模式,那么这种方法便可以接受的。

但是,即使设置了sync_master_info=1和sync_relay_info=1, 问题还是会出现,因为复制信息是在transactions提交后写入的,如果crash发生在事务提交和OS写文件之间,那么relay-log.info就可能是错误的。当slave从新启动的时候,最后那个事务可能会被执行两次.具体的影响取决于事务的具体操作.复制可能会继续运行比如update/delete,或者报错 比如insert操作,此时主从数据的一致性可能会被破坏。

MySQL 5.6版本通过将复制信息存放到表中来解决此问题.通过配置两个参数 relay_log_info_repository=TABLE,master_info_repository=TABLE,relay log info 会存放到 mysql.slave_relay_log_info表中,master info 会存放mysql.slave_master_info表中。就是把SQL线程执行事务和更新mysql.slave_replay_log_info的语句看成一个事务处理,这样就会一直同步的.

我们可以通过伪代码来了解crash-safe 的原理

crash-unsafe情况下 SQL_thread 的 的工作模式

START TRANSACTION;
 
 Statement 1

  ...

 Statement N

 COMMIT;

Update replication info files
crash-safe情况下 SQL_thread 的 的工作模式

START TRANSACTION;
 
  Statement 1

  ...

  Statement N

  Update replication info

COMMIT
crash-safe就是将relay-info.log的信息保存在InnoDB的事务表中,这时执行relay log中的事务和写relay info在一个事务中,就能得到原子性保证。从而避免已执行的binlog位点和写入relay log info 的位点信息不一致的情况发生。看到这里也请各位读者思考一下 ,现在的这种方案是否完美,有哪些问题?
 从上面的改变解决了SQL thread记录执行状态可能导致不一致的风险,但是对于IO thread 依然存在问题 。IO thread 从master上拷贝binlog写入 relay log中,每个二进制日志由多个log event组成,所以每接收到一个log event就需要更新master-info.log而且该是写入操作系统缓存。从IO thread的工作原理来看,它没有办法 将写入master info和拉取binlog放到同一个事务中而保持原子操作,因此IO thread 的行为是会对数据一致性会产生影响,设想一个log event传送到了relay log中两次的情形。如何解决呢?
 方案一 通过参数sync_master_info可以控制fdatasync的时间。默认值是10000,表示IO线程的偏移量每10000个事务更新一次 ,,通过设置其为1,每写一次事务便同步到master.info 。
 方案二 通过MySQL 5.5版本开始提供的参数relay_log_recovery ,当slave发生crash后重启之后重连master时,slave不根据master-info.log的信息进行重连,而是根据relay-info中执行到master的位置信息重新开始拉master上的日志数据。

三 如何使用
  1 停止slave的mysql实例
  2 my.cnf文件中添加
    master-info-repository=TABLE
      relay-log-info-repository=TABLE
      relay-log-recovery
  3 重启slave的mysql实例
 注意:
如果是MySQL 5.6.5 或者更早期。slave_master_info 和 slave_relay_log_info 表默认使用MyISAM 引擎。所以还得修改成innodb,如下:       

ALTER TABLE mysql.slave_master_info ENGINE=InnoDB;
 
ALTER TABLE mysql.slave_relay_log_info ENGINE=InnoDB
四 小结
    MySQL 5.6 版本为MySQL的稳定性做出了很多改进,这点值得MySQL DBA 去关注,也值得大家去思考,这些改善点还有那些不足之处?有如何解决?

本文永久更新链接地址

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:Oracle编译时警告Nächster Artikel:CentOS 7 安装MySQL