代码改变世界

半同步复制

2022-04-13 22:27  abce  阅读(184)  评论(0编辑  收藏  举报

 

原文没有看完,感兴趣的:https://www.percona.com/blog/face-to-face-with-semi-synchronous-replication/

异步复制和半同步复制的区别

异步复制

Asynchronous

这是标准的半同步复制。

 

在复制中有两个步骤:

1.数据拷贝。通常很快。数据从源端的二进制日志拷贝到从库的relay log中(io_thread)

2.数据应用。从库从relay log中读取数据,写入到数据库(sql_thread)。这一步通常会是瓶颈的所在,可以通过一些参数进行调优。应用日志的效率与很多因素有关,甚至与schema设计都有关。

 

半同步复制

Semi-sync

半同步复制在返回ack之前,多了一个检查。这个检查阶段发生在数据拷贝阶段,即源库二进制日志数据被拷贝到从库的relay日志阶段。

这种机制的引入,服务可能会有显着延迟,没有提供100%的数据一致性保证。负载较高的时候,可能会降低服务的可用性,因为源库在等待从库的消息反馈。

默认的半同步复制rpl_semi_sync_source_wait_point设置是after_sync:源库发生failure的时候,源库上所有提交的事务已经被复制到从库的relay log。源库发生异常退出或failover时,是无损的,因为从库已经有的同步的数据。

 

简单总结一下:

·标准的复制,分成两步:(1)从源端拷贝数据;(2)从库端应用数据

·标准复制不能保证主从数据的一致性

·半同步复制,源库将数据写入二进制日志,并等待T秒,接收N个从库的ack信息

 

创建半同步复制,请参考:https://dev.mysql.com/doc/refman/8.0/en/replication-semisync-installation.html

简单可以归纳为:

·安装插件

·源库端开启rpl_semi_sync_source_enabled=1

·从库端开启rpl_semi_sync_replica_enabled=1;如果复制已经在运行,stop/start replicat ion_thread

 

接下里我们谈谈上面提到的T秒和N个从库中的T和N。

T是超时设置,默认是10秒。参数rpl_semi_sync_source_timeout控制了源库的等待时间。超时后就会变成异步复制。根据( https://dev.mysql.com/worklog/task/?id=1720 )从库追上后又会变成半同步复制。但是根据(https://github.com/mysql/mysql-server/blob/beb865a960b9a8a16cf999c323e46c5b0c67f21f/plugin/semisync/semisync_source.cc#L844),并不能百分百切换回来。

测试发现,并不会切换回去!!!

 

N表示必须提供ACK的从库的数量。

如果你有10个从库,而半同步复制中,你可能只需要2个,并不需要所有的都必须返回ACK。

半同步复制中,源库的rpl_semi_sync_source_enabled必须开启。在半同步复制因为超时切换到异步复制的时候,检查该设置:

select @@rpl_semi_sync_source_enabled;
+--------------------------------+
| @@rpl_semi_sync_source_enabled |
+--------------------------------+
|                             1 |
+--------------------------------+

还是显示值为1。

 

在文档中,检查半同步复制状态的时候,我们应该检查Rpl_semi_sync_source_status。即表示,可能发生Rpl_semi_sync_source_status = 0而rpl_semi_sync_source_enabled =1。

那这是一个bug么?根据文档:

当源由于提交阻塞超时或从库追赶而在异步或半同步复制之间切换时,它会适当地设置Rpl_semi_sync_source_status 或 Rpl_semi_sync_master_status 状态变量的值。在源上从半同步复制自动回退到异步复制意味着 rpl_semi_sync_source_enabled 或 rpl_semi_sync_master_enabled 系统变量可能在源端具有值 1,即使此时半同步复制实际上无法运行。你可以监控 Rpl_semi_sync_source_status 或 Rpl_semi_sync_master_status 状态变量以确定源当前是使用异步复制还是半同步复制。

这不是一个bug。

 

总结一下:

·开启半同步需要设置全局变量

·源库可以在不更改该变量的情况下(静默)取消半同步复制

·永远不会自动恢复半同步

·检查半同步是否有效的方法是使用Status变量,当 Rpl_semi_sync_source_status=0和rpl_semi_sync_source_enabled=1时,你有一个超时并且源现在正在异步复制中工作

·重新激活半同步的方法是先将rpl_semi_sync_source_enabled 设置为 OFF,然后 rpl_semi_sync_source_enabled = ON

·从库可以设置半同步开/关,但除非你不停止/启动 Replica_IO_THREAD,否则变量的状态可能与服务器的状态不一致。

 

 

 

 

 

https://www.percona.com/blog/face-to-face-with-semi-synchronous-replication/