1. 半同步的解释
1、逻辑上
是介于全同步复制与全异步复制之间的一种,主库只需要等待至少一个从库节点收到并且 Flush Binlog 到 Relay Log 文件即可,主库不需要等待所有从库给主库反馈。同时,这里只是一个收到的反馈,而不是已经完全完成并且提交的反馈,如此,节省了很多时间。
2、技术上
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。
所以说,半同步提高了数据完整性,至少存在两个地方。半同步失败,自动降级为异步,直到修复好
2. 半同步的实现
主节点的操作
主节点的操作,添加插件:
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
Query OK, 0 rows affected (0.11 sec)
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS #查看插件状态
-> FROM INFORMATION_SCHEMA.PLUGINS
-> WHERE PLUGIN_NAME LIKE '%semi%';
+----------------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE |
+----------------------+---------------+
1 row in set (0.00 sec)
mysql> SET GLOBAL rpl_semi_sync_master_enabled=1; ##激活插件
mysql> show VARIABLES LIKE 'rpl_semi_sync%';
+-------------------------------------------+------------+
| Variable_name | Value |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled | ON |##是否开启半同步
| rpl_semi_sync_master_timeout | 10000 |##切换复制的延迟时间为10s
| rpl_semi_sync_master_trace_level | 32 |##开启半同步复制模式的调试级别默认32
| rpl_semi_sync_master_wait_for_slave_count | 1 |##至少有1个slave接收到日志
| rpl_semi_sync_master_wait_no_slave | ON |##是否允许master的每个事物提交后都等待slave的回复信号
| rpl_semi_sync_master_wait_point | AFTER_SYNC |#等待的point
+-------------------------------------------+------------+
6 rows in set (0.02 sec)
mysql> show status like '%rpl%';
+--------------------------------------------+-------+
| 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)
从节点的操作
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; ##安装插件
Query OK, 0 rows affected (0.06 sec)
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
-> FROM INFORMATION_SCHEMA.PLUGINS
-> WHERE PLUGIN_NAME LIKE '%semi%';
+---------------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+---------------------+---------------+
| rpl_semi_sync_slave | ACTIVE |
+---------------------+---------------+
1 row in set (0.01 sec)
mysql> SET GLOBAL rpl_semi_sync_slave_enabled=1; #激活插件
mysql> stop SLAVE IO_THREAD; #关了再开
Query OK, 0 rows affected (0.03 sec)
mysql> start SLAVE IO_THREAD;
Query OK, 0 rows affected (0.01 sec)
mysql> show variables like '%rpl%';
+---------------------------------+----------+
| Variable_name | Value |
+---------------------------------+----------+
| rpl_semi_sync_slave_enabled | ON | ##开启
| rpl_semi_sync_slave_trace_level | 32 |
| rpl_stop_slave_timeout | 31536000 |
+---------------------------------+----------+
3 rows in set (0.01 sec)
半同步配置完成,此时,主节点会默认等待从节点十秒,若十秒之内没有反应,降级为异步
现在进行测试:
在server2上:
mysql> STOP SLAVE IO_THREAD;
Query OK, 0 rows affected (0.33 sec)
在server1上:
mysql> use westos;
mysql> insert into usertb values('user4','123');
会等待10秒
mysql> insert into usertb values('user5','123');
不会等待了 为异步复制了
mysql> show status like '%rpl%';
+--------------------------------------------+-------+
| 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 | 2 |
| Rpl_semi_sync_master_status | OFF |
| 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)
此时在server2上,打开IO线程,数据同步过来了:
mysql> start SLAVE IO_THREAD;
mysql> show processlist;
+----+-------------+-----------+-------+---------+------+--------------------------------------------------------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+-------------+-----------+-------+---------+------+--------------------------------------------------------+------------------+
| 4 | root | localhost | mysql | Query | 0 | starting | show processlist |
| 6 | system user | | NULL | Connect | 48 | Slave has read all relay log; waiting for more updates | NULL |
| 8 | system user | | NULL | Connect | 20 | Waiting for master to send event | NULL |
+----+-------------+-----------+-------+---------+------+--------------------------------------------------------+------------------+
3 rows in set (0.00 sec)
mysql> use westos;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from usertb;
+----------+----------+
| username | password |
+----------+----------+
| user1 | 123 |
| user2 | 123 |
| user3 | 123 |
| user4 | 123 |
| user5 | 123 |
+----------+----------+
5 rows in set (0.00 sec)
参数的含义
id列:一个标识
user列: 显示当前用户,如果不是root,这个命令就只显示你权限范围内的sql语句
host列:显示这个语句是从哪个ip 的哪个端口上发出的。可用来追踪出问题语句的用户
db列:显示这个进程目前连接的是哪个数据库
command列:显示当前连接的执行的命令,一般就是休眠(sleep),查询(query),连接(connect)
time列:此这个状态持续的时间,单位是秒
state列:显示使用当前连接的sql语句的状态