目标

主库宕机不丢数据(Master Failover without data loss)

facebook有两篇不错的文章:

1. Loss Less Semisync

半同步复制实现的关键点是Master对于事务提交过程特殊处理。目前实现半同步复制主要有两种模式,AFTER_SYNC模式和AFTER_COMMIT模式。两种方式的主要区别在于是否在存储引擎提交后等待Slave的ACK。

下面展示了半同步复制中,binlog的提交过程。

1. binlog prepare (doing nothing)
2. innodb prepare (fsync)
3. binlog commit (writing to fscache)
4. binlog commit (fsync)
5. loss-less semisync wait (AFTER_SYNC)
6. innodb commit (releasing row locks, changes are visible to other users)
7. normal semisync wait (AFTER_COMMIT)

半同步复制是否能保证不丢数据?

我们通过几种场景来简单分析下。

第一种情况:假设Master前4步binlog commit执行成功后,binlog还没来得及传递给Slave,此时Master挂了,Slave作为新Master提供服务,那么备库比主库要少一个事务(因为主库的redo 和binlog已经落盘),但是不影响用户,对于用户而言,这个事务没有成功返回,那么提交与否,用户都可以接受,用户一定会进行异常捕获而重试。

第二种情况,假设innodb commit执行成功后,binlog还没来得及传递给Slave,此时Master挂了,此时与第一种情况一样,备库比主库少一个事务。如下图所示,在AFTER_COMMIT模式下,user1在innodb commit执行完后,其他用户可以看到该事务的更新,而切换到备库后,却发现再次读这个更新又没了,这个就发生了“幻读”,如果其他事务依赖于这个更新,则会对业务逻辑产生影响。当然这仅仅是极端情况。

AFTER_SYNC模式可以解决“幻读”问题。master在AFTER_SYNC模式下,Fsync binlog后,就开始等待Slave同步。那么在进行innodb commit后,即其它事务能看到该事务的更新时,Slave已经成功接收到binlog,即使发生切换,Slave拥有与Master同样的数据,不会发生“幻读”现象。但是对于上面描述的第一种情况,结果是一样的。

所以,在极端情况下,半同步复制的Master-Slave会有一个事务不一致,但是对于用户而言,由于这个事务并没有成功返回给用户,所以无论事务提交与否都是可以接受的,用户有必要进行查询或重试,判读是否更新成功。或者我们想想,对于单机而言,若事务执行成功后,返回给用户时,网络断了,用户也是面临一样的问题,所以,这不是半同步复制的问题。对于提交返回成功的事务,版同步复制保证Master-Slave一定是一致的,从这个角度来看,半同步复制不会丢数据,可以保证Master-Slave的强一致性。

2. Reduce durability on master

以前mysql5.6有个Bug: 主库在(2)(3)之间宕机,接着主库故障恢复后,主备之间的复制会中断,备库会报1206的错。

(1)master writes to binlog (writing to kernel buffer)
(2)binlog dump threads read the binlog events and send to slaves
(3)master flushes to binlog (fsync to binlog file)

为什么会有这个Bug产生呢?原因是在5.6仅仅只是在writing to kernel buffer阶段持有LOCK_log锁。所以在 fsync()完成之前,binlog dump线程就可以读取主库的binlog,发送到备库去。

为了修复这个bug,主库增加了持有LOCK_log锁的时间,直到fsync()结束后释放。这个改进点退化了半同步复制的性能。因为在5.6中,LOCK_log锁是一个非常热的mutex锁。binlog dump线程和用户线程都需要去持有LOCK_log锁。

不过比较好的是,将持久化参数设置成非严格模式(sync_binlog=0;innodb_flush_log_at_trx_commit=0|2),可以缓解LOCK_log锁带来的性能退化。

对于LOCK_log锁的优化,可以看看这个链接:

http://my-replication-life.blogspot.com/2013/09/dump-thread-enhancement.html

http://www.actionsky.com/docs/archives/129

  • 主库端拆分LOCK_log

在主库上,binlog的写入和读取都需要同一把锁来保护,也就是LOCK_log,当写入负载较大时,LOCK_log成为热点锁;而对于dump线程而言,每一个dump线程在读取binlog事件时,都需要先持有LOCK_log锁;dump线程越多,引起的竞争越激烈。

当dump线程无法及时获取LOCK_log锁时,就会影响发送binlog到备库的速率,进而影响备库IO线程返回ACK的速率。

拆分的思路也很简单,就是每次写入binlog时,维持该binlog文件末尾的偏移量;在该偏移量之前我们都可以安全读取binlog文件而无需加锁。

  • 备库端拆分LOCK_log

首先区分一点,备库的LOCK_log属于relay log,和主库的LOCK_log属于不同的类对象。 备库上,SQL线程与IO线程在一种情况下会存在LOCK_log竞争,也就是当前SQL线程执行的relylog和IO线程写入的relaylog是同一个文件时,这时候IO线程和SQL线程使用的是同一个IO CACHE来操作文件,因此必须使用LOCK_log来保证读和写的互斥;

为了分拆LOCK_log,需要实现如下两点: a.SQL线程总是在读取事件时,使用自有的IO CACHE,而不是和IO线程公用IO CACHE b.和主库LOCK_log拆分类似,需要在IO线程写入relay log时,维持文件末尾偏移量,SQL线程可以根据该偏移量安全的读取事件

3. Set master_info_repository=TABLE

4. Reducing plugin_lock mutex contention

5. Semisync mysqlbinlog

6. GTID

Semi synchronous replication的更多相关文章

  1. 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 ...

  2. MYSQL 备份工具

    backup of a database is a very important thing. If no backup, meet the following situation goes craz ...

  3. mysql常规巡检

    mysql常规巡检   目录 一.巡检脚本 二.下载巡检脚本 三.脚本执行说明 1.inspection.conf 使用说明 2.inspection_mysql.sh 使用说明 3.mysqltun ...

  4. MySQL半同步复制配置

    ansible-playbook -f 3 endpoint/mysql.yml -e "exec=fileConfig" -e "db_action=setAll&qu ...

  5. 第十章· MySQL的主从复制

    一.主从复制简介  2015年5月28日11时,12小时后恢复,损失:平均每小时106.48W$ 1)高可用 2)辅助备份 3)分担负载 复制是 MySQL 的一项功能,允许服务器将更改从一个实例复 ...

  6. mysqltuner对数据库的优化

    主要用于对mysql配置及my.cnf配置检查,提供详细信息,为进一步优化mysql做参考. 下载地址: (1)http://mysqltuner.com/ (2)脚本获取# wget -c http ...

  7. MySQL--14 半同步复制

    目录 MySQL半同步复制 半同步复制开启方法 测试半同步 MySQL过滤复制 MySQL半同步复制 从MYSQL5.5开始,支持半自动复制.之前版本的MySQL Replication都是异步(as ...

  8. MySQL 主从复制(下)

    延时复制 因为延时复制主从数据同一时间不一致, 所以延时从库一般只能做备份,不提供任何对外服务 配置延时复制(已经有主从) 1.停止主从 mysql> stop slave; Query OK, ...

  9. MySQL5.7新特性:lossless replication 无损复制

    MySQL的三种复制方式 asynchronous 异步复制 fully synchronous 全同步复制 Semisynchronous 半同步复制 asynchronous replicatio ...

随机推荐

  1. lvs 最常用算法 + tcpdump vrrp 抓包

    1.SH: source hash, 源地址散列. 将请求的目标IP地址换成请求的源IP地址:实现session保持的机制:将来自于同一个IP的请求始终调度至同一RS: 源地址散列调度算法正好与目标地 ...

  2. mysql中唯一约束用法

    以前比较naive,有次同事一定要在表里建唯一约束的时候,我就很纳闷为啥非要在db层面做限制,在自己的业务代码里做啊,就是说入库的时候先查一遍有没有,没有记录的情况再准许入库. 后来发现如果只是自己处 ...

  3. STS-新建spring mvc项目

    引入响应的jar包解决报错: 由于国内的网络限制,下载会较慢.使用之前可自行更换maven的镜像路径,越近越好.

  4. 一键安装Docker图形化管理界面-Shipyard

    Shipyard是一款开源的图形化的Docker管理工具,记得以前安装很麻烦的,现在官方有了自动安装脚本,使用非常方便.复制.粘贴.使用,就这么简单.先不研究他是如何实现的,安装使用起来再说. $ c ...

  5. mssql2012的分页查询

    sql2102支持的分页查询 注意:以下都是先执行排序,再取行数据 select* from t_workers order by worker_id desc offset 3 rows   --先 ...

  6. 2017-2018-2 20155315《网络对抗技术》免考五:Windows提权

    原理 使用metasploit使目标机成功回连之后,要进一步攻击就需要提升操作权限.对于版本较低的Windows系统,在回连的时候使用getsystem提权是可以成功的,但是对于更高的系统操作就会被拒 ...

  7. IIS发布问题

    下午发布一个IIS ,出现一个很奇葩的问题,在本地跑代码运行都正常,但是发布到IIS上后 访问提示: CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framewo ...

  8. 【Qt】QOpenGLWidget展示蒙版效果

    关键代码是派生QOpenGLWidget,覆写paintEvent函数 QPainter p; p.begin(this); p.drawImage(QPoint(, ), m_Img); QLine ...

  9. Tengine 添加第三方监控模块nginx-module-vts

    一.概述 除nginx官网源码提供的各种模板,nginx还有第三方模块.官方文档中也列出了nginx的很多第三方模块,除官网之外,还有很多的有用的模块也能在Github上找到. 官网第三方模块地址:h ...

  10. libgdx学习记录6——动作Action

    libgdx中的Action类能够有效的帮助我们实现位移.旋转.缩放.淡入淡出等效果,对游戏的设计很有用. Action是一个抽象类,本身不可以实例化.一般使用的它的继承类,常用的有 MoveToAc ...