MySQL主从复制半同步复制原理及搭建

在MySQL5.5之前的版本中,MySQL的复制是异步复制,主库和从库的数据之间存在一定的延迟,比如网络故障等各种原因,这样子容易存在隐患就是:当在主库写入一个事务成功后并提交了,但是由于从库延迟没有及时得到主库推送的Binlog日志时,主库突然宕机了,那么此时从库就可能损失这个事务,从而造成主从不一致的状况。

因此我们MySQL5.5版本之后引入了半同步复制的概念

半同步复制的原理:

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

这个示意图是半同步复制的步骤:

在这个半同步复制模式下:第1、2、3中任何一个步骤中主库宕机,则事务并没有提交成功。从库也没有得到日志,此时的主从复制数据是一致的。

那什么时候半同步复制会突然变成异步复制呢?

  在第4步的时候,如果网络延迟故障或从库宕机,那么此时主库的Binlog都没有及时传送给从库上,此时主库上的事务会等待一段时间,时间长短由参数rpl_semi_master_timeout设置的毫秒数来决定,如果Binlog在这段时间内都无法成功推送到从库上,则MySQL自动调整复制模式为异步模式,此时事务正常返回提交结果给客户端。

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

搭建步骤:

这次我们使用一个master节点两个slave节点进行搭建,并且进行此实验之前我们已经搭建好异步复制的环境了。搭建半同步复制不过是在异步的基础上添加一些插件而已。

172.31.22.29 master
172.31.26.133 slave
172.31.17.203 slave


1、首先判断一下当前版本的数据库是否支持动态扩展,因为我们的版本都是一致的,因此在一台机器上检查即可

mysql> select @@have_dynamic_loading;
+------------------------+
| @@have_dynamic_loading |
+------------------------+
| YES                    |
+------------------------+
1 row in set (0.00 sec)

2、确认支持动态增加插件以后,我们再来检查一下MySQL的$MYSQL/lib/plugin目录下是否存在主库插件“semisync_master.so”和从库插件“semisync_slave.so”。

[root@:vg_adn_tidbCkhsTest /usr/local/mysql/lib/plugin]#ls        #这里只列出了一部分而已
adt_null.so                         libtest_framework.so          libtest_sql_lock.so                         mysqlx.so
authentication_ldap_sasl_client.so  libtest_services.so           libtest_sql_processlist.so                  rewrite_example.so
auth_socket.so                      libtest_services_threaded.so  libtest_sql_replication.so                  rewriter.so
connection_control.so               libtest_session_detach.so     libtest_sql_shutdown.so                     semisync_master.so
debug                               libtest_session_info.so       libtest_sql_sqlmode.so                      semisync_slave.so
group_replication.so                libtest_session_in_thd.so     libtest_sql_stored_procedures_functions.so  test_security_context.so

接下来我们在主库上安装插件

mysql> install plugin rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.00 sec)

在两个从库上安装插件

MySQL [(none)]> install plugin rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.01 sec)

安装完成后,我们可以使用语句来查看一下:

mysql> select * from mysql.plugin;
+----------------------+--------------------+
| name                 | dl                 |
+----------------------+--------------------+
| rpl_semi_sync_master | semisync_master.so |
+----------------------+--------------------+
1 row in set (0.00 sec)

说明我们已经安装插件成功了。并且系统重启的时候也会自动加载该插件,不必担心。

3、现在我们需要分别在主库和从库上配置参数打开半同步semi-sync,默认情况下半同步设置不打开的,主库上配置全局参数。

mysql> set global rpl_semi_sync_master_enabled=1;
Query OK, 0 rows affected (0.00 sec)

mysql> set global rpl_semi_sync_master_timeout=10000;              #注意这是毫秒单位,因此这个数是10秒。
Query OK, 0 rows affected (0.00 sec)

两个从库上也需要配置:

MySQL [(none)]> set global rpl_semi_sync_slave_enabled=1;
Query OK, 0 rows affected (0.00 sec)

注意:由于之前已经配置过异步复制,因此在这里需要重启一下从库上的I/O线程。(如果是全新配置的半同步复制则不需要这一步骤。)

MySQL [(none)]> stop slave io_thread;
Query OK, 0 rows affected (0.00 sec)

MySQL [(none)]> start slave io_thread;
Query OK, 0 rows affected (0.00 sec)

有几台slave,就在几台上执行这样子的操作。到此,半同步复制就搭建成功了。

在主库上使用下面命令执行以下看看半同步复制的状态信息:

mysql> show status like '%semi_sync%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 2     |
| 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.00 sec)

我们注重关注这三个值:

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

2、Rpl_semi_sync_master_no_tx:这个值表示当前主库有多少个事务不是半同步模式下从库及时响应的。

3、Rpl_semi_sync_master_yes_tx:这个值表示当前主库上有多少个事务是通过半同步复制到从库的。

在日常的维护中,我们可以查看着三项值判断半同步复制是否是正常的。

原文地址:https://www.cnblogs.com/FengGeBlog/p/10213583.html