一、半同步简介master节点在执行完客户端提交的事务后不是立刻返回结果给客户端,而是等待至少一个slave节点接收并写到relay log中才返回给客户端。
半同步相对于异步复制而言,提高了数据的安全性,同时也造成了一定程度的延迟,这个延迟最少是一个tcp往返的时间。所以,半同步复制最好在低延时的网络中使用。
mysql从5.5开始就支持半同步复制,在5.7.2版本的时候对半同步复制进行了一次改进;原先的半同步策略为 after_commit 改进后的策略为 after_sync 两者的差异在于slave节点ack应答master的时机不同。
二、两种模式介绍after_commit 模式介绍
master将每个事务写入到二进制日志并刷盘保存,同时将事务发送给slave,然后将事务提交给存储引擎处理并进行提交,然后等待slave返回确认信息,在收到确认信息后,master将结果返回给客户端,然后当前客户端可以继续工作。
after_sync 模式介绍
master将每个事务写入到二进制日志并刷盘保存,同时将事务发送给slave,然后等待slave返回确认信息,收到确认信息后,将事务提交给存储引擎处理并进行提交,并将结果返回给客户端,然后当前客户端可以继续工作。
三、两种方式比较对于第一种 after_commit 方式,当前客户端只有在服务器向存储引擎提交数据并收到slave返回的确认后,才会收到事务的返回结果。在事务提交之后收到slave返回确认信息之前,此刻其他客户端可以看到当前客户端提交的事务信息。
如果slave节点由于网络等原因并未收到master节点传递过来的事务,而master节点此刻crash了。ha进行故障转移,客户端都连到slave节点上,这时先前在master节点看到的事务在slave节点并未看到,就会发生事务丢失的情况。
对于第二种 after_sync 方式,当事务被slave确认后master在存储引擎层面进行提交事务后,所有客户端才能看到事务造成的数据更改。因此,所有客户端在master上同一时刻看到是相同的数据。
当master节点crash的情况下,所有在master上提交的事务都被复制到slave(保存到中继日志中)。 master服务器意外crash。此刻ha进行故障转移到salve后,客户端看到的数据是无损的,因为slave是最新的。
注意,然而,在这种情况下,master不能直接恢复使用,因为它的二进制日志可能包含未提交的事务,此刻当二进制日志恢复并用于业务需求时,可能会导致与slave的冲突。
四、如何开启半同步方式1:半同步以插件的形式存在,咱们可以直接在线开启即可(本次采用这次方式)
主节点开启:
[root@greatsql][(none)]>install plugin rpl_semi_sync_master soname 'semisync_master.so';query ok, 0 rows affected (0.02 sec)
从节点开启:
[root@greatsql][(none)]>install plugin rpl_semi_sync_slave soname 'semisync_slave.so';query ok, 0 rows affected (0.02 sec)
ps:一般情况下所有节点都同步部署master和slave插件,这样故障切换的时候会比较方便处理
方式2:在my.cnf配置中进行开启
主从节点都同步配置开启:
plugin-load="rpl_semi_sync_master=semisync_master.so;rpl_sync_slave=semisync_slave.so"rpl_semi_sync_master_enabled=1rpl_semi_sync_slave_enabled=1
五、查看插件开启情况方式1:查询plugin
主节点查看:
[root@greatsql][test]>show plugins;| rpl_semi_sync_master | active | replication | semisync_master.so | gpl |
从节点查看:
[root@greatsql][(none)]>show plugins;| rpl_semi_sync_slave | active | replication | semisync_slave.so | gpl |
方式二:查询information_schema.plugins信息更全面
主节点信息:
(thu feb 17 03:03:12 2022)[root@greatsql][(none)]>select * from information_schema.plugins where plugin_name like "%semi%"\g;*************************** 1. row *************************** plugin_name: rpl_semi_sync_master plugin_version: 1.0 plugin_status: active plugin_type: replication plugin_type_version: 4.0 plugin_library: semisync_master.soplugin_library_version: 1.10 plugin_author: oracle corporation plugin_description: semi-synchronous replication master plugin_license: gpl load_option: on1 row in set (0.00 sec)error:no query specified# 从节点信息(thu feb 17 16:05:19 2022)[root@greatsql][(none)]>select * from information_schema.plugins where plugin_name like "%semi%"\g;*************************** 1. row *************************** plugin_name: rpl_semi_sync_slave plugin_version: 1.0 plugin_status: active plugin_type: replication plugin_type_version: 4.0 plugin_library: semisync_slave.soplugin_library_version: 1.10 plugin_author: oracle corporation plugin_description: semi-synchronous replication slave plugin_license: gpl load_option: on1 row in set (0.00 sec
六、开启半同步功能因为上面是在线安装插件的,所以插件安装完成后,服务还要启动一下
主节点启用半同步复制:
[root@greatsql][test]>set global rpl_semi_sync_master_enabled = on;query ok, 0 rows affected (0.00 sec)
从节点启用半同步复制:
t@greatsql][(none)]>set global rpl_semi_sync_slave_enabled = on;query ok, 0 rows affected (0.00 sec)
以上设置完成后,从节点重启io线程
(mon feb 14 15:19:58 2022)[root@greatsql][(none)]>(mon feb 14 15:19:58 2022)[root@greatsql][(none)]>stop slave io_thread;query ok, 0 rows affected, 1 warning (0.01 sec)(mon feb 14 15:21:41 2022)[root@greatsql][(none)]>start slave io_thread;query ok, 0 rows affected, 1 warning (0.01 sec)
七、查看半同步是否运行 主节点:
[root@greatsql][test]>show status like 'rpl_semi_sync_master_status';+-----------------------------+-------+| variable_name | value |+-----------------------------+-------+| rpl_semi_sync_master_status | on |+-----------------------------+-------+1 row in set (0.00 sec)
从节点:
[root@greatsql][(none)]>show status like 'rpl_semi_sync_slave_status';+----------------------------+-------+| variable_name | value |+----------------------------+-------+| rpl_semi_sync_slave_status | on |+----------------------------+-------+1 row in set (0.01 sec)
查看主节点error.log,可以看出来从节点已经启用半同步复制了
# 关键信息 start semi-sync binlog_dump to slave (server_id: 3306)2022-02-14t02:16:35.411061-05:00 13 [note] [my-010014] [repl] while initializing dump thread for slave with uuid <652ade08-8b1c-11ec-9f62-00155dcff90a>, found a zombie dump thread with the same uuid. master is killing the zombie dump thread(12).2022-02-14t02:16:35.411236-05:00 13 [note] [my-010462] [repl] start binlog_dump to master_thread_id(13) slave_server(3306), pos(, 4)2022-02-14t02:16:35.411263-05:00 13 [note] [my-011170] [repl] start asynchronous binlog_dump to slave (server_id: 3306), pos(, 4).2022-02-14t02:16:35.411419-05:00 12 [note] [my-011171] [repl] stop asynchronous binlog_dump to slave (server_id: 3306).2022-02-14t02:19:33.913084-05:00 9 [note] [my-011130] [repl] semi-sync replication initialized for transactions.2022-02-14t02:19:33.913133-05:00 9 [note] [my-011142] [repl] semi-sync replication enabled on the master.2022-02-14t02:19:33.913638-05:00 0 [note] [my-011166] [repl] starting ack receiver thread.2022-02-14t02:21:46.899725-05:00 14 [note] [my-010014] [repl] while initializing dump thread for slave with uuid <652ade08-8b1c-11ec-9f62-00155dcff90a>, found a zombie dump thread with the same uuid. master is killing the zombie dump thread(13).2022-02-14t02:21:46.899894-05:00 14 [note] [my-010462] [repl] start binlog_dump to master_thread_id(14) slave_server(3306), pos(, 4)2022-02-14t02:21:46.899953-05:00 14 [note] [my-011170] [repl] start semi-sync binlog_dump to slave (server_id: 3306), pos(, 4).
以上,mysql半同步复制搭建完毕!
八、半同步参数信息主节点参数信息:
[root@greatsql][test]>show variables like '%rpl%';+-------------------------------------------+------------+| variable_name | value |+-------------------------------------------+------------+| rpl_read_size | 8192 || 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_stop_slave_timeout | 31536000 |+-------------------------------------------+------------+8 rows in set (0.00 sec)
部分参数简单说明:
从节点参数信息:
[root@greatsql][test]>show variables like '%rpl%';+---------------------------------+----------+| variable_name | value |+---------------------------------+----------+| rpl_read_size | 8192 || rpl_semi_sync_slave_enabled | on || rpl_semi_sync_slave_trace_level | 32 || rpl_stop_slave_timeout | 31536000 |+---------------------------------+----------+4 rows in set (0.00 sec)
部分参数简单说明:
九、半同步状态信息主节点查看:
[root@greatsql][test]> show status like '%rpl_semi%';+--------------------------------------------+-------+| variable_name | value |+--------------------------------------------+-------+| rpl_semi_sync_master_clients | 1 || 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 |+--------------------------------------------+-------+14 rows in set (0.00 sec)
部分参数用途简要说明:
从节点转态信息:
show global status like '%semi%';+----------------------------+-------+| variable_name | value |+----------------------------+-------+| rpl_semi_sync_slave_status | on |+----------------------------+-------+1 row in set (0.00 sec)
参数简单说明:
十、测试一下半同步的同步情况半同步是否会降级为异步复制?是会的。
当半同步复制发生超时时(由rpl_semi_sync_master_timeout参数控制,单位是毫秒,默认为10000,即10s),会暂时关闭半同步复制,转而使用异步复制。
当master dump 线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为半同步复制。
1.从节点暂时先关掉io线程[root@greatsql][(none)]>stop slave io_thread;query ok, 0 rows affected, 1 warning (0.02 sec)
2.主节点写入几条测试数据[root@greatsql][test]>insert into ptype values(4,'4','4'),(5,'5','5'),(6,'6','6');query ok, 3 rows affected (0.02 sec)
3.等待10s后查看复制状态,半同步已经关掉了[root@greatsql][test]>show status like 'rpl_semi_sync_slave_status';+----------------------------+-------+| variable_name | value |+----------------------------+-------+| rpl_semi_sync_slave_status | off |+----------------------------+-------+1 row in set (0.00 sec)
4.从节点开启io线程[root@greatsql][(none)]>start slave io_thread;query ok, 0 rows affected, 1 warning (0.02 sec)
5.再次查看复制状态,半同步复制自动开启了t@greatsql][test]>show status like 'rpl_semi_sync_slave_status';+----------------------------+-------+| variable_name | value |+----------------------------+-------+| rpl_semi_sync_slave_status | on |+----------------------------+-------+1 row in set (0.00 sec)
以上就是mysql中如何实现半同步semi-sync replication的详细内容。