爲什麼需要半同步複製
默認情況下,MySQL的複製功能是異步的,異步複製可以提供最佳的性能,主庫把Binlog日誌發送給從
庫即結束,並不驗證從庫是否接收完畢。這意味着當主服務器或從服務器端發生故障時,有可能從服務
器沒有接收到主服務器發送過來的binlog日誌,這就會造成主服務器和從服務器的數據不一致,甚至在
恢復時造成數據的丟失
什麼是半同步複製
在一主多從的環境下,如果一個從收到了來自主服務器的同步信息,那麼立即返回給主,表示已同步完成;不需要等所有從都同步才返回信息,繼而保障了主機異常宕機時,數據不會丟失,可提升爲已完成備份的從服務器提升爲主,保障服務的持續集成。如果主存活,slave全部宕機,主服務器寫入數據後等待time超時時間過期後,就會返回成功信息,不同繼續等待slave,如果slave再次上線,繼而同步成功。
官方文檔: https://mariadb.com/kb/en/library/semisynchronous-replication/
實驗環境
OS | IP | Dabase | Type |
---|---|---|---|
centos7.6 | 192.168.146.97 | MariaDB5.5.6 | Master |
centos7.6 | 192.168.146.97 | MariaDB5.5.6 | Slave1 |
centos7.6 | 192.168.146.97 | MariaDB5.5.6 | Slave2 |
配置YUM倉庫: 本示例採用阿里yum源
[root@97 /etc/yum.repos.d]#curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
[root@97 /etc/yum.repos.d]#yum install mariadb-server -y
Master1配置
[root@97 /etc/yum.repos.d]#cat /etc/my.cnf.d/server.cnf
[mysqld]
server-id=97 #服務器ID
log-bin=myqsl-bin #二進制日誌
log-error #錯誤日誌
啓動服務,並配置mariadbserver
[root@97 ~]# systemctl start mariadb
[root@97 ~]# mysql
先搭建三臺機器的主從配置,後續接入半同步配置
Master
MariaDB [(none)]> grant replication slave on *.* to 'repluser'@'192.168.146.%' identified by 'replpasswd'; 創建可複製的用戶
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> show master logs; #查看當前bin-log日誌位置
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 30322 |
| mysql-bin.000002 | 1038814 |
| mysql-bin.000003 | 407 |
+------------------+-----------+
3 rows in set (0.00 sec)
slave1配置
[root@107 ~]#cat /etc/my.cnf
[mysqld]
server-id=107
log-error
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
[root@107 ~]#systemctl start mariadb
[root@107 ~]#mysql
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='192.168.146.97', MASTER_USER='repluser', MASTER_PASSWORD='replpasswd', MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=407;
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.146.97
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 407
Relay_Log_File: mariadb-relay-bin.000002
Relay_Log_Pos: 529
Relay_Master_Log_File: mysql-bin.000003
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: 407
Relay_Log_Space: 825
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: 97
1 row in set (0.00 sec)
測試
Master創建db1測試
MariaDB [(none)]> create database db1;
Query OK, 1 row affected (0.00 sec)
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
slave查看
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 | #至此主從已完成
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.01 sec)
半同步設置
Master
MariaDB [(none)]> INSTALL SONAME 'semisync_master'; #安裝master插件,無須重啓
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SET GLOBAL rpl_semi_sync_master_enabled=ON; #開啓master_sync
Query OK, 0 rows affected (0.001 sec)
MariaDB [(none)]> SET GLOBAL rpl_semi_sync_master_timeout = 1000; #設置超時時長爲1s
Query OK, 0 rows affected (0.000 sec)
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE '%semi%'; #查看相關全局變量
+---------------------------------------+--------------+
| Variable_name | Value |
+---------------------------------------+--------------+
| rpl_semi_sync_master_enabled | ON |
| rpl_semi_sync_master_timeout | 1000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_COMMIT |
| rpl_semi_sync_slave_delay_master | OFF |
| rpl_semi_sync_slave_enabled | OFF |
| rpl_semi_sync_slave_kill_conn_timeout | 5 |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------------+--------------+
9 rows in set (0.001 sec)
MariaDB [(none)]> SHOW GLOBAL STATUS LIKE '%semi%'; #查看當前狀態信息
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 0 | #此時雖然master插件已就緒,還沒有slave就緒
| Rpl_semi_sync_master_get_ack | 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 | 0 |
| Rpl_semi_sync_master_no_tx | 0 |
| Rpl_semi_sync_master_request_ack | 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 |
| Rpl_semi_sync_slave_send_ack | 0 |
| Rpl_semi_sync_slave_status | OFF |
+--------------------------------------------+-------+
18 rows in set (0.001 sec)
slave1.2設置
MariaDB [(none)]> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; #安裝從插件
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> SET GLOBAL rpl_semi_sync_slave_enabled=1; #啓動從插件
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE '%semi%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | ON |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+
2 rows in set (0.00 sec)
MariaDB [(none)]> SHOW GLOBAL STATUS LIKE '%semi%'; #此時發現slave是關閉的
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | OFF |
+----------------------------+-------+
1 row in set (0.01 sec)
MariaDB [(none)]> STOP SLAVE IO_THREAD; #重啓線程
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> START SLAVE IO_THREAD;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SHOW GLOBAL STATUS LIKE '%semi%'; #插件開啓
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+----------------------------+-------+
1 row in set (0.00 sec)
master上查看slave插件線程是否啓動且同步到了master
MariaDB [(none)]> SHOW GLOBAL STATUS LIKE '%semi%';
+--------------------------------------------+-------+
| 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 |
+--------------------------------------------+-------+
14 rows in set (0.00 sec)
測試半同步
#在master實現,創建數據庫,立即成功
MariaDB [(none)]> create database db2;
Query OK, 1 row affected (1.00 sec)
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| db2 |
| mysql |
| performance_schema |
| test |
+--------------------+
6 rows in set (0.00 sec)
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| db2 |
| mysql |
| performance_schema |
| test |
+--------------------+
7 rows in set (0.00 sec)
#在所有slave節點實現,停止複製線程
MariaDB [(none)]> stop slave;
Query OK, 0 rows affected (0.011 sec)
#在master實現,創建數據庫,等待3s才能成功
MariaDB [(none)]> create database db3
Query OK, 1 row affected (1.00 sec)
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| db2 |
| db3 |
| mysql |
| performance_schema |
| test |
+--------------------+
6 rows in set (0.00 sec)
此時slave上沒有同步信息,因爲線程已關閉
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| db2 |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
#在任意一個slave節點實現,恢復複製線程
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.006 sec)
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| db1 |
| db2 |
| db3 | #數據馬上同步成功
| mysql |
| performance_schema |
| test |
+--------------------+
6 rows in set (0.00 sec)