MySQL中半同步模式的实现示例

 更新时间:2024年09月09日 15:43:36   作者:妍妍的宝贝  
MySQL半同步复制是一种解决主从数据一致性问题的机制,本文就来介绍一下MySQL中半同步模式的实现示例,具有一定的参考价值,感兴趣的可以了解一下

1 半同步简介: 解决主从数据一致性问题

MySQL 半同步复制是一种机制,旨在解决主从数据的一致性问题。它的主要目标是在主服务器提交事务之前等待至少一个从服务器确认收到了该事务的二进制日志事件。这样可以确保主服务器上的事务在从服务器上至少有一个副本,从而提高数据可靠性。

在默认情况下,MySQL的复制是异步的,这意味着主服务器及其从服务器是独立的。异步复制可以提供最佳的性能,因为主服务器在将更新的数据写入它的二进制日志(Binlog)文件中后,无需等待验证更新数据是否已经复制到从服务器中,就可以自由处理其它进入的事务处理请求。但这也同时带来了很高的风险,如果在主服务器或从服务器端发生故障,会造成主从数据的不一致,甚至在恢复时造成数据丢失。

从MySQL5.5开始引入了一种半同步复制功能,该功能可以确保主服务器和访问链中至少一台从服务器之间的数据一致性和冗余。在这种配置结构中,一台主服务器和其许多从服务器都进行了配置,这样在复制拓扑中,至少有一台从服务器在父主服务器进行事务处理前,必须确认更新已经收到并写入了其中继日志 (Relay Log)。当出现超时,源主服务器必须暂时切换到异步复制模式重新复制,直到至少有一台设置为半同步复制模式的从服务器及时收到信息。 继5.5半同步复制后,MySQL5.6又对其进行了优化和改进,其中有两个地方较为重要:

1> 在主从切换后,在传统的方式里,需要找到binlog和POS点,然后更改master指向,而在mysql5.6里,你无须再知道binlog和POS点,你只需要知道master的IP、端口,账号密码即可,因为同步复制是自动的,mysql通过内部机制GTID自动找点同步。 ​

2> 多线程复制,以前的版本,同步复制是单线程的,只能一个一个执行,在MySQL5.6里,可以做到多个库之间的多线程复制,但一个库里的表,多线程复制是无效的。

1.用户线程写入完成后master中的dump会把日志推送到slave端

2.slave中的io线程接收后保存到relaylog中继日志

3.保存完成后slave向master端返回ack

4.在未接受到slave的ack时master端时不做提交的,一直处于等待当收到ack后提交到存储引擎

5.在5.6版本中用到的时after_commit模式,after_commit模式时先提交在等待ack返回后输出ok

2 实现半同步模式实践操作

2.1 MASTER

mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
    -> FROM INFORMATION_SCHEMA.PLUGINS
    -> WHERE PLUGIN_NAME LIKE '%semi%';
+----------------------+---------------+
| PLUGIN_NAME          | PLUGIN_STATUS |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE        |
+----------------------+---------------+
[root@mysql-01 ~]# vim /etc/my.cnf 

[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
log_bin=mysql-bin
server_id=10
gtid_mode=ON
enforce-gtid-consistency=ON
rpl_semi_sync_master_enabled=1    # 增加模块 master 端自启动 


[root@mysql-01 ~]# systemctl restart mysqld


# 查看模块是否安装成功
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
    -> FROM INFORMATION_SCHEMA.PLUGINS
    -> WHERE PLUGIN_NAME LIKE '%semi%';
+----------------------+---------------+
| PLUGIN_NAME          | PLUGIN_STATUS |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE        |
+----------------------+---------------+

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 |
+-------------------------------------------+------------+

mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0     |  -- (1) 表示当前有多少个从服务器客户端正在进行半同步复制。
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |  -- (2) 表示主服务器在等待从服务器确认时网络平均等待时间(毫秒)。这里的值为0,表示没有平均网络等待时间。
| Rpl_semi_sync_master_net_wait_time         | 0     |  -- (3) 表示主服务器在网络等待上的总时间(毫秒)。这里的值同样为0,表示没有总的网络等待时间。
| Rpl_semi_sync_master_net_waits             | 0     |  -- (4) 表示主服务器因网络原因等待的次数。这里的值为0,表示没有因网络原因导致的等待。
| Rpl_semi_sync_master_no_times              | 0     |  -- (5) 表示主服务器没有等待任何从服务器确认的次数。这里的值为0,表示所有事务都至少等待了一个从服务器的确认。
| Rpl_semi_sync_master_no_tx                 | 0     |  -- (6) 表示主服务器没有提交任何事务的次数。这里的值为0,表示所有事务都进行了半同步复制。
| Rpl_semi_sync_master_status                | ON    |  -- (7) 表示半同步复制当前是否启用。在这里,半同步复制是启用的。
| Rpl_semi_sync_master_timefunc_failures     | 0     |  -- (8) 表示由于时间函数失败而导致半同步复制失败的次数。这里的值为0,表示没有时间函数失败。
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |  -- (9) 表示主服务器在等待从服务器确认事务时的平均等待时间(毫秒)。这里的值为0,表示没有平均等待时间。
| Rpl_semi_sync_master_tx_wait_time          | 0     |  -- (10) 表示主服务器等待从服务器确认事务的总等待时间(毫秒)。这里的值为0,表示没有总的等待时间。
| Rpl_semi_sync_master_tx_waits              | 0     |  -- (11) 表示主服务器等待从服务器确认事务的次数。这里的值为0,表示没有等待时间。
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |  -- (12) 表示主服务器在等待从服务器确认时回溯binlog位置的次数。这里的值为0,表示没有回溯binlog位置。
| Rpl_semi_sync_master_wait_sessions         | 0     |  -- (13) 表示主服务器等待从服务器确认事务时涉及的会话数量。这里的值为0,表示没有等待会话。
| Rpl_semi_sync_master_yes_tx                | 0     |  -- (14) 表示主服务器成功提交事务并得到从服务器确认的次数。这里的值为0,表示没有事务成功提交并得到确认。
+--------------------------------------------+-------+

2.2 SLAVE 1

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

[root@mysql-02 ~]# vim /etc/my.cnf

[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server_id=20
gtid_mode=ON
enforce-gtid-consistency=ON
rpl_semi_sync_slave_enabled=1

[root@mysql-02 ~]# systemctl restart mysqld

[root@mysql-02 ~]# mysql -uroot -pOpenlab123!

mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+

mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';  # 查看模块是否加载
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+

2.3 SLAVE 2 

mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

[root@mysql-02 ~]# vim /etc/my.cnf

[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server_id=30
gtid_mode=ON
enforce-gtid-consistency=ON
rpl_semi_sync_slave_enabled=1

[root@mysql-02 ~]# systemctl restart mysqld

[root@mysql-02 ~]# mysql -uroot -pOpenlab123!

mysql> SHOW VARIABLES LIKE 'rpl_semi_sync%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+

mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';  # 查看模块是否加载
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |
+----------------------------+-------+

2.4 查看client链接状态 

再次回到MASTER

[root@mysql-01 ~]# systemctl restart mysqld


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     |
+--------------------------------------------+-------+

2.5 SLAVE 服务器故障模拟

2.5.1 停止 SLAVE 的 IO_THREAD 

# SLAVE 1
mysql> STOP SLAVE IO_THREAD;
mysql> SHOW SLAVE STATUS\G

# SLAVE 2 
mysql> STOP SLAVE IO_THREAD;
mysql> SHOW SLAVE STATUS\G

2.5.2 查看SLAVE 的IO线程是否关闭 

2.5.3 查看 MASTER 上 client 的连接状态

mysql> SHOW STATUS LIKE 'Rpl_semi%';

2.5.4 在MASTER端插入数据

mysql> insert into wawa values(7,'www.shuyan');
Query OK, 1 row affected (10.00 sec)

                                    # 会卡住十秒钟然后从同步转为异步,再插入数据
mysql> SELECT * FROM wawa;
+----+-----------------+
| id | name            |
+----+-----------------+
|  1 | wawa            |
|  2 | shuyan          |
|  3 | shuyan and wawa |
|  4 | shuyan--------  |
|  5 | shuyan.com      |
|  6 | 12333           |
|  7 | www.shuyan      |
+----+-----------------+

mysql> SHOW STATUS LIKE 'Rpl_semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 0     |
| 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              | 1     |
| Rpl_semi_sync_master_no_tx                 | 1     | # 一笔数据为同步
| Rpl_semi_sync_master_status                | OFF   | # 自动转为异步模式,等待slave恢复
| 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)

2.5.5 MASTER 还能写入数据的原因

为什么还能写入呢?是因为他在超过超时时间的时候,模式由同步模式转为异步模式

开启从服务器的 IO_THREAD 线程

# SLAVE 1
mysql> start slave io_thread;
# SLAVE 2
mysql> start slave io_thread;


# 在SLAVE上发现数据已经同步过来了
mysql> select * from shuyan.wawa;
+----+-----------------+
| id | name            |
+----+-----------------+
|  1 | wawa            |
|  2 | shuyan          |
|  3 | shuyan and wawa |
|  4 | shuyan--------  |
|  5 | shuyan.com      |
|  6 | 12333           |
|  7 | www.shuyan      |
+----+-----------------+

在从服务器开启半同步复制时,主服务器会在等待从服务器响应之前设置一个超时时间。如果超过这个时间还没有收到从服务器的响应,主服务器会自动转换为异步模式。当从服务器恢复连接时,它会自动接收到主服务器在此期间插入的所有数据。

当从服务器IO_THREAD 线程 恢复连接时,从服务器会按照 GTID 的顺序接收并应用来自主服务器的事务。

当从服务器的 I/O 线程恢复连接时,它会查找 gtid_executed 列表中缺失的 GTID,并从相应的二进制日志文件和位置开始复制。这样,从服务器会按照 GTID 的顺序接收并应用来自主服务器的事务,从而保证数据的一致性和完整性

MySQL 半同步复制可以通过 GTID(全局事务标识符)来比对数据。当从服务器恢复连接时,它会根据 GTID 查找主服务器上尚未应用的事务,并自动接收到这些事务。

到此这篇关于MySQL中半同步模式的实现示例的文章就介绍到这了,更多相关MySQL 半同步模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Shell下实现免密码快速登陆MySQL数据库的方法

    Shell下实现免密码快速登陆MySQL数据库的方法

    这篇文章主要给大家介绍了在Shell下实现免密码快速登陆MySQL数据库的方法,文中通过示例代码一步步介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编来一起看看吧。
    2017-06-06
  • mysql5.7.19 winx64安装配置方法图文教程(win10)

    mysql5.7.19 winx64安装配置方法图文教程(win10)

    这篇文章主要为大家详细介绍了mysql5.7.19 winx64安装配置教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • MySQL中一条SQL查询语句是如何执行的

    MySQL中一条SQL查询语句是如何执行的

    在写SQL查询语句的时候,通常要考虑SQL语句的查询效率,了解SQL查询语句的执行顺序,可以让我们写出更好的SQL语句,下面这篇文章主要给大家介绍了关于MySQL中一条SQL查询语句是如何执行的相关资料,需要的朋友可以参考下
    2022-04-04
  • Mysql中的索引精讲

    Mysql中的索引精讲

    这篇文章主要给大家介绍了关于Mysql中索引的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Mysql具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • Mysql占用过高CPU时的优化手段(必看)

    Mysql占用过高CPU时的优化手段(必看)

    下面小编就为大家带来一篇Mysql占用过高CPU时的优化手段(必看)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • Mysql时区的几种问题及解决方法

    Mysql时区的几种问题及解决方法

    在使用MySQL时,时区设置容易引发一些错误,本文将介绍MySQL时区问题可能引发的错误,并提供一些解决方案,具有一定的参考价值,感兴趣的可以了解一下
    2024-07-07
  • 一文带你了解Mysql主从同步原理

    一文带你了解Mysql主从同步原理

    本文主要讲解了Mysql主从同步原理,主从同步可以扩展数据库的负载能力、容错还可以数据备份等。想要了解相关内容的朋友可以阅读这篇文章
    2021-08-08
  • Mysql数据库5.7升级到8.4的实现

    Mysql数据库5.7升级到8.4的实现

    很多情况需要升级MySQL的数据库版本,本文主要介绍了Mysql数据库5.7升级到8.4的实现,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-06-06
  • MySQL的缓存策略方式

    MySQL的缓存策略方式

    MySQL缓存方案主要用于减轻数据库读写压力,通过使用Redis缓存用户定义的热点数据,用户可以直接从缓存中获取数据,文章还讨论了如何通过读写分离、连接池和异步连接等技术提升MySQL的访问性能,此外,还探讨了缓存方案中的一致性问题、读写策略以及缓存穿透
    2024-09-09
  • Linux下安装与使用MySQL详细介绍

    Linux下安装与使用MySQL详细介绍

    以下是对在Linux下安装与使用MySQL进行了详细的介绍,需要的朋友可以过来参考下
    2013-08-08

最新评论