mysql的半同步复制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql的半同步复制相关的知识,希望对你有一定的参考价值。
mysql的半同步复制
简介
MySQL通过复制(Replication)实现存储系统的高可用。目前,MySQL支持的复制方式有:
异步复制(Asynchronous Replication):原理最简单,性能最好。但是主备之间数据不一致的概率很大。
半同步复制(Semi-synchronous Replication):相比异步复制,半同步复制牺牲了一定的性能,提升了主备之间数据的一致性(有一些情况还是会出现主备数据不一致)。
组复制(Group Replication):基于Paxos算法实现分布式数据复制的强一致性。只要大多数机器存活就能保证系统可用。相比半同步复制,Group Replication的数据一致性和系统可用性更高。
MySQL5.5引入一种叫做半同步复制模式。开启这种模式,可以保证slave数据库接收完master数据库发送过来的binlog日志并写入自己的中继日志中,然后反馈给master数据库,告知已经复制完毕。
开启这种模式后,当出现超时,主数据库将会自动转为异步复制模式,直到至少有一台从服务器接受到主数据库的binlog,并且反馈给主数据库。这时主数据库才会切换回半同步复制模式。
异步复制即是master数据库把binlog日志发送给slave数据库,然后就没有了然后了。
默认情况下,MySQL的复制是异步的,主库执行完Commit提交操作后,在主库写入BInlog后即可成功返回给客户端,无需等待BInlog传给从 库。当在主库上写入一个事务并提交成功,而从库尚未得到主库推送的Binlog时,主库宕机了,从而从库可能损失该事务,造成主从库的不一致。
为了解决这个问题,MySQL引入了半同步复制。半同步复制保证了主库上的每一个Binlog都能可靠的复制到从库上,主库在每次事务提交时,并不及时反 馈给前端用户,而是等待其中一个从库也接收到Binlog并成功写入中继日志后,主库才返回Commit操作成功给客户端。此时,至少有两份日志记录,一 份在主库的Binlog上,另一份在至少一个从库的中继日志上,从而保证了数据的完整性。
在 master 的 dumper 线程通知 slave 后,增加了一个 ack(ack 作为一个标记),即是否成功收到事务 t1 的标志码。也就是 dumper 线程除了发送 t1 到slave,还承担了接收 slave 的 ack 工作。(这样其实就增加了 dumper 线程的额外开销)如果出现异常,没有收到 ack,那么将自动降级为普通的复制,直到异常修复。
简单理解:在主从复制的基础上,加了一层保险,在开启半同步复制的时候,随即会有 rpl_semi_sync_master_timeout 此参数的默认值,手动可以进行修改,在此值设置的时间内 master 端是会一直等待 slave 端将日志文件拉取至relay log 的 ack 确认值,若是超出设置的值,则会自动变成异步复制。
5.7 半同步的特点:
1、AFTER_SYNC,加强了数据一致性,在事物提交之前等 ack 信号
2、rpl_semi_sync_master_wait_slave_count,可以用来控制主库接受多少个 slave 写
事务成功反馈。
3、对 binlog lock 进行优化,旧版本在主提交 binlog 的写会话和 dump thread 读 binlog
的操作都会对 binlog 添加互斥锁,导致 binlog 文件的读写是串行化的。 5.7 办版本对此进
行了优化,实现了并行化。
5.6串行
5.7 并行
在主从复制的前提下,做以下实验
实验:serevr2 master
server3 slave
在master端:
安装插件
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
mysql> select * from information_schema.plugins where plugin_name like '%semi%'G;
查看半同步插件是否是激活状态 show variables like '%rpl%';
rpl_semi_sync_master_enabled #设置开启或者关闭半同步复制,默认关闭
rpl_semi_sync_master_timeout #超出此时间变成异步复制(ms)
rpl_semi_sync_master_trace_level #启用半同步复制的调制级别
rpl_semi_sync_master_wait_for_slave_count #可以有几个从进行半同步复制
rpl_semi_sync_master_wait_no_slave #是否允许 master 每个事物都要等待 slave 的 ack
rpl_semi_sync_master_wait_point #此参数在 mysql5.7 版本中默认是 AFTER_SYNC,意思是: master 等待 slave 反馈接收到 relay log 的 ack 之后, 再提交事务并且返回 commit OK 结果给客户端。 即使主库 crash,所有在主库上已经提交的事务都能保证已经同步到 slave 的 relaylog 中。
rpl_stop_slave_timeout #这个参数是在执行重大的事物时,需要 stop slave,但是此时 stop slave 的时间会很长,次参时是用来控制 stop slave 的时间的。
如下将半同步复制的参数打开
mysql> set global rpl_semi_sync_master_enabled=ON;
slave端:
安装插件
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
#查看插件是否激活
mysql> select * from information_schema.plugins where plugin_name like '%semi%'G;
#打开半同步复制从库的参数
mysql> set global semi_sync_slave_enabled=ON;
测试:
模拟网络延迟或者从库故障,将从库的 io 线程关闭
mysql> stop slave io_thread;
在主库建立写入数据
主库在 rpl_semi_sync_master_timeout=10000(毫秒)内会一直等待 slave 端的 ack
信号
将 io 线程打开后,从库已经完成了复制
插入一条记录,查看主库的状态:
mysql> insert into usertb values('use','555');
mysql> show status like '%semi_sync%';
状态值分析:
Rpl_semi_sync_master_status:值为ON,表示半同步目前是打开状态;
Rpl_semi_sync_master_yes_tx:值为1,表示主库当前是有一个事务是通过半同步复制到从库;
Rpl_semi_sync_master_no_tx:值为0,表示当前没有不是半同步模式下从库及时响应的。
模拟网络故障,半同步转为异步复制模式
1)半同步复制在主库等待10秒超时
2)模拟从库故障
mysql> stop slave;
3)主库执行一个事务并提交,主库的提交操作会阻塞10秒
新开一个窗口检查当前主库线程,发现提交操作在等待从库半同步操作相应:
mysql> show processlistG;
4)主库上等待10秒超时
检查半同步状态值:
状态值分析:
Rpl_semi_sync_master_status
:值为OFF,表示半同步关闭,目前复制模式是异步复制;
Rpl_semi_sync_master_yes_tx
:值为1,表示刚才的事务不是通过半同步完成的,不累加;
Rpl_semi_sync_master_no_tx :值为1 ,表示半同步模式下,从库没有及时响应的事务增加1个。
模拟异步复制自动切换为半同步模式
1)从库正常
2)检查从库状态,则数据同步到从库
3)检查主库半同步复制状态,表示自动切换为半同步模式
4)在主库测试当前模式是半同步模式
提交一个事务后,Rpl_semi_sync_master_yes_tx 由1变为2,表示刚才的操作是通过半同步模式完成的。
以上是关于mysql的半同步复制的主要内容,如果未能解决你的问题,请参考以下文章