目录
一、MySQL半同步复制
一、三种复制方式比较
1、异步复制
2、同步复制
3、半同步复制
4、半同步复制比较
5、半同步复制的特点
二、搭建半同步复制
1、如果不清楚Plugin的目录,用如下查找:
2、所有数据库服务器,安装半同步插件(semisync_master.so,semisync_slave.so)
3、检查是否安装成功
4、查看半同步相关信息
5、修改my.cnf文件,配置主从半同步复制
6、依次重启mysql的服务(master、slave1 、slave2)
7、查看半同步相关信息
8、监控(查看)半同步复制状态
9、测试
该操作必须在实现基于GTID的主从复制的基础上进行,详细请查看:十、MySQL主从架构配置-CSDN博客
一、MySQL半同步复制
一、三种复制方式比较
1、异步复制
这是mysql默认的复制模式,异步复制是指主库写binlog、从库I/O线程读binlog并写入relaylog、从库sql线程重放事务。这三步之间是异步的。异步复制的优点是主库不需要关心备库的状态,主库不保证事务被传输到从库,如果主库崩溃,某些事务可能还未发送到从库,切换后可能导致事务的丢失。其优点是可以有更高的吞吐量,缺点是不能保持数据实时一致,不适合要求主从数据一致性要求高的应用场景。
2、同步复制
同步复制的模式下,主库在提交事务前,必须确认事务在所有的备库上都已经完成提交,即主库是最后一个提交的。在提交前需要将事务传递给从库并完成重放、提交等一系列动作,其优点是任何时候主备库都是一致的。主库的崩溃不会丢失事务,缺点是由于主库需要等待备库先提交事务,吞吐量低。
3、半同步复制
MySQL5.5 引入半同步复制,半同步复制介于异步复制和同步复制之间。主库在提交事务时先等待,必须确认至少一个从库收到了事件(从库将事件写入relaylog,不需要重放和提交,并向主库发送一个确认信息ACK),主库收到信息后才正式commit.
4、半同步复制比较
- 与同步复制相比,半同步复制速度快很多,因为他只需要至少1个从库确认写入relaylog,并不需要完成在从库上的事务提交。
- 与异步复制相比,半同步复制更安全,因为主库在提交时,事务至少已经存在2个地方(主库的binlog和从库的relaylog)。
- 由于半同步复制在提交事务前,需要从库返回确认信息,所以这里涉及到网络的往返通信开销,因此,半同步复制只适合在网络条件较好的且距离不远的环境部署,否则可能因为网络延迟大幅降低主库性能。
5、半同步复制的特点
- 从库在连接主库时需要表明它是否支持半同步复制。
- 如果主库启用了半同步复制,且有一个支持半同步复制的从库,则主库上事务提交将等待至少一个从库确认已收到事务,或者知道发生超时。
- 默认只有在将事务写入其中继日志并刷新到磁盘后,主库才会提交事务(也可以配置成提交后等待确认)。
- 如果没有任何从库确认事务的情况下发生超时,则主库将退化为异步复制。当至少有一个半同步从库赶上时,主库恢复半同步复制。退化与恢复过程都是自动的。
- 必须在主库和从库上都启用半同步复制,否则使用异步复制。
二、搭建半同步复制
为了尽可能的减少主库硬件损坏宕机造成的数据丢失,因此在配置MHA的同时建议配置成mysql的半同步复制。
MHA配置详见:十一、MYSQL 基于MHA的高可用集群-CSDN博客
注意:
mysql半同步复制是以插件形式实现的,插件由Google提供,具体位/usr/lib64/mysql/plugin/下,一个是master用的semisync_master.so,一个是slave用的semisync_slave.so,要使用半同步复制,要在主从分别安装相应的插件,并且通过参数来控制半同步复制。
使用半同步需要满足的条件:
- 服务器要支持动态加载。参数have_dynamic_loading要设置为True(MySQL8.0默认就是True)。
检查是否支持:
mysql> show variables like '%have_dynamic%';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| have_dynamic_loading | YES |
+----------------------+-------+
1 row in set (0.01 sec)
- 已经完成基础异步复制的配置
具体配置:
1、如果不清楚Plugin的目录,用如下查找:
mysql> show variables like '%plugin_dir%';
+---------------+--------------------------+
| Variable_name | Value |
+---------------+--------------------------+
| plugin_dir | /usr/lib64/mysql/plugin/ |
+---------------+--------------------------+
1 row in set (0.02 sec)
mysql>
2、所有数据库服务器,安装半同步插件(semisync_master.so,semisync_slave.so)
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (0.02 sec)
MySQL 8.0.26以上版本执行下面命令:我的是mysql Ver 8.0.16 再此不做演示
mysql> install plugin rpl_semi_sync_source soname 'semisync_source.so';
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (0.00 sec)
MySQL 8.0.26以上版本执行下面命令:我的是mysql Ver 8.0.16 再此不做演示
mysql> install plugin rpl_semi_sync_replica soname 'semisync_replica.so';
3、检查是否安装成功
mysql> show plugins;
+---------------------------------+----------+--------------------+--------------------+---------+
| Name | Status | Type | Library | License |
+---------------------------------+----------+--------------------+--------------------+---------+
| rpl_semi_sync_master | ACTIVE | REPLICATION | semisync_master.so | GPL |
| rpl_semi_sync_slave | ACTIVE | REPLICATION | semisync_slave.so | GPL |
+---------------------------------+----------+--------------------+--------------------+---------+
46 rows in set (0.00 sec)
或者使用:select * from information_schema.plugins\G;
4、查看半同步相关信息
mysql> show status like 'rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | OFF |
+-----------------------------+-------+
1 row in set (0.01 sec)
或者
mysql> show variables like '%rpl_semi_sync%'; 详解见下方
+-------------------------------------------+------------+
| 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_for_slave_count | 1 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
| rpl_semi_sync_slave_enabled | OFF |
| rpl_semi_sync_slave_trace_level | 32 |
+-------------------------------------------+------------+
8 rows in set (0.01 sec)
从上面信息可以看到 半同步复制的插件已经安装,只是没有启用,所以是OFF状态。
5、修改my.cnf文件,配置主从半同步复制
master 主机上
[root@rabbitmq_1 etc]# vim my.cnf
[mysqld]
rpl_semi_sync_master_enabled=1 #1表示启用,0表示关闭
rpl_semi_sync_master_timeout=10000
#毫秒单位,该参数主服务器等待确认消息10秒后,不在等待,变为异步方式。
rpl_semi_sync_slave_enabled=1
slave1 和slave2 上的my.cnf添加:
[root@rabbitmq_2 etc]# vim my.cnf
rpl_semi_sync_slave_enabled=1
# MySQL 8.0.26 版本以后
slave 添加:
rpl_semi_sync_replica_enabled=1
然后:
stop slave io_thread; start slave thread;
然后在主库操作master添加:
rpl_semi_sync_source_enabled=1
rpl_semi_sync_source_timeout=10000
rpl_semi_sync_replica_enabled=1
-----在线开启
6、依次重启mysql的服务(master、slave1 、slave2)
[root@rabbitmq_1 etc]# systemctl restart mysqld.service
重启完成,先检查下主从复制是否有问题
登录从库,查看从库的状态是否为两个yes
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
这个是正在连接,过几秒在看 就yes了。
(root@localhost) [(none)]> show master status;
+------------------+----------+--------------+------------------+------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000131 | 515 | | | d26ec757-adba-11ed-997d-000c297ca098:1-2 |
+------------------+----------+--------------+------------------+------------------------------------------+
7、查看半同步相关信息
mysql> show variables like '%rpl_semi_sync%';
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| 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_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | 32 |
+-------------------------------------------+------------+
8 rows in set (0.00 sec)
可以看到半同步复制已经启用了(ON),搭建完成。
参数详解:
1、如果使用的是8.0.26以上的版本,参数中的'master'会被替换为'source','slave'会被替换为'replica',
rpl_semi_sync_master_enabled #用来控制是否开启半同步复制,ON:开启,OFF:关闭
rpl_semi_sync_master_timeout #主库等待从库ACK超时的时长,单位为毫秒,默认10000(10S)
rpl_semi_sync_master_trace_level #半同步复制时,主库的调试级别
rpl_semi_sync_master_wait_for_slave_count #主库需要收到多少个ACK才认为此次提交成功,否则就降级为异步复制,默认是1,即只要有1个从库确认即可提交。
rpl_semi_sync_master_wait_no_slave #为ON时(默认值),当状态变量Rpl_semi_sync_master_clients中的值小于rpl_semi_sync_master_wait_for_slave_count时(即从库数小于需要的最小确认数)Rpl_semi_sync_master_status依旧为ON,只有当事务提交后等待rpl_semi_sync_master_timeout超时后,Rpl_semi_sync_master_status才会变为OFF,即降级为异步复制;为OFF时,当状态变量Rpl_semi_sync_master_clients中的值小于rpl_semi_sync_master_wait_for_slave_count时,Rpl_semi_sync_master_status立即显示为OFF,即立即降级为异步复制。
rpl_semi_sync_master_wait_point #控制主库上commit、接收ACK、返回控制给客户端的时间点。值为after_sync(默认)或after_commit。
# after_sync:主库会等待从库的ACK后再提交事务,最后返还控制权给客户端。主库上所有会话同一时间看到提交的事务,如果发生failover,主从数据是一致的。
# after_commit:主库会先提交事务,再等待ACK,最后返还控制权给客户端。主库会先提交,此时主库上其他会话可以看到已提交的事务,但执行事务的会话还未返还,依然在等待从库确认,如果从库因为崩溃没有处理这个事务,那么其他会话会在主从看到不一致的数据(主库事务提交了,从库的事务丢了)。
8、监控(查看)半同步复制状态
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 | 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 |
| Rpl_semi_sync_slave_status | OFF |
+--------------------------------------------+-------+
15 rows in set (0.00 sec)
可以看到目前已经有2个slave服务器已经配置成了半同步模式。
参数详解:
Rpl_semi_sync_master_clients #当前有多少个半同步从库连接到主库。
Rpl_semi_sync_master_net_avg_wait_time #主库等待从库回复的平均时间,以微秒为单位。此变量始终为0,不推荐使用,并且将在以后的版本中删除。
Rpl_semi_sync_master_net_wait_time #主库等待从库回复的总时间,以微秒为单位。此变量始终为0,不推荐使用,并且将在以后的版本中删除。
Rpl_semi_sync_master_net_waits #主库等待从库回复的总次数。
Rpl_semi_sync_master_no_times #主库关闭半同步复制的次数。
Rpl_semi_sync_master_no_tx #从库未成功确认的事务数。
Rpl_semi_sync_master_status #为ON时表示使用半同步复制,为OFF时表示异步复制。
Rpl_semi_sync_master_tx_avg_wait_time:#主库等待一个事务的平均时间,以微秒为单位。
Rpl_semi_sync_master_yes_tx:#从库成功确认的事务数。
9、测试
mysql> show databases;
+------------------------+
| Database |
+------------------------+
| information_schema |
| mysql |
| newtaxcontrol |
| newtaxcontrol-activiti |
| newtaxcontrol-server |
| newtaxcontrol-weixin |
| online_invoice |
| performance_schema |
| sys |
| tax-disk |
| tax-invoice |
| taxctrldb |
+------------------------+
12 rows in set (0.00 sec)
1、创建一个数据库
mysql> create database asd;
Query OK, 1 row affected (0.00 sec)
2、查看半同步复制状态
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 | 2 |
| 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 | 610 |
| Rpl_semi_sync_master_tx_wait_time | 610 |
| Rpl_semi_sync_master_tx_waits | 1 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 1 |
| Rpl_semi_sync_slave_status | OFF |
+--------------------------------------------+-------+
15 rows in set (0.00 sec)
3、删除刚才创建的数据库
mysql> drop database asd;
Query OK, 0 rows affected (0.01 sec)
4、再查看状态
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 | 4 |
| 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 | 513 |
| Rpl_semi_sync_master_tx_wait_time | 1027 |
| Rpl_semi_sync_master_tx_waits | 2 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 2 |
| Rpl_semi_sync_slave_status | OFF |
+--------------------------------------------+-------+
15 rows in set (0.01 sec)