乐趣区

关于mysql:MySQL主从复制之半同步semisync-replication

  • GreatSQL 社区原创内容未经受权不得随便应用,转载请分割小编并注明起源。

半同步简介

  • MASTER 节点在执行完客户端提交的事务后不是立即返回后果给客户端,而是期待至多一个 SLAVE 节点接管并写到 relay log 中才返回给客户端。
  • 半同步绝对于异步复制而言,进步了数据的安全性,同时也造成了肯定水平的提早,这个提早起码是一个 TCP 往返的工夫。所以,半同步复制最好在低延时的网络中应用。
  • MySQL 从 5.5 开始就反对半同步复制,在 5.7.2 版本的时候对半同步复制进行了一次改良;原先的半同步策略为 AFTER_COMMIT 改良后的策略为 AFTER_SYNC 两者的差别在于 SLAVE 节点 ACK 应答 MASTER 的机会不同。

两种模式介绍

  • AFTER_COMMIT 模式介绍

MASTER 将每个事务写入到二进制日志并刷盘保留,同时将事务发送给 SLAVE,而后将事务提交给存储引擎解决并进行提交,而后期待 SLAVE 返回确认信息,在收到确认信息后,MASTER 将后果返回给客户端,而后以后客户端能够持续工作。

  • AFTER_SYNC 模式介绍

MASTER 将每个事务写入到二进制日志并刷盘保留,同时将事务发送给 SLAVE,而后期待 SLAVE 返回确认信息,收到确认信息后,将事务提交给存储引擎解决并进行提交,并将后果返回给客户端,而后以后客户端能够持续工作。

两种形式比拟

  • 对于第一种 AFTER_COMMIT 形式,以后客户端只有在服务器向存储引擎提交数据并收到 SLAVE 返回的确认后,才会收到事务的返回后果。在事务提交之后收到 SLAVE 返回确认信息之前,此刻其余客户端能够看到以后客户端提交的事务信息。

    如果 SLAVE 节点因为网络等起因并未收到 MASTER 节点传递过去的事务,而 MASTER 节点此刻 crash 了。HA 进行故障转移,客户端都连到 SLAVE 节点上,这时先前在 MASTER 节点看到的事务在 SLAVE 节点并未看到,就会产生事务失落的状况。

  • 对于第二种 AFTER_SYNC 形式,当事务被 SLAVE 确认后 MASTER 在存储引擎层面进行提交事务后,所有客户端能力看到事务造成的数据更改。因而,所有客户端在 MASTER 上同一时刻看到是雷同的数据。

    当 MASTER 节点 crash 的状况下,所有在 MASTER 上提交的事务都被复制到 SLAVE(保留到中继日志中)。MASTER 服务器意外 crash。此刻 HA 进行故障转移到 SALVE 后,客户端看到的数据是无损的,因为 SLAVE 是最新的。
    留神,然而,在这种状况下,MASTER 不能间接复原应用,因为它的二进制日志可能蕴含未提交的事务,此刻当二进制日志复原并用于业务需要时,可能会导致与 SLAVE 的抵触。

如何开启半同步

  • 形式 1:半同步以插件的模式存在,咱们能够间接在线开启即可(本次采纳这次形式)
# 主节点开启
[root@GreatSQL][(none)]>INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.02 sec)

# 从节点开启
[root@GreatSQL][(none)]>INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
Query OK, 0 rows affected (0.02 sec)

# PS:个别状况下所有节点都同步部署 master 和 slave 插件,这样故障切换的时候会比拟不便解决
  • 形式 2:在 my.cnf 配置中进行开启
# 主从节点都同步配置开启
plugin-load="rpl_semi_sync_master=semisync_master.so;rpl_sync_slave=semisync_slave.so"
rpl_semi_sync_master_enabled=1
rpl_semi_sync_slave_enabled=1

查看插件开启状况

  • 形式 1:查问plugin
# 主节点查看
[root@GreatSQL][test]>show plugins;
| rpl_semi_sync_master | ACTIVE | REPLICATION | semisync_master.so | GPL |

# 从节点查看
[root@GreatSQL][(none)]>show plugins;
| rpl_semi_sync_slave | ACTIVE | REPLICATION | semisync_slave.so | GPL |
  • 形式二:查问 information_schema.plugins 信息更全面
# 主节点信息
(Thu Feb 17 03:03:12 2022)[root@GreatSQL][(none)]>select * from information_schema.plugins where plugin_name like "%semi%"\G;
*************************** 1. row ***************************
           PLUGIN_NAME: rpl_semi_sync_master
        PLUGIN_VERSION: 1.0
         PLUGIN_STATUS: ACTIVE
           PLUGIN_TYPE: REPLICATION
   PLUGIN_TYPE_VERSION: 4.0
        PLUGIN_LIBRARY: semisync_master.so
PLUGIN_LIBRARY_VERSION: 1.10
         PLUGIN_AUTHOR: Oracle Corporation
    PLUGIN_DESCRIPTION: Semi-synchronous replication master
        PLUGIN_LICENSE: GPL
           LOAD_OPTION: ON
1 row in set (0.00 sec)

ERROR:
No query specified

# 从节点信息
(Thu Feb 17 16:05:19 2022)[root@GreatSQL][(none)]>select * from information_schema.plugins where plugin_name like "%semi%"\G;
*************************** 1. row ***************************
           PLUGIN_NAME: rpl_semi_sync_slave
        PLUGIN_VERSION: 1.0
         PLUGIN_STATUS: ACTIVE
           PLUGIN_TYPE: REPLICATION
   PLUGIN_TYPE_VERSION: 4.0
        PLUGIN_LIBRARY: semisync_slave.so
PLUGIN_LIBRARY_VERSION: 1.10
         PLUGIN_AUTHOR: Oracle Corporation
    PLUGIN_DESCRIPTION: Semi-synchronous replication slave
        PLUGIN_LICENSE: GPL
           LOAD_OPTION: ON
1 row in set (0.00 sec

开启半同步性能

  • 因为下面是在线装置插件的,所以插件装置实现后,服务还要启动一下
# 主节点启用半同步复制
[root@GreatSQL][test]>SET GLOBAL rpl_semi_sync_master_enabled = on;
Query OK, 0 rows affected (0.00 sec)

# 从节点启用半同步复制
[root@GreatSQL][(none)]>SET GLOBAL rpl_semi_sync_slave_enabled = on;
Query OK, 0 rows affected (0.00 sec)
  • 以上设置实现后,从节点重启 IO 线程
(Mon Feb 14 15:19:58 2022)[root@GreatSQL][(none)]>
(Mon Feb 14 15:19:58 2022)[root@GreatSQL][(none)]>STOP SLAVE IO_THREAD;
Query OK, 0 rows affected, 1 warning (0.01 sec)

(Mon Feb 14 15:21:41 2022)[root@GreatSQL][(none)]>START SLAVE IO_THREAD;
Query OK, 0 rows affected, 1 warning (0.01 sec)

查看半同步是否运行

# 主节点
[root@GreatSQL][test]>show status like 'Rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name               | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON    |
+-----------------------------+-------+
1 row in set (0.00 sec)

# 从节点
[root@GreatSQL][(none)]>show status like 'Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.01 sec)
  • 查看主节点 error.log,能够看进去从节点曾经启用半同步复制了
# 要害信息 Start semi-sync binlog_dump to slave (server_id: 3306)
2022-02-14T02:16:35.411061-05:00 13 [Note] [MY-010014] [Repl] While initializing dump thread for slave with UUID <652ade08-8b1c-11ec-9f62-00155dcff90a>, found a zombie dump thread with the same UUID. Master is killing the zombie dump thread(12).
2022-02-14T02:16:35.411236-05:00 13 [Note] [MY-010462] [Repl] Start binlog_dump to master_thread_id(13) slave_server(3306), pos(, 4)
2022-02-14T02:16:35.411263-05:00 13 [Note] [MY-011170] [Repl] Start asynchronous binlog_dump to slave (server_id: 3306), pos(, 4).
2022-02-14T02:16:35.411419-05:00 12 [Note] [MY-011171] [Repl] Stop asynchronous binlog_dump to slave (server_id: 3306).
2022-02-14T02:19:33.913084-05:00 9 [Note] [MY-011130] [Repl] Semi-sync replication initialized for transactions.
2022-02-14T02:19:33.913133-05:00 9 [Note] [MY-011142] [Repl] Semi-sync replication enabled on the master.
2022-02-14T02:19:33.913638-05:00 0 [Note] [MY-011166] [Repl] Starting ack receiver thread.
2022-02-14T02:21:46.899725-05:00 14 [Note] [MY-010014] [Repl] While initializing dump thread for slave with UUID <652ade08-8b1c-11ec-9f62-00155dcff90a>, found a zombie dump thread with the same UUID. Master is killing the zombie dump thread(13).
2022-02-14T02:21:46.899894-05:00 14 [Note] [MY-010462] [Repl] Start binlog_dump to master_thread_id(14) slave_server(3306), pos(, 4)
2022-02-14T02:21:46.899953-05:00 14 [Note] [MY-011170] [Repl] Start semi-sync binlog_dump to slave (server_id: 3306), pos(, 4).

以上,MySQL 半同步复制搭建结束!

半同步参数信息

# 主节点参数信息
[root@GreatSQL][test]>show variables like '%Rpl%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_read_size                             | 8192       |
| rpl_semi_sync_master_enabled              | ON         |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
| rpl_stop_slave_timeout                    | 31536000   |
+-------------------------------------------+------------+
8 rows in set (0.00 sec)
  • 局部参数简略阐明
参数名 用处
rpl_semi_sync_master_enabled 是否开启半同步复制,ON 为开启,OFF 为敞开
rpl_semi_sync_master_timeout Master 期待 Slave 的 ack 回复的超时工夫,默认为 10 秒(根本单位毫秒)
rpl_semi_sync_master_trace_level 调试级别
rpl_semi_sync_master_wait_for_slave_count Master 提交后须要的 ACK 回复的数量。如果 Slave 数量大于等于这个值,那么 Master 就失常,如果低于这个值,Master 可能会在事务提交阶段产生一次超时期待,当期待超过参数(rpl_semi_sync_master_timeout)设定时,Master 就转为异步模式
rpl_semi_sync_master_wait_no_slave 就是在超时工夫内,如果 Slave 宕机的数量超过了应该要收到的 ack 数量,Master 是否降级为异步复制
rpl_semi_sync_master_wait_point 半同步的形式是哪一种,默认是 AFTER_SYNC,5.7.2 之前是 AFTER_COMMIT
# 从节点参数信息
[root@GreatSQL][test]>show variables like '%Rpl%';
+---------------------------------+----------+
| Variable_name                   | Value    |
+---------------------------------+----------+
| rpl_read_size                   | 8192     |
| rpl_semi_sync_slave_enabled     | ON       |
| rpl_semi_sync_slave_trace_level | 32       |
| rpl_stop_slave_timeout          | 31536000 |
+---------------------------------+----------+
4 rows in set (0.00 sec)
  • 局部参数简略阐明
参数名 用处
rpl_semi_sync_master_enabled 是否开启半同步复制,ON 为开启,OFF 为敞开
rpl_semi_sync_slave_trace_level 调试级别

半同步状态信息

  • 主节点查看
[root@GreatSQL][test]> show status like '%Rpl_semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     |
| 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)
  • 局部参数用处简要阐明
参数名 用处
Rpl_semi_sync_master_clients 以后有多少个从库被设置为半同步模式,不蕴含异步复制的 Slave 实例
Rpl_semi_sync_master_net_avg_wait_time 期待从库返回 ACK 确认音讯的均匀工夫(单位:ms)
Rpl_semi_sync_master_net_wait_time 等到从库返回 ACK 确认音讯的总工夫(单位:ms)
Rpl_semi_sync_master_net_waits 期待从库返回 ACK 确认音讯的总次数
Rpl_semi_sync_master_no_tx 事务没有失去从库返回确认音讯就提交的次数
Rpl_semi_sync_master_status 当半同步复制开启后,该变量用来动静地显示半同步复制的状态。当值为 OFF, 表明以后处于异步复制下; 当期待从库返回确认音讯工夫超过 rpl_semi_sync_master_timeout 值后批改为 OFF。当值设置为 ON, 表明以后处于半同步复制下。当从库追赶上主库后批改为 ON。
Rpl_semi_sync_master_timefunc_failures 调用函数 gettimeofday()失败的次数
Rpl_semi_sync_master_tx_avg_wait_time MASTER 上均匀每个事务期待时长
Rpl_semi_sync_master_tx_wait_time MASTER 上事务期待的总时长
Rpl_semi_sync_master_tx_waits MASTER 上事务期待的次数
Rpl_semi_sync_master_wait_pos_backtraverse MASTER 期待事件的二进制坐标低于之前期待事件的总次数。当事务开始期待回复的程序与其二进制日志事件的写入程序不同时,就会产生这种状况。这种状况在敞开 binlog_order_commit 的状况下可能会呈现。
Rpl_semi_sync_master_wait_sessions 以后期待从库返回确认音讯的回话数
Rpl_semi_sync_master_yes_tx Slave 节点确认胜利提交的事务数
# 从节点转态信息
show global status like '%semi%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)
  • 参数简略阐明
参数名 用处
Rpl_semi_sync_slave_status 动静参数,ON 示意在用半同步复制,OFF 示意异步复制

测试一下半同步的同步状况

  • 半同步是否会降级为异步复制?是会的。
  • 当半同步复制产生超时时(由 rpl_semi_sync_master_timeout 参数管制,单位是毫秒,默认为 10000,即 10s),会临时敞开半同步复制,转而应用异步复制。
  • 当 MASTER DUMP 线程发送完一个事务的所有事件之后,如果在 rpl_semi_sync_master_timeout 内,收到了从库的响应,则主从又从新复原为半同步复制。
# 1. 从节点临时先关掉 IO 线程
[root@GreatSQL][(none)]>STOP SLAVE IO_THREAD;
Query OK, 0 rows affected, 1 warning (0.02 sec)

# 2. 主节点写入几条测试数据
[root@GreatSQL][test]>insert into ptype values(4,'4','4'),(5,'5','5'),(6,'6','6');
Query OK, 3 rows affected (0.02 sec)

# 3. 期待 10s 后查看复制状态,半同步曾经关掉了
[root@GreatSQL][test]>show status like 'Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | OFF   |
+----------------------------+-------+
1 row in set (0.00 sec)

# 4. 从节点开启 IO 线程
[root@GreatSQL][(none)]>START SLAVE IO_THREAD;
Query OK, 0 rows affected, 1 warning (0.02 sec)

# 5. 再次查看复制状态,半同步复制主动开启了
[root@GreatSQL][test]>show status like 'Rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+
1 row in set (0.00 sec)

Enjoy GreatSQL :)

文章举荐:

GreatSQL 季报(2021.12.26)
https://mp.weixin.qq.com/s/FZ…

技术分享 |sysbench 压测工具用法浅析
https://mp.weixin.qq.com/s/m1…

故障剖析 | linux 磁盘 io 利用率高,剖析的正确姿态
https://mp.weixin.qq.com/s/7c…

技术分享 | 闪回在 MySQL 中的实现和改良
https://mp.weixin.qq.com/s/6j…

万答 #20,索引下推如何进行数据过滤
https://mp.weixin.qq.com/s/pt…

对于 GreatSQL

GreatSQL 是由万里数据库保护的 MySQL 分支,专一于晋升 MGR 可靠性及性能,反对 InnoDB 并行查问个性,是实用于金融级利用的 MySQL 分支版本。

Gitee:
https://gitee.com/GreatSQL/Gr…

GitHub:
https://github.com/GreatSQL/G…

Bilibili:
https://space.bilibili.com/13…

微信 &QQ 群:
可搜寻增加 GreatSQL 社区助手微信好友,发送验证信息“加群”退出 GreatSQL/MGR 交换微信群

QQ 群:533341697
微信小助手:wanlidbc

本文由博客一文多发平台 OpenWrite 公布!

退出移动版