默认情况下,MySQL的复制功能是异步的,异步复制可以提供最佳的性能,主库把binlog日志发送给从库即结束,并不验证从库是否接收完毕。这意味着当主服务器或从服务器端发生故障时,有可能从服务器没有接收到主服务器发送过来的binlog日志,这就会造成主服务器和从服务器的数据不一致,甚至在恢复时造成数据的丢失。
MySQL5.5版本为了保证主从数据的一致性问题。加入了半同步复制的组件(插件),可以控制从库IO线程是否将relaylog落盘,一旦落盘通过插件返回ACK给主库ACK_REC。接受到ACK之后,主库的事务才能提交成功。在默认情况下,如果超过10秒没有返回ACK,此次复制行为会切换为异步复制。
在MySQL5.6,5.7 当中也加入了一些比较好的特性,也不能完全保证的数据一致。如果生产业务比较关注主从最终一致(比如:金融等)。推荐可以使用MGR的架构,或者PXC等一致性架构。
![图片[1]-半同步复制-李佳程的个人主页](http://www.lijiach.com/wp-content/uploads/2022/11/image-123.png)
# 半同步复制默认设置
rpl_semi_sync_master_wait_point=after_commit
![图片[2]-半同步复制-李佳程的个人主页](http://www.lijiach.com/wp-content/uploads/2022/11/image-124.png)
- 缺点1: 幻读
- 当用户提交一个事务,该事务已经写入redo日志和binlog日志,但该事务还没写入从库,此时处在waiting slave dump处,此时另一个用户可以读取到这条数据,而他自己却不能;
- 缺点2:数据丢失
- 一个提交的事务在waiting slave dump处crash后,主库将比从库多一条数据
# 增强半同步复制(MySQL5.7新增功能)
rpl_semi_rsync_master_wait_point=after_sync
![图片[3]-半同步复制-李佳程的个人主页](http://www.lijiach.com/wp-content/uploads/2022/11/image-125.png)
- 改善1:解决幻读
- 当用户发起一个事务,该事务先写入二进制后,再向从库进行同步,由于还没有完成提交,此时其他用户无法读取到该数据,解决了幻读
- 改善2:解决数据丢失
- 一个事务在waiting slave dump处crash掉后,可以通过观察从库上是否存在主库的last gtid值,如果存在,这条数据正常恢复,如果不存在则删除主库的那条多余的GTID值,然后恢复,保证了数据的完整性
在MySQL8.0 实现半同步复制
# master服务器配置
[root@centos79-mysql01 ~]# vim /etc/my.cnf
[mysqld]
server-id=21
log-bin
rpl_semi_sync_master_enabled=ON #需要先安装semisync_master.so插件后,再重启
rpl_semi_sync_master_timeout=3000 #设置3s内无法同步,也将返回成功信息给客户端
# 永久安装插件
[root@centos79-mysql01 ~]# mysql -uroot -p123456
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
# 重启服务
[root@centos79-mysql01 ~]# service mysqld restart
mysql> create user copyuser@'192.168.%' identified by '123456';
mysql> grant replication slave on *.* to copyuser@'192.168.%';
mysql> show master logs;
+-----------------------------+-----------+-----------+
| Log_name | File_size | Encrypted |
+-----------------------------+-----------+-----------+
| centos79-mysql01-bin.000001 | 180 | No |
| centos79-mysql01-bin.000002 | 518 | No |
| centos79-mysql01-bin.000003 | 11501 | No |
+-----------------------------+-----------+-----------+
3 rows in set (0.00 sec)
# 从服务器1配置
[root@centos79-mysql02 ~]# vim /etc/my.cnf
[mysqld]
server-id=22
rpl_semi_sync_slave_enabled=ON #需要先安装semisync_slave.so插件后,再重启
# 永久安装插件
[root@centos79-mysql02 ~]# mysql -uroot -p123456
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
# 重启服务
[root@centos79-mysql02 ~]# service mysqld restart
# 使用复制用户请求服务器公钥
mysql -ucopyuser -p123456 -h192.168.1.21 --get-server-public-key
# 配置从主服务器同步
[root@centos79-mysql02 ~]# mysql -uroot -p123456
mysql> CHANGE MASTER TO MASTER_HOST='192.168.1.21',MASTER_USER='copyuser',MASTER_PASSWORD='123456',MASTER_PORT=3306,MASTER_LOG_FILE='centos79-mysql01-bin.000003',MASTER_LOG_POS=157;
mysql> start slave;
# 从服务器2配置
[root@centos79-mysql03 ~]# vim /etc/my.cnf
[mysqld]
server-id=23
rpl_semi_sync_slave_enabled=ON #需要先安装semisync_slave.so插件后,再重启
# 永久安装插件
[root@centos79-mysql03 ~]# mysql -uroot -p123456
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
# 重启服务
[root@centos79-mysql03 ~]# service mysqld restart
# 使用复制用户请求服务器公钥
mysql -ucopyuser -p123456 -h192.168.1.21 --get-server-public-key
# 配置从主服务器同步
[root@centos79-mysql03 ~]# mysql -uroot -p123456
mysql> CHANGE MASTER TO MASTER_HOST='192.168.1.21',MASTER_USER='copyuser',MASTER_PASSWORD='123456',MASTER_PORT=3306,MASTER_LOG_FILE='centos79-mysql01-bin.000003',MASTER_LOG_POS=11501;
mysql> start slave;
# 主服务器查看状态
mysql> show variables like '%semi%';
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled | ON |
| rpl_semi_sync_master_timeout | 3000 |
| 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 |
+-------------------------------------------+------------+
6 rows in set (0.00 sec)
mysql> SHOW STATUS LIKE 'Rpl_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 | 1 |
| Rpl_semi_sync_master_no_times | 2 |
| Rpl_semi_sync_master_no_tx | 38 |
| 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)
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END