MySQL crash-safe replication(2):
MySQL数据库的成功离不开其replicaiton(复制),相对于Oracle DG和Microsoft SQL Server Log Shipping来说,其简单易上手,基本上1,2分钟内根据手册就能完成环境的搭建。然而,随着使用的深入,replication自身的问题会慢慢显露,其中非crash safe的特性使得许多DBA感到头疼,甚至不能理解其所发问题的原因。简单来说,crash-safe replication是指当master/slave任何一个节点发生宕机等意外情况下,服务器重启后master/slave的数据依然能够保证一致性。
crash-safe master相对比较简单,只要使用事务的存储引擎,并且正确的配置就能达到crash safe的效果。对于最为常见的InnoDB存储引擎而言,只需在配置文件中进行如下的设置:
|
[mysqld]
sync_binlog=1 innodb-flush-log-at-trx-commit=1 |
MySQL 5.6版本之前存在一个bug,即当启用上述两个参数时,会使得InnoDB存储引擎的group commit失效,从而导致在写密集的环境中性能的急剧下降。因此,DBA在性能和数据一致性中做了妥协,通常将参数innodb-flush-log-at-trx-commit设置为2,而这就导致了master不再是crash safe的,主从数据可能会不一致。MariaDB真正解决了该问题,因此很多分支版本,比如Percona,Facebook MySQL,InnoSQL都将MariaDB的group commit方案移植到了自己的分支中,从而解决group commit失效的问题。
crash-safe slave的情况就有些复杂,而这可能是DBA更为常见的问题。例如slave不断的报1062错误,或者发现主从数据不一致(特别是表没有主键的情况)。而这时DBA的选择通常也很无奈,基本就是全库重建了。所以说,当你有运维超过200台以上的MySQL服务器的经验时,就会发现这是一个很大的问题。
导致不能实现crash-safe slave有两方面的原因,即replication中的SQL thread和IO thread。首先来看SQL thread,其主要完成两个操作:
- 运行relay log中对应的事务信息
- 更新relay-info.log文件
更新relay-info.log文件是为了记录已经执行relay log中的位置,当slave重启后可以根据这个位置继续同步relay log。但是,这里用户会发现这两个操作不是在一个事务中,一个是数据库操作,一个是文件操作,因此不能达到原子的效果。此外,MySQL数据库默认对于文件relay-info.log是写入到操作系统缓存,因此在发生宕机时可能导致大量的已更新位置的丢失,从而导致重复执行SQL语句,最终的现象就是主从数据不一致。MySQL 5.5新增了参数sync_relay_log_info,可以控制每次事务更新relay-info.log后就进行一次fdatasync操作,这加重了系统负担,而且即使这样也可能存在最后一个事务丢失的情况。
早在MySQL 4.0时Google就发布过补丁解决过该问题(https://code.google.com/p/google-mysql-tools/wiki/TransactionalReplication),其在每次InnoDB存储引擎提交时,记录二进制日志的位置信息到事务系统段的段头。当slave重启后将保存的这部分的信息重新生成relay-info.log文件。Percona也采用了这种方式,并通过参数innodb_recovery_update_relay_log来控制是否在启动时替换relay-info.log文件。
MySQL 5.6采用了另一种方法,就是将relay-info.log的信息保存在InnoDB的事务表中,这时两个操作都是数据库操作,在一个事务中就能得到原子性。例如对于slave的日志回放,其过程为:
| BEGIN; apply log event; apply log event; UPDATE mysql.slave_relay_log_info SET Master_log_pos = Exec_Master_Log_Pos, Master_log_name = Relay_Master_Log_File, Relay_log_name = Relay_Log_File, Relay_log_pos = Relay_Log_Pos; COMMIT; |
这样的处理方式解决更新relay-info.log的原子性问题,但是这是最终完美的解决方案吗?很可惜,还是存在一些缺陷。可以看到由于最后表slave_relay_log_info的更新会锁住记录,从而导致slave上的事务提交都是串行的。虽然MySQL 5.6支持并行复制,但是由于串行更新表slave_relay_log_info,再次导致group commit失效。因此通过--log-slave-updates再立级联replication的话,性能又会受限。MariaDB正在解决该问题,非常有可能在MariaDB 10 GA版本中见到完美的解决方案。
IO thread用于同步master上的二进制日志,但是其在crash时依然会导致数据不一致的情况发生。IO thread将收到的二进制日志写入到relay log,每个二进制日志由多个log event组成,所以每接受到一个log event就需要更新master-info.log。和relay-info.log一样,其也是写入操作系统缓存,参数sync_master_info可以控制fdatasync的时间。由于IO thread的更新不能像SQL thread一样进行放到一个事务进行原子操作,因此其是对数据一致性会产生影响,设想一个log event传送到了relay log中两次的情形。
不过好在从MySQL 5.5版本开始提供了参数relay_log_recovery,当发生crash导致重连master时,其不根据master-info.log的信息进行重连,而是根据relay-info中执行到master的位置信息重新开始拉master上的日志数据(不过需要确保日志依然存在于master上,否则就。。。)
MySQL crash-safe replication(2):的更多相关文章
- InnoSQL HA Suite的实现原理与配置说明 InnoSQL的VSR功能Virtual Sync Replication MySQL 5.5版本引入了半同步复制(semi-sync replicaiton)的功能 MySQL 5.6支持了crash safe功能
InnoSQL HA Suite的实现原理与配置说明 InnoSQL的VSR功能Virtual Sync Replication MySQL 5.5版本引入了半同步复制(semi-sync repl ...
- MySQL crash-safe replication(3): MySQL的Crash Safe和Binlog的关系
2016-12-23 17:29 宋利兵 作者:宋利兵 来源:MySQL代码研究(mysqlcode) 0.导读 本文重点介绍了InnoDB的crash safe和binlog之间的关系,以及2阶段提 ...
- MySQL Crash Errcode: 28 - No space left on device
一台MySQL服务器突然Crash了,检查进程 ps -ef | grep -i mysql 发现mysqld进程已经没有了, 检查错误日志时发现MySQL确实Crash了.具体如下所示: 注意日志中 ...
- 【原创】获取MySQL crash 时的core file
最近有台服务器的MySQL经常crash,为了进一步定位问题,开启了mysql core file功能,开启步骤如下,供参考 [开启步骤] 1. my.cnf文件中增加2个配置选项 [mysqld] ...
- System.TypeInitializationException: 'The type initializer for 'MySql.Data.MySqlClient.Replication.ReplicationManager' threw an exception.'
下午在调试的时候报错数据库连接就报错我就很纳闷后面用原来的代码写发现还是报错 System.TypeInitializationException: 'The type initializer for ...
- 《MySQL 5.7 Replication新特性》分享之互动问题解答
原创 2016-07-21 宋利兵 MySQL中文网 分享主题 <MySQL 5.7 Replication新特性> 嘉宾介绍 宋利兵,MySQL研发工程师.2009年加入MySQL全球研 ...
- 捉虫日记 | MySQL 5.7.20 try_acquire_lock_impl 异常导致mysql crash
背景 近期线上MySQL 5.7.20集群不定期(多则三周,短则一两天)出现主库mysql crash.触发主从切换问题,堆栈信息如下: 从堆栈信息可以明显看出,在调用 try_acquire_loc ...
- MySQL 5.7 Replication 相关新功能说明
背景: MySQL5.7在主从复制上面相对之前版本多了一些新特性,包括多源复制.基于组提交的并行复制.在线修改Replication Filter.GTID增强.半同步复制增强等.因为都是和复制相关, ...
- Mysql 5.5 replication 多数据库主从备份Master-Slave配置总结
配置Mysql server 5.5 的双机备份,也就是master-slave模式.本例子还是一个多database复制的情况. 现在有两个database在同一台mysql server,也就是m ...
- Latch导致MySQL Crash
作者:沃趣科技数据库专家 董红禹 问题概述 最近我们遇到一个MySQL的问题,分析后很有代表意义,特地写出来供大家参考.出现问题是,数据库先是被置为只读,然后过了一段时间,MySQL直接Crash掉了 ...
随机推荐
- TensorFlow object detection API应用
前一篇讲述了TensorFlow object detection API的安装与配置,现在我们尝试用这个API搭建自己的目标检测模型. 一.准备数据集 本篇旨在人脸识别,在百度图片上下载了120张张 ...
- 修改wireshark协议解析规则
不同的协议有不同的解码器,wireshark尝试为每个包尝试找到正确的解码器,特定的情况有可能会选择错误的解码器. 1.使用了其它协议的标准端口,被错误解码,使用udp的80端口发送数据被当作QUIC ...
- jdk8-stream-并行流的使用
使用jdk的stream, 可以非常方便的将串行改为并行 1, 判断是否质数 /** * 将一个stream改成简单的并行 */ @Test public void test1() { // 串行 , ...
- 通过DataTrigger绑定Tag属性值进行判断(.net 3.5的环境)
如下,在UserControl中通过Tag传递不同的值,然后在Style中使用DataTrigger进行判断, <UserControl Style="{DynamicResource ...
- vi/vim编辑器必知必会
一.我们为什么要学习vim编辑器? Linux的命令行界面下面有非常多的文本编辑器.比如经常听说的就有Emacs.pico.nano.joe与vim等.vim可以看做是vi的高级版.我们为什么一定要学 ...
- MySQL主主复制以及使用keepalived保证高可用
1:准备工作 MySQL的安装步骤在此处省略:安装完成一定要做以下准备工作,初始化MySQL,/usr/bin/mysql_secure_installation,设置root密码,删除无效账户以及t ...
- shell命令——if
if中[ ]实际上调用的是test的一种快捷方法.bash的数值和字符串比较运算符: 注意=两边的空格 字符串 数值 为真,如果 x = y x -eq y x != y x -ne y x ...
- 深入出不来nodejs源码-从fs.stat方法来看node架构
node的源码分析还挺多的,不过像我这样愣头完全平铺源码做解析的貌似还没有,所以开个先例,从一个API来了解node的调用链. 首先上一张整体的图,网上翻到的,自己懒得画: 这里的层次结构十分的清晰, ...
- 手机调试 ---- Node启动服务
最近刚开始做手机端Web网站, 在这段时间遇到过很多坑.比如各个安卓手机的JS兼容性问题,以及安卓手机与苹果手机的差异化. 最近在做一个需求.进入手机站点主页,会弹出置顶APP下载框,用户点击图片,如 ...
- Jquey节点操作
创建添加节点: 创建jquery对象:$("<a href="http://baidu.com" target="_blank">百度请点 ...