MySQL Semi-Synchronous Replication. See the Magic. Try the Magic.
缺点:性能\效率(Performance);每个事务可能会花费一定的时间直至所有的slave服务器向master确认该事务已被复制并完成。
SemiSync可以通过mysql server5.5实现。
实验演示
Preparing the environment
Loading SemiSync Replication plugin
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
On the slave,以拥有'super'权限的用户执行:
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
分别检查一下加载后的情况:
mysql> SHOW plugins;
Setting Asynchronous Replication
搭建一个Async Replication环境,这是第一步,SemiSync replication是在Async Replication基础之上实现的。
On the master:
编辑/etc/my.cnf
log-bin=mysql-bin
server-id=1
重启mysql
Shutting down MySQL.. [ OK ]
Starting MySQL.. [ OK ]
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
mysql> FLUSH PRIVILEGES;
编辑/etc/my.cnf
server-id=2
Restart the server as root
Shutting down MySQL.. [ OK ]
Starting MySQL.. [ OK ]
在master,确保master可以进行 Async replication
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 524 | | |
+------------------+----------+--------------+------------------+
MASTER_HOST='192.168.0.136',
MASTER_USER='repl',
MASTER_PASSWORD='slave',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_CONNECT_RETRY=10;
Query OK, 0 rows affected (0.01 sec)
mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW slave STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting FOR master TO send event
Master_Host: 192.168.0.136
Master_User: repl
Master_Port: 3306
Connect_Retry: 10
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 1264
Relay_Log_File: slave-relay-bin.000003
Relay_Log_Pos: 253
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1264
Relay_Log_Space: 1295
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
1 row IN SET (0.00 sec)
On the slave:
mysql> SHOW TABLES;
Empty SET (0.00 sec)
On the Master:
mysql> SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+
| test1 |
+----------------+
On the slave:
+----------------+
| Tables_in_test |
+----------------+
| test1 |
+----------------+
On the master:
mysql> SELECT * FROM test1;
+------+--------+
| id | name |
+------+--------+
| 1 | Test 1 |
+------+--------+
On the slave:
+------+--------+
| id | name |
+------+--------+
| 1 | Test 1 |
+------+--------+
现在我们在master上插入新记录并检查slave
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO test1 VALUES (3,'Test 3');
Query OK, 1 row affected (0.03 sec)
mysql> SELECT * FROM test1;
+------+--------+
| id | name |
+------+--------+
| 1 | Test 1 |
| 2 | Test 2 |
| 3 | Test 3 |
+------+--------+
On the slave:
+------+--------+
| id | name |
+------+--------+
| 1 | Test 1 |
+------+--------+
现在修改iptables,去除阻止规则:
# iptables -D INPUT -s 192.168.0.136 -j DROPOn the slave:
重启slave服务
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> SELECT * FROM test1;
+------+--------+
| id | name |
+------+--------+
| 1 | Test 1 |
| 2 | Test 2 |
| 3 | Test 3 |
+------+--------+
Moving into Semi-Synchronous Replication
我们之前已经加载过其插件,在这步要对其进行设置,我们可以进行动态加载也可以写入my.cnf。
On the master:
Query OK, 0 rows affected (0.00 sec)
mysql> SET GLOBAL rpl_semi_sync_master_timeout = 10000;
Query OK, 0 rows affected (0.00 sec)
On the slave:
Query OK, 0 rows affected (0.00 sec)
mysql> STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;
Query OK, 0 rows affected (0.02 sec)
Query OK, 0 rows affected (0.00 sec)
On the master:
+------------------------------------+-------+
| 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_no_slave | ON |
+------------------------------------+-------+
4 rows IN SET (0.00 sec)
mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
+--------------------------------------------+-------+
| 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)
On the slave:
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
2 rows IN SET (0.00 sec)
mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+----------------------------+-------+
1 row IN SET (0.00 sec)
接下来实验"Semi",我们会分别在m/s连接通畅的情况下与阻止网络连接的情况下,插入新记录,看看会发生什么:
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM test1;
+------+--------+
| id | name |
+------+--------+
| 1 | Test 1 |
| 2 | Test 2 |
| 3 | Test 3 |
| 4 | Test 4 |
+------+--------+
4 rows IN SET (0.00 sec)
mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 1 |
| Rpl_semi_sync_master_net_avg_wait_time | 602 |
| Rpl_semi_sync_master_net_wait_time | 602 |
| Rpl_semi_sync_master_net_waits | 1 |
| 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 | 1 |
+--------------------------------------------+-------+
14 rows IN SET (0.00 sec)
注意Rpl_semi_sync_master_yes_tx 现在是1
On the slave:
+------+--------+
| id | name |
+------+--------+
| 1 | Test 1 |
| 2 | Test 2 |
| 3 | Test 3 |
| 4 | Test 4 |
+------+--------+
4 rows IN SET (0.00 sec)
现在我们开始阻断网络连接
On the slave:
# iptables -A INPUT -s 192.168.0.136 -j DROP
On the master:
Query OK, 1 row affected (10.00 sec)
mysql> SELECT * FROM test1;
+------+--------+
| id | name |
+------+--------+
| 1 | Test 1 |
| 2 | Test 2 |
| 3 | Test 3 |
| 4 | Test 4 |
| 5 | Test 5 |
+------+--------+
5 rows IN SET (0.00 sec)
mysql> SHOW STATUS LIKE 'Rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 1 |
| Rpl_semi_sync_master_net_avg_wait_time | 602 |
| Rpl_semi_sync_master_net_wait_time | 602 |
| Rpl_semi_sync_master_net_waits | 1 |
| Rpl_semi_sync_master_no_times | 1 |
| Rpl_semi_sync_master_no_tx | 1 |
| 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 | 1 |
+--------------------------------------------+-------+
14 rows IN SET (0.00 sec)
On the slave :
# iptables -D INPUT -s 192.168.0.136 -j DROP
+------+--------+
| id | name |
+------+--------+
| 1 | Test 1 |
| 2 | Test 2 |
| 3 | Test 3 |
| 4 | Test 4 |
+------+--------+
4 rows IN SET (0.00 sec)
mysql> STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;
Query OK, 0 rows affected (0.02 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM test1;
+------+--------+
| id | name |
+------+--------+
| 1 | Test 1 |
| 2 | Test 2 |
| 3 | Test 3 |
| 4 | Test 4 |
| 5 | Test 5 |
+------+--------+
5 rows IN SET (0.00 sec)
On the master:
+--------------------------------------------+----------+
| Variable_name | Value |
+--------------------------------------------+----------+
| Rpl_semi_sync_master_clients | 1 |
| Rpl_semi_sync_master_net_avg_wait_time | 28584321 |
| Rpl_semi_sync_master_net_wait_time | 57168643 |
| Rpl_semi_sync_master_net_waits | 2 |
| Rpl_semi_sync_master_no_times | 1 |
| Rpl_semi_sync_master_no_tx | 1 |
| 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 | 1 |
+--------------------------------------------+----------+
14 rows IN SET (0.00 sec)
mysql> INSERT INTO test1 VALUES (6,'Test 6');
Query OK, 1 row affected (0.01 sec)
原文: