全网最新最全的MySQL 8.0 半同步复制讲解

全网最新最全的MySQL 8.0 半同步复制讲解,第1张

全网最新最全的MySQL 8.0 半同步复制讲解 作者公众号,欢迎一起交流。

 对于MySQL数据库来说,单机环境会存在单点故障从而有数据丢失的风险,那么MySQL数据库的主从复制是否就能保证数据的可靠呢?本篇将对MySQL的复制进行分析,并详细介绍MySQL数据库的半同步复制机制。

1 复制分析

前面介绍了MySQL数据库基于位点的主从复制和基于GTID的主从复制的环境搭建,接下来将分析下MySQL的复制方式。

1.1 复制原理

如下图所示,当在主库执行事务时,对数据的修改以事件的形式写到Binlog文件,然后主库的DUMP线程读取Binlog文件中的事件,从库的I/O线程将从主库读取的复制事件存储在Relay Log中,SQL线程读取Relay Log并将其应用于从库,从而实现主从库的一致。

 1.2 异步复制

如下图所示,MySQL数据库默认以异步复制的方式进行主从库的同步,即当主库执行事务并写到Binlog文件后,返回客户端事务执行成功,从库通过I/O线程获得主库从DUMP线程读取的Binlog内容,但主库并不知道从库是否已获得Binlog中的事务并进行处理,也就是说不能保证主库Binlog中的事件能够到达从库。如果主库发生crash,主库已提交的事务可能还没来得及传输到从库,这时进行主库到从库的Failover,就可能会发生数据的丢失。这就是异步复制的工作机制。

 1.3 全同步复制

如下图所示,相比较于异步复制会有数据丢失的风险,那么如果在主库执行的事务在所有从库应用后再返回客户端事务执行成功,由于主库执行的事务在从库都已执行,这样即使主库发生crash,主库到从库的Failover也不会发生数据的丢失,这就是全同步复制的工作机制,但是这种方式会有一个很大的缺点,那就是完成一个事务可能会有很大的延迟。

 1.4 半同步复制

如下图所示,由于异步复制可能会引起数据的丢失,而全同步复制可能会产生很大的延迟,那么半同步复制是以上两种复制的一个折中,当主库执行事务并写到Binlog文件后,主库等待至少一个从库(从库数量可配置)接收并记录Binlog事件到从库的Relaylog中,收到从库的确认后,提交事务并返回客户端事务执行成功,这就是半同步复制的工作机制,它既保证了即使主库发生crash也不会丢失数据(因为至少有一个从库获取到了主库的Binlog日志),又不会完成一个事务产生很大的延迟(因为不用等待所有从库都接收到Binlog日志并将其在从库重放)。

 2 安装半同步复制

半同步复制是通过插件来实现的,因此,安装半同步复制环境,需先在主、从库安装半同步复制插件,插件安装后,便有了相关的系统变量、状态变量对半同步环境进行配置和监控。要使用半同步复制,必须满足如下要求:

  • MySQL服务器支持动态加载插件,即变量have_dynamic_loading值为YES,默认支持
  • 主从复制环境已经运行,即在已经运行的复制环境安装半同步复制插件并进行相应的配置
  • 半同步复制只支持默认的复制通道,不能同时配置多个复制通道

实验环境若无特殊说明,MySQL数据库版本均为8.0.27

2.1 安装半同步复制插件

1)查看插件所在位置

mysql> show variables like 'plugin_dir';

+---------------+------------------------------+

| Variable_name | Value |

+---------------+------------------------------+

| plugin_dir | /usr/local/mysql/lib/plugin/ |

+---------------+------------------------------+

1 row in set (0.00 sec)

2)主库安装插件

mysql> install plugin rpl_semi_sync_source soname 'semisync_source.so';

Query OK, 0 rows affected (0.03 sec)

3)从库安装插件

mysql> install plugin rpl_semi_sync_replica soname 'semisync_replica.so';

Query OK, 0 rows affected (0.03 sec)

4)检查插件安装

mysql> show plugins;
2.2 开启半同步复制

半同步复制插件安装完成后,默认是没有激活半同步复制,需同时在主库和从库进行激活。

1)主库激活半同步复制

mysql> set global rpl_semi_sync_source_enabled=1;

Query OK, 0 rows affected (0.00 sec)



mysql> show variables like 'rpl_semi_sync_source_enabled';

+------------------------------+-------+

| Variable_name | Value |

+------------------------------+-------+

| rpl_semi_sync_source_enabled | ON |

+------------------------------+-------+

1 row in set (0.00 sec)

2)从库激活半同步复制

mysql> set global rpl_semi_sync_replica_enabled=1;

Query OK, 0 rows affected (0.00 sec)



mysql> show variables like 'rpl_semi_sync_replica_enabled';

+-------------------------------+-------+

| Variable_name | Value |

+-------------------------------+-------+

| rpl_semi_sync_replica_enabled | ON |

+-------------------------------+-------+

1 row in set (0.00 sec)

3)重新启动I/O线程

mysql> stop replica io_thread;

Query OK, 0 rows affected (0.00 sec)



mysql> start replica io_thread;

Query OK, 0 rows affected (0.00 sec)

4)插入一条记录进行验证,可以看到,Rpl_semi_sync_source_yes_tx的值为1

mysql> insert into test.test values(1,'Alen');

Query OK, 1 row affected (0.12 sec)



mysql> show global status like 'rpl%';

+--------------------------------------------+-------+

| Variable_name | Value |

+--------------------------------------------+-------+

| Rpl_semi_sync_source_clients | 1 |

| Rpl_semi_sync_source_net_avg_wait_time | 0 |

| Rpl_semi_sync_source_net_wait_time | 0 |

| Rpl_semi_sync_source_net_waits | 1 |

| Rpl_semi_sync_source_no_times | 0 |

| Rpl_semi_sync_source_no_tx | 0 |

| Rpl_semi_sync_source_status | ON |

| Rpl_semi_sync_source_timefunc_failures | 0 |

| Rpl_semi_sync_source_tx_avg_wait_time | 1754 |

| Rpl_semi_sync_source_tx_wait_time | 1754 |

| Rpl_semi_sync_source_tx_waits | 1 |

| Rpl_semi_sync_source_wait_pos_backtraverse | 0 |

| Rpl_semi_sync_source_wait_sessions | 0 |

| Rpl_semi_sync_source_yes_tx | 1 |

+--------------------------------------------+-------+

14 rows in set (0.00 sec)

5)将配置写入到配置文件/etc/my.cnf

主库:rpl_semi_sync_source_enabled = 1

从库:rpl_semi_sync_replica_enabled = 1
3 配置半同步复制

在主、从库安装完半同步复制插件后,就可以使用相关的系统变量对半同步复制进行配置,变量的查看可以使用Show Variables命令进行查看。

3.1 查看主库的半同步复制变量

在主库执行show variables 命令,即可看到半同步复制主库端相应的系统变量:

mysql> show variables like 'rpl_semi%';

+---------------------------------------------+------------+

| Variable_name | Value |

+---------------------------------------------+------------+

| rpl_semi_sync_source_enabled | ON |

| rpl_semi_sync_source_timeout | 10000 |

| rpl_semi_sync_source_trace_level | 32 |

| rpl_semi_sync_source_wait_for_replica_count | 1 |

| rpl_semi_sync_source_wait_no_replica | ON |

| rpl_semi_sync_source_wait_point | AFTER_SYNC |

+---------------------------------------------+------------+

6 rows in set (0.00 sec)

变量说明:

1)rpl_semi_sync_source_enabled

默认OFF,用于控制主库是否启用半同步复制,设置为ON,表示主库开启半同步复制

2)rpl_semi_sync_source_timeout

默认10000毫秒(10秒),用于控制主库等待从库返回确认提交的超时时间,若超过对应的时间未收到从库的确认,则半同步复制将退化为异步复制

3)rpl_semi_sync_source_trace_level

默认32,用于控制主库半同步复制调试跟踪级别,定义的级别共有4个,分别是:1、16、32和64

4)rpl_semi_sync_source_wait_for_replica_count

默认1,用于控制主库在返回客户端会话前每个事务必须被多少个从库接收,默认是1,即主库收到一个从库接收到事务事件的确认信息后,即可进行提交事务并返回给客户端会话,该值越小,性能越好

5)rpl_semi_sync_source_wait_no_replica

默认ON,即允许在超时时间内从库的数量小于rpl_semi_sync_source_wait_for_replica_count配置的值,只要在超时时间到期前有足够的从库确认事务,半同步复制就会继续

6)rpl_semi_sync_source_wait_point

默认AFTER_SYNC,用于控制主库在向提交事务的客户端返回状态前等待接收事务的从库确认的时间点,该参数有两个值,分别是AFTER_SYNC和AFTER_COMMIT,不同的值,产生的影响不同:

AFTER_COMMIT:

当rpl_semi_sync_source_wait_point=after_commit时,事务的执行过程如图,由于先在存储引擎层进行提交,然后等待从库的确认,如果在从库确认的过程中,主库宕机了,此时,可能的情况有两种:

事务还没发送到从库上

此时,客户端会收到事务提交失败的信息,客户端会重新提交该事务到新的主库上,当宕机的主库重新启动后,以从库的身份重新加入到该主从架构中,会发现该事务在从库中被提交了两次,一次是之前作为主的时候,一次是被新主库同步过来的。

事务已经发送到从库上

此时,从库已经收到并应用了该事务,但是客户端仍然会收到事务提交失败的信息,重新提交该事务到新的主库上。

 使用AFTER_COMMIT,事务在存储引擎层提交后,执行事务的客户端便收到返回信息,在提交到存储引擎之后和从库发出应答确认之前的这段时间,其他客户端可以看到已经提交的事务,如果此时发生错误,主从库切换后,之前可能看到数据的客户端发现在新主库看不到对应的数据了,比如下面的插入 *** 作,会发生幻读。

 

 AFTER_SYNC:

当rpl_semi_sync_source_wait_point=after_sync时,事务的执行过程如图,”waiting slave dump“被调整到”storage commit“之前,即先等待从库的应答确认,然后再在存储引擎层进行事务的提交。

 使用AFTER_SYNC,由于先收到从库的应答确认,然后再在存储引擎层提交事务,并返回给客户端,这样,在同样的时间,所有的客户端都可以看到已提交的数据,即使主库发生故障进行主从库切换,所有在主库提交的事务已经复制到从库,因此,从库的数据也是最新的,这种半同步方案也称为无损半同步复制。

 3.2 查看从库的半同步复制变量

在从库执行show variables 命令,即可看到半同步复制从库端相应的系统变量:

mysql> show variables like 'rpl_semi%';

+-----------------------------------+-------+

| Variable_name | Value |

+-----------------------------------+-------+

| rpl_semi_sync_replica_enabled | ON |

| rpl_semi_sync_replica_trace_level | 32 |

+-----------------------------------+-------+

2 rows in set (0.01 sec)

变量说明:

1)rpl_semi_sync_replica_enabled

默认OFF,用于控制从库是否启用半同步复制,设置为ON,表示从库开启半同步复制

2)rpl_semi_sync_replica_trace_level

默认32,用于控制从库半同步复制调试跟踪级别,定义的级别共有4个,分别是:1、16、32和64

4 监控半同步复制

半同步复制提供了很多状态变量用于查看当前复制的状态,可使用Show Status进行查看。

4.1 查看主库的半同步复制状态

在主库执行show status命令,即可看到半同步复制主库端相应的状态变量:

mysql> show status like 'rpl_semi%';

+--------------------------------------------+-------+

| Variable_name | Value |

+--------------------------------------------+-------+

| Rpl_semi_sync_source_clients | 1 |

| Rpl_semi_sync_source_net_avg_wait_time | 0 |

| Rpl_semi_sync_source_net_wait_time | 0 |

| Rpl_semi_sync_source_net_waits | 1 |

| Rpl_semi_sync_source_no_times | 0 |

| Rpl_semi_sync_source_no_tx | 0 |

| Rpl_semi_sync_source_status | ON |

| Rpl_semi_sync_source_timefunc_failures | 0 |

| Rpl_semi_sync_source_tx_avg_wait_time | 1754 |

| Rpl_semi_sync_source_tx_wait_time | 1754 |

| Rpl_semi_sync_source_tx_waits | 1 |

| Rpl_semi_sync_source_wait_pos_backtraverse | 0 |

| Rpl_semi_sync_source_wait_sessions | 0 |

| Rpl_semi_sync_source_yes_tx | 1 |

+--------------------------------------------+-------+

14 rows in set (0.00 sec)

变量说明:

1)Rpl_semi_sync_source_clients

连接到主库的半同步从库的数量

2)Rpl_semi_sync_source_net_avg_wait_time

主库等待从库应答的平均时间(以微妙为单位),值一直是0,已被弃用

3)Rpl_semi_sync_source_net_wait_time

主库等待从库应答的总时间(以微妙为单位),值一直是0,已被弃用

4)Rpl_semi_sync_source_net_waits

主库等待从库应答的总次数

5)Rpl_semi_sync_source_no_times

主库关闭半同步复制的次数,即当主库在指定时间内未收到从库的应答确认,就会退化为异步复制

6)Rpl_semi_sync_source_no_tx

从库未成功确认的提交的次数

7)Rpl_semi_sync_source_status

主库当前是否处于半同步复制状态,如果已启用插件,并且已经发生了提交确认,则该值为ON,如果插件未启用,或者由于提交确认超时,主库退化为异步复制,则该值为OFF

8)Rpl_semi_sync_source_timefunc_failures

当调用时间函数(例如gettimeofday())时,主库失败的次数

9)Rpl_semi_sync_source_tx_avg_wait_time

主库等待每个事务的平均时间(以微秒为单位)

10)Rpl_semi_sync_source_tx_wait_time

主库等待事务的总时间(以微秒为单位)

11)Rpl_semi_sync_source_tx_waits

主库等待事务的总次数

12)Rpl_semi_sync_source_wait_pos_backtraverse

13)Rpl_semi_sync_source_wait_sessions

正在等待从库应答的会话数

14)Rpl_semi_sync_source_yes_tx

从库已成功确认提交的次数

4.2 查看从库的半同步复制状态

在从库执行show status 命令,即可看到半同步复制从库端相应的状态变量:

mysql> show status like 'rpl_semi%';

+------------------------------+-------+

| Variable_name | Value |

+------------------------------+-------+

| Rpl_semi_sync_replica_status | ON |

+------------------------------+-------+

1 row in set (0.00 sec)

变量说明:

1)Rpl_semi_sync_replica_status

显示当前从库是否运行半同步复制,如果插件已启用,并且复制I/O线程正在运行,则为ON,否则为OFF

以上就是关于半同步复制的介绍,希望可以让你对半同步复制有个更深入的认识。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5686605.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存