《深入浅出MySQL:数据库开发、优化与管理维护(2nd)》第31章之MySQL半同步复制搭建学习笔记

时间:2022-11-22 16:20:23

MySQL的异步复制在使用的过程中,主库和从库的数据之间存在一定的延迟,这样存在一个隐患:当在主库上写入一个事务并提交成功,而从库尚未得到主库推送的Binlog日志时,主库宕机了,例如主库可能因磁盘损坏、内存故障等造成主库上该事务Binlog丢失,此时从库就可能损失这个事务,从而造成主从不一致。

此问题可以使用半同步复制来处理,使用异步复制时,主库执行完commit操作后,在主库写入binglog日志后即可成功返回客户端,无需等待binlog日志传送给从库。

《深入浅出MySQL:数据库开发、优化与管理维护(2nd)》第31章之MySQL半同步复制搭建学习笔记

使用半同步复制时,为了保证主库上的每一个binlog事务都能够被可靠的复制到从库上,主库在每次事务成功提交时,并不及时反应给client,而是等到其中一个从库也接收到binlog事务并成功写入relay log后,主库才返回commit操作成功给client。半同步复制保证了事务成功提交后,至少有两份日志记录,一份在主库的binlog上,另一份在至少一个从库的relay log上,从而进一步保证了数据的完整性。

《深入浅出MySQL:数据库开发、优化与管理维护(2nd)》第31章之MySQL半同步复制搭建学习笔记

半同步复制模式下,在上图中的步骤①、②、③任何一个步骤中主库宕机,则事务提交失败,从库上也没有收到事务对应的binlog日志,所以主从数据一致;假如在步骤④传送binlog日志到从库时,从库宕机或者网络故障,导致binlog并没有及时地传送到从库上,此时主库上的事务会等待一段时间(时间长短由参数rpl_semi_sync_master_timeout设置的毫秒数决定),如果binlog在这段时间内都无法成功推送到从库上,则自动调整为异步模式,事务正常返回提交结果给客户端。

半同步复制很大程度上取决于主从库之间的网络情况,往返时延RTT越小决定了从库的实时性越好。通俗的说,主从时间网络越快,从库越实时。

半同步复制需要使用插件来实现,主库和从库使用不同的插件。安装简单,在异步复制的基础上,安装半同步复制插件即可。

(1)判断MySQL服务器是否支持动态添加插件

select @@have_dynamic_loading;

(2)确定支持动态添加插件后,检查MySQL的安装目录下是否存在插件,一般默认在$MYSQL_HOME/lib/plugin目录下存在主库插件semisync_master.so和从库插件semisync_slave.so:

在主库上安装semisync_master.so插件:

install plugin rpl_semi_sync_master SONAME 'semisync_master.so';

从库上安装semisync_slave.so插件:

install plugin rpl_semi_sync_slave SONAME 'semisync_slave.so';

安装完成后,从plugin表中查看刚才安装的插件,下次重启后自动加载插件

select * from mysql.plugin;

(3)需要分别在主库和从库上配置参数打开半同步semi-sync,默认半同步设置是不打开的,主库上配置全局参数

set global rpl_semi_sync_master_enabled=1;

从库上一样配置全局参数
set global rpl_semi_sync_slave_enabled=1;

如果异步复制已开启,需要重启从库上的i/o线程(如果是全新配置的半同步复制不需要):

STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;

主库上通过SHOW STATUS命令能够看到当前半同步复制的一些状态值

mysql> SHOW STATUS like '%semi_sync%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0     |
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    |
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
+--------------------------------------------+-------+
14 rows in set (0.01 sec)

Rpl_semi_sync_master_status:值为ON,表示半同步复制目前处于打开状态。

Rpl_semi_sync_master_yes_tx:值为0,表示主库当前尚未有任何一个事务是通过半同步复制到从库。

Rpl_semi_sync_master_no_tx:值为0,表示当前有0个事务不是半同步模式下从库及时响应的。


从库状态:

mysql> SHOW STATUS like '%semi_sync%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.01 sec)

如果Rpl_semi_sync_master_status和Rpl_semi_sync_slave_status都为ON,说明半同步复制搭建完成。