怎么实现MySQL中的半同步复制

62次阅读
没有评论

共计 5174 个字符,预计需要花费 13 分钟才能阅读完成。

这篇文章给大家介绍怎么实现 MySQL 中的半同步复制,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

关于 MySQL 的复制架构,大体有下面三种方式,异步,全同步复制,半同步复制。

三种复制方式

  第一种是异步复制,是比较经典的主从复制,搭建主从默认的架构方式,就是属于异步的,相对来说性能要好一些。但是还是会有丢失数据的情况。

 
第二种是全复制,比如说 MySQL Cluster 这样的方式,是属于全复制的,实际上 MySQL
Cluster 其实发展并不大顺利,更多时候是一个实验室产品,但是时间定格在 2016 年 12 月 12 日,MySQL  5.7.17
GA 的重大特性 group
replication 插件推出,增强了 MySQL 原有的高可用方案 (原有的 Replication 方案),提供了重要的特性—多写,保证组内高可用,确保数据最终一致性。有点类似 Oracle 里面的 RAC.

  第三种是在异步和全复制之间的一种方案,就是半同步 semi-sync replication。自 MySQL 5.5 推出,是对异步和全复制的一种补充,确切的说,应该是对 MySQL Cluster 这种方案的补充。

 
如果把这个和 Oracle 联系起来,其实和 Oracle 高可用模式有点类似,Oracle 中是最大性能模式,最大保护模式,最大高可用模式,其中最大性能模式就是异步的方式,类似于异步复制的角色,最大保护模式是完全的数据同步,有点类似于全复制的方案,而最大高可用模式是介于两者之间,甚至可以达到动态切换,和半同步复制的角色差不多。

半同步复制

要开启半同步,我们需要安装插件,这个过程就很简单了。基本的要求是在满足异步复制的情况下,版本在 5.5 以上,并且变量 have_dynamic_loading 为 YES

show variables like %have_dynamic_loading%
+———————-+——-+
| Variable_name  | Value |
+———————-+——-+
| have_dynamic_loading | YES  |
+———————-+——-+
1 row in set (0.00 sec) 在 base 目录下,可以很容易找到所需的插件。当前的 base 目录为 /usr, 可以根据关键字找到插件。

# find . -name semisync_master.so
./lib64/mysql/plugin/semisync_master.so
./lib64/mysql/plugin/debug/semisync_master.so

要安装插件就是两个简单的命令。

install plugin rpl_semi_sync_master soname semisync_master.so
Query OK, 0 rows affected (0.11 sec)

install plugin rpl_semi_sync_slave soname semisync_slave.so
Query OK, 0 rows affected (0.00 sec) 安装后查看 mysql.plugin 看看插件记录是否存在,或者使用 show plugins 也可以。

select * from mysql.plugin;
+———————-+——————–+
| name  | dl  |
+———————-+——————–+
| rpl_semi_sync_master | semisync_master.so |
| rpl_semi_sync_slave  | semisync_slave.so  |
+———————-+——————–+
2 rows in set (0.00 sec) 当然默认半同步的开关还没有打开。

show variables like rpl_semi_sync_master%
+————————————+——-+
| Variable_name  | Value |
+————————————+——-+
| rpl_semi_sync_master_enabled  | OFF  |
| rpl_semi_sync_master_timeout  | 10000 |
| rpl_semi_sync_master_trace_level  | 32  |
| rpl_semi_sync_master_wait_no_slave | ON  |
+————————————+——-+
4 rows in set (0.00 sec) 这里涉及到两个参数 rpl_semi_sync_master_enabled 和 rpl_semi_sync_slave_enabled,比较直观。

打开即可。set global rpl_semi_sync_master_enabled=1;
set global rpl_semi_sync_slave_enabled=1; 如果在 master 端简单验证,也可以使用 show status

show status like rpl_semi_sync_master_status
+—————————–+——-+
| Variable_name  | Value |
+—————————–+——-+
| Rpl_semi_sync_master_status | ON  |
+—————————–+——-+ 当然在 slave 端也需要做同样的操作,然后在 slave 端重启 IO_Thread 即可。

STOP SLAVE IO_THREAD;
Query OK, 0 rows affected (0.01 sec)
START SLAVE IO_THREAD;
Query OK, 0 rows affected (0.01 sec)Master 端检查 Rpl_semi_sync_master_statusSlave 端检查

Rpl_semi_sync_slave_status

半同步在 MySQL 5.6,5.7 的变化

MySQL  5.7 中新增了一个参数来控制半同步模式下 主库在返回给会话事务成功之前提交事务的方式。

show variables like rpl_semi_sync_master_wait_point
+———————————+————+
| Variable_name  | Value  |
+———————————+————+
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
+———————————+————+
1 row in set (0.00 sec) 而在 MySQL 5.6 中是什么设置呢,是 AFTER_COMMIT

这两个参数该怎么理解。我参考了 https://sanwen8.cn/p/105GRDe.html  中的图片。

master 的数据写入了 binlog,slave 刷新到磁盘 (relay log),所以在 OLTP 的场景下,master 需要等待 slave 反馈收到 relay log,只有收到 ACK 后 master 才将 commit OK 结果反馈给客户端

而 MySQL 5.7 中的半同步复制,有个叫法是 Loss-Less 半同步复制。实现的方式有了一些差别。

这种模式(AFTER_SYNC),事务是在提交之前发送给 Slave,当 Slave 没有接收成功,并且如果发生 Master 宕机的场景,不会导致主从不一致,因为此时 Master 端还没有提交,所以主从都没有数据。

简单测试半同步复制

我们来简单看看半同步复制的一些小测试。

create database testsync;

然后创建一个表,插入一行数据。很明显执行速度很快。

create table testsync.test(id int);
Query OK, 0 rows affected (0.07 sec)

insert into testsync.test values(100);
Query OK, 1 row affected (0.01 sec) 我们模拟网络延迟的情况,直接把 slave 停掉。

stop slave; 这个时候在 Master 端插入数据就会有很慢。这个过程持续了大概 10 秒多。

insert into testsync.test values(101);
Query OK, 1 row affected (10.00 sec) 这里为什么是 10 秒,和一个扮同步复制的参数有关。单位是毫秒,所以换算下来就是 10 秒。

show variables like rpl_semi_sync_master_timeout
+——————————+——-+
| Variable_name  | Value |
+——————————+——-+
| rpl_semi_sync_master_timeout | 10000 |
+——————————+——-+

我们看看扮同步复制的开关。

show status like Rpl_semi_sync_master_status
+—————————–+——-+
| Variable_name  | Value |
+—————————–+——-+
| Rpl_semi_sync_master_status | OFF  |
+—————————–+——-+slave 端也是 OFF 的状态。

我们恢复状态,把 slave 启动。然后在 Master 端继续插入一条记录,速度就很快了。

insert into testsync.test values(102);
Query OK, 1 row affected (0.00 sec) 此时的开关是打开的。

show status like Rpl_semi_sync_master_status
+—————————–+——-+
| Variable_name  | Value |
+—————————–+——-+
| Rpl_semi_sync_master_status | ON  |
+—————————–+——-+ 查看数据库日志,其实也能看到很明确的信息。

2017-02-04T23:37:44.551667+08:00 2145633 [Warning] Timeout waiting for
reply of binlog (file: mysql-bin.000017, pos: 1056976828), semi-sync up
to file mysql-bin.000017, position 1056976573.
2017-02-04T23:37:44.551713+08:00 2145633 [Note] Semi-sync replication switched OFF.
2017-02-04T23:41:05.824146+08:00
2145900 [Note] Start binlog_dump to master_thread_id(2145900)
slave_server(13058), pos(mysql-bin.000017, 1056976573)
2017-02-04T23:41:05.824194+08:00
2145900 [Note] Start semi-sync binlog_dump to slave (server_id: 13058),
pos(mysql-bin.000017, 1056976573)
2017-02-04T23:41:05.835505+08:00 0 [Note] Semi-sync replication switched ON at (mysql-bin.000017, 1056977083)

关于怎么实现 MySQL 中的半同步复制就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-19发表,共计5174字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)