MySQL 5.6 对复制功能提供了新特性:slave 支持 crash-safe,可以解决之前版本中系统异常断电可能导致的 SQL thread 信息不准确的问题。
可以对从库进行配置 crash-safe 功能是 MySQL 5.6 关于复制的一个重大改进。然而,我们注意到对如何正确开启这个特性存在着一些困惑,那么让我们一起来理清它要怎么做。
简而言之
1.停止从库 MySQL 服务
2.在配置文件 my.cnf 中添加 relay_log_info_repository = TABLE 和 relay_log_recovery = ON
3.重启 MySQL 服务
详情
如果要在从库启用 crash-safe 功能,你需要完全理解为什么要做上面所说的配置。首先,让我们看看当从库崩溃时,同步会断开的原因。
在一个从节点上,同步涉及到 2 个线程:把主节点的二进制日志( binary log )复制到本地中继日志( relay log )的 IO 线程,和执行中继日志中的语句的 SQL 线程。每个线程当前的位置都存储在一个文件里:IO 线程存在 master.info 文件,SQL 线程存在 relay-log.info 文件。
目前为止,还不错。第一个问题是,这些文件不是每次写入都同步到磁盘:如果发生崩溃,写入到文件中的位置很可能是不准确的。MySQL 5.5 对这个进行了修复:你可以设置 set sync_master_info = 1 和 sync_relay_log_info = 1 来确保写入两个日志文件,且在每个事物完成之后同步到磁盘。同步到磁盘是有消耗的,但如果服务器有回写缓存(write-back cache)策略,这些设置还是会起到积极作用,可以接受。
但是,等等,尽管设置了 set sync_master_info = 1 和 sync_relay_log_info = 1,还是可能会出现问题。这是因为复制信息是在事务提交后才写到日志文件的。因此,如果在事务提交之后,复制信息更新之前,发生了崩溃,当服务重启的时候,复制信息是错的,并且一个事务会被执行两次。这个影响取决于这些事务:复制可能还可以正常运行,或者断开,或者导致数据不一致。
MySQL 5.6 通过让我们把复制信息存储在表中,而不是之前的日志文件,来解决这个问题(当 relay_log_info_repository = TABLE 时,会创建表 mysql.slave_relay_log_info,当 master_info_repository = TABLE 时,会创建表 mysql.slave_master_info)。想法很简单:我们可以把复制信息的更新包含在事务当中,确保它和数据同步/一致。
伪代码,写入到日志文件:
START TRANSACTION;
-- Statement 1
-- ...
-- Statement N
COMMIT;
-- Update replication info files
写入到表:
START TRANSACTION;
-- Statement 1
-- ...
-- Statement N
-- Update replication info
COMMIT;
然而,这并没有看起来那么简单。对于 SQL 线程而言,因为实例会在一个事务提交的同时更新表 slave_relay_log_info,所以它可以很好的工作。但对于 IO 线程而言,表的更新与事务的执行并没有关系,那么实例是如何知道什么时候去更新这个表呢?
答案是:它由 sync_master_info 控制。默认值是 10000,表示 IO 线程的位置,只会每提交 10000 个事务更新一次。这明显不利于从节点开启 crash-safe 功能。一个办法是,设置 sync_master_info = 1,但正如前面所说,它可能会影响性能(这就是为什么默认值不是 1)。
还有一个更加优雅的解决方法,那就是设置 relay_log_recovery = ON,但它要求重启 MySQL 服务。这个设置确保当 MySQL 服务启动时,会从表 slave_relay_log_info 恢复出最新的 IO 线程的位置。因此,你甚至不需要为了从节点要开启 crash-safe 功能而去把 IO 线程信息存储到表里面。换句话说,没有必要再去设置 master_info_repository = TABLE。
最后再说一下,一旦设置了 relay_log_info_repository = TABLE,因为这个表会在每个事物提交之后更新,所以 sync_relay_log_info 的设置是什么就无关紧要了。因此,你可以安全地把它从配置文件中删除。
希望这篇文章可以让你从这个这么棒的特性中有所收获。
MySQL crash-safe replication(3): MySQL的Crash Safe和Binlog的关系
2016-12-23 17:29 宋利兵 作者:宋利兵 来源:MySQL代码研究(mysqlcode) 0.导读 本文重点介绍了InnoDB的crash safe和binlog之间的关系,以及2阶段提 ...
MySQL 并行复制从库发生自动重启分析
并行复制从库发生自动重启分析 背景 半同步复制从库在晚上凌晨2点半发生自动重启,另一个异步复制从库在第二天凌晨3点也发生了自动重启. 分析 版本mysql 5.7.16 mysql> show ...
不停止MySQL服务增加从库的两种方式
不停止MySQL服务增加从库的两种方式 转载自:http://lizhenliang.blog.51cto.com/7876557/1669829 现在生产环境MySQL数据库是一主一从,由于业务量访 ...
mysql基础之对库表操作
原文:mysql基础之对库表操作 查看一下所有的库,怎么办? Mysql>Show databases; 选库语句: Use 库名 创建一个数据库: create database 数据库名 [ ...
不停止MySQL服务增加从库的两种方式【转载】
现在生产环境MySQL数据库是一主一从,由于业务量访问不断增大,故再增加一台从库.前提是不能影响线上业务使用,也就是说不能重启MySQL服务,为了避免出现其他情况,选择在网站访问量低峰期时间段操作. ...
Mysql优化_慢查询开启说明及Mysql慢查询分析工具mysqldumpslow用法讲解
Mysql优化_慢查询开启说明及Mysql慢查询分析工具mysqldumpslow用法讲解 Mysql慢查询开启 Mysql的查询讯日志是Mysql提供的一种日志记录,它用来记录在Mysql中响应 ...
MySQL 5.5开启慢查询功能
vim /etc/my.cnf [mysqld] slow-query-log = on # 开启慢查询功能 slow_query_log_file = /usr/local/mysql/data/s ...
.NET 使用 MySql.Data.dll 动态库操作MySql的帮助类--MySqlHelper
.NET 使用 MySql.Data.dll 动态库操作MySql的帮助类--MySqlHelper 參考演示样例代码,例如以下所看到的: /// /// MySql ...
随机推荐
List集合的迭代器方法
1.后台JAVA代码的实现 //获取所有的支付方式的迭代器 // 获取支付方式 @RequestMapping(value = "get/payed/type", method = ...
远程访问mysql
转载:http://www.codesky.net/article/201108/106005.html 数据库不允许从远程访问怎么办?本文提供了三种解决方法: 1.改表法.可能是你的帐号不允许从远程 ...
mybatis.net insert 返回主键
mybatis insert语句
bootstrap2.3.2 modal 用href时有缓存
$('body').on('hidden', '.modal', function () {$(this).removeData('modal');}); 直接在js里加入上面的代码就可以解决缓存问题 ...
android EditText控制光标的位置
利用自定义键盘,需要手动删除编辑框中的文本时,会根据光标的位置来删除字符.那么,如何来控制光标呢,android为我们提供了哪些方法,来处理光标呢? 这里提供几个自己写的方法,根据这些方法可以满足在光 ...
ubuntu 10.04 安装qt 5.0.2
转自ubuntu 10.04 安装qt 5.0.2 从qt project网站下载下来最新的qt5.0.2套件,发现是个.run文件,添加x属性,然后直接sudo ./****.run, 提示 /l ...
[转]能用HTML/CSS解决的问题就不要使用JS
原文链接:http://www.codeceo.com/article/html-css-not-js.html 为什么说能使用html/css解决的问题就不要使用JS呢?两个字,因为简单.简单就意味 ...
poj3924
题目:给定一个起点(xw1, yw1),直线经过(xw2, yw2),速度为vw无限运动的点,还有一个起点(xt1, yt1),终点(xt2, yt2),并且在以vt速度在两者往返运动,求两者在运动中 ...