1. 程式人生 > 其它 >MYSQL主從複製(非同步與半同步複製)

MYSQL主從複製(非同步與半同步複製)

技術標籤:運維

主從複製

原理:將主伺服器的binlog日誌複製到從伺服器上執行一遍,達到主從資料的一致狀態。**

過程:從庫開啟一個I/O執行緒,向主庫請求Binlog日誌。主節點開啟一個binlog dump執行緒,檢查自己的二進位制日誌,併發送給從節點;從庫將接收到的資料儲存到中繼日誌(Relay log)中,另外開啟一個SQL執行緒,把Relay中的操作在自身機器上執行一遍

優點:作為備用資料庫,並且不影響業務可做讀寫分離,一般是一個寫庫,一個或多個讀庫,分佈在不同的伺服器上,充分發揮伺服器和資料庫的效能,但要保證資料的一致性

MySQL複製支援多種不同的複製策略,包括同步、半同步、非同步和延遲策略等。

同步策略:Master要等待所有Slave應答之後才會提交(MySql對DB操作的提交通常是先對操作事件進行二進位制日誌檔案寫入然後再進行提交)。
半同步策略:Master等待至少一個Slave應答就可以提交。
非同步策略:Master不需要等待Slave應答就可以提交。
延遲策略:Slave要至少落後Master指定的時間。

非同步複製

MySQL預設的複製即是非同步的,主庫在執行完客戶端提交的事務後會立即將結果返給給客戶端,並不關心從庫是否已經接收並處理,這樣就會有一個問題,主如果crash掉了,此時主上已經提交的事務可能並沒有傳到從庫上,如果此時,強行將從提升為主,可能導致新主上的資料不完整。

主庫將事務 Binlog 事件寫入到 Binlog 檔案中,此時主庫只會通知一下 Dump 執行緒傳送這些新的 Binlog,然後主庫就會繼續處理提交操作,而此時不會保證這些 Binlog 傳到任何一個從庫節點上。

非同步複製—基於二進位制日誌檔案的主從複製
注:server1和server2上均裝有mysql,且均完成了安全初始化
在server1上:(master)
server1(172.25.20.1)為主資料庫,
server2(172.25.20.3)為從資料庫

vim /etc/my.cnf
/etc/init.d/mysqld restart
##寫入server-id=1(伺服器ID) log-bin=mysql-bin(開啟二進位制日誌)
##進入mysql mysql -p mysql>create user 'repl'@'172.25.20.%' identified by 'westos';##建立複製使用者 mysql>grant replication slave on *.* to 'repl'@'172.25.20.%';##授予使用者許可權 mysql> flush privileges;

server2上:(slave)

mysql -h 172.25.20.1 -u repl -pwestos
##檢測複製使用者是否建立成功

vim /etc/my.cnf
##寫入server-id=2

systemctl restart mariadb

在server1上:

mysql -p
mysql> show master status;##檢視master狀態

在server2上:

配置slave:

mysql -p
mysql> change master to   
 -> master_host='172.25.20.1',    
 -> master_user='repl',    
 -> master_password='westos',    
 -> master_log_file='mysql-bin.000001',    
 -> master_log_pos=1200;
mysql> start slave;
mysql> show slave status\G;           
#Slave_IO_Running: Yes            
#Slave_SQL_Running: Yes
#顯示如上說明主從複製成功  

注意:上面的master_log_file和master_log_pos的引數根據master 的狀態填寫
測試:
在server1中建立一個庫或表,在server2中也可以顯示看到,則證明主從複製成功。
非同步複製—基於全域性事務標識(GTID)的主從複製
注:兩個伺服器已經使用MySQL的基於二進位制日誌位置的複製協議作為主伺服器和從伺服器執行
在server1(主節點中)
配置主節點:啟用複製主節點,開啟gtid服務

vim /etc/my.cnf
log-bin=mysql-bin ##基於二進位制日誌位置的主從複製
server-id=1
gtid_mode=ON ##開啟gtid
enforce-gtid-consistency=OK
/etc/init.d/mysqld restart

在server2(從節點中)
配置從站slave開啟GTID的服務

vim /etc/my.cnf

server-id=2   ##基於二進位制日誌位置的主從複製
gtid_mode=ON  ##開啟gtid
enforce-gtid-consistency=ON

systemctl restart mariadb

配置從站slave使用基於GTID的自動定位。

mysql> stop slave; ##停止基於二進位制位置的複製

mysql> CHANGE MASTER TO
    -> MASTER_HOST = '172.25.20.1',
    -> MASTER_USER = 'repl',
    -> MASTER_PASSWORD = 'westos',
    -> MASTER_AUTO_POSITION = 1;

mysql> START SLAVE; ##開啟gtid的主從複製
mysql> SHOW SLAVE STATUS\G ##檢視複製狀態

測試:
在主節點server1中插入資料,在從節點server2中檢視。

半同步複製

半同步複製是介於全同步複製與全非同步複製之間的一種,主庫只需要等待至少一個從庫節點收到並且 Flush Binlog 到 Relay Log 檔案即可,主庫不需要等待所有從庫給主庫反饋。同時,這裡只是一個收到的反饋,而不是已經完全完成並且提交的反饋,如此,節省了很多時間。

介於非同步複製和全同步複製之間,主庫在執行完客戶端提交的事務後不是立刻返回給客戶端,而是等待至少一個從庫接收到並寫到relay log中才返回給客戶端。相對於非同步複製,半同步複製提高了資料的安全性,同時它也造成了一定程度的延遲,這個延遲最少是一個TCP/IP往返的時間。所以,半同步複製最好在低延時的網路中使用。

半同步複製為非同步複製協議添加了一個同步步驟。這意味著主庫在提交時等待至少一個從庫確認它已收到該事務,才會繼續提交操作。

對角箭頭表示伺服器之間交換的訊息或伺服器與客戶端應用程式之間交換的訊息。

在server1中:
主庫安裝服務外掛,並且開啟半同步複製:

mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (0.01 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=ON;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%semi%';    #環境變數
mysql> show status like '%rpl_semi_sync%';	#狀態變數

在server2中:
在從端也安裝外掛,開啟半同步複製:

mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (0.00 sec)

mysql> set global rpl_semi_sync_slave_enabled=ON;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%semi%'; 

注意: 要重啟從上的IO執行緒,如果沒有重啟,則預設還是非同步複製,重啟後,slave會在master上註冊為半同步複製的slave角色。

mysql> stop slave io_thread;
Query OK, 0 rows affected (0.00 sec)

mysql> start slave io_thread;
Query OK, 0 rows affected (0.00 sec)

mysql> show status like '%rpl%';
mysql> show variables like '%rpl%';

測試:半同步測試正常同步情況:

從端開啟IO:

mysql> start slave io_thread;
Query OK, 0 rows affected (0.00 sec)

主端插入新資料:
mysql> insert into userlist values ('user333','333');
Query OK, 1 row affected (0.01 sec)

mysql> select * from user_tb;

mysql> show status like '%rpl%'; 
#Rpl_semi_sync_master_yes_tx 變為1,成功一次

從端驗證同步結果:
mysql> select * from user_tb;

原理:將主伺服器的binlog日誌複製到從伺服器上執行一遍,達到主從資料的一致狀態。**

過程:從庫開啟一個I/O執行緒,向主庫請求Binlog日誌。主節點開啟一個binlog dump執行緒,檢查自己的二進位制日誌,併發送給從節點;從庫將接收到的資料儲存到中繼日誌(Relay log)中,另外開啟一個SQL執行緒,把Relay中的操作在自身機器上執行一遍

優點:作為備用資料庫,並且不影響業務可做讀寫分離,一般是一個寫庫,一個或多個讀庫,分佈在不同的伺服器上,充分發揮伺服器和資料庫的效能,但要保證資料的一致性

MySQL複製支援多種不同的複製策略,包括同步、半同步、非同步和延遲策略等。

同步策略:Master要等待所有Slave應答之後才會提交(MySql對DB操作的提交通常是先對操作事件進行二進位制日誌檔案寫入然後再進行提交)。
半同步策略:Master等待至少一個Slave應答就可以提交。
非同步策略:Master不需要等待Slave應答就可以提交。
延遲策略:Slave要至少落後Master指定的時間。

非同步複製
MySQL預設的複製即是非同步的,主庫在執行完客戶端提交的事務後會立即將結果返給給客戶端,並不關心從庫是否已經接收並處理,這樣就會有一個問題,主如果crash掉了,此時主上已經提交的事務可能並沒有傳到從庫上,如果此時,強行將從提升為主,可能導致新主上的資料不完整。

主庫將事務 Binlog 事件寫入到 Binlog 檔案中,此時主庫只會通知一下 Dump 執行緒傳送這些新的 Binlog,然後主庫就會繼續處理提交操作,而此時不會保證這些 Binlog 傳到任何一個從庫節點上。

非同步複製—基於二進位制日誌檔案的主從複製
注:server1和server2上均裝有mysql,且均完成了安全初始化
在server1上:(master)
server1(172.25.20.1)為主資料庫,
server2(172.25.20.3)為從資料庫

vim /etc/my.cnf
/etc/init.d/mysqld restart
##寫入server-id=1(伺服器ID) log-bin=mysql-bin(開啟二進位制日誌)

##進入mysql
mysql -p

mysql>create user 'repl'@'172.25.20.%' identified by 'westos';##建立複製使用者
mysql>grant replication slave on *.* to 'repl'@'172.25.20.%';##授予使用者許可權
mysql> flush privileges;

server2上:(slave)

mysql -h 172.25.20.1 -u repl -pwestos
##檢測複製使用者是否建立成功

vim /etc/my.cnf
##寫入server-id=2

systemctl restart mariadb

在server1上:

mysql -p
mysql> show master status;##檢視master狀態

在server2上:

配置slave:

mysql -p
mysql> change master to   
 -> master_host='172.25.20.1',    
 -> master_user='repl',    
 -> master_password='westos',    
 -> master_log_file='mysql-bin.000001',    
 -> master_log_pos=1200;
mysql> start slave;
mysql> show slave status\G;           
#Slave_IO_Running: Yes            
#Slave_SQL_Running: Yes
#顯示如上說明主從複製成功  

注意:上面的master_log_file和master_log_pos的引數根據master 的狀態填寫
測試:
在server1中建立一個庫或表,在server2中也可以顯示看到,則證明主從複製成功。
非同步複製—基於全域性事務標識(GTID)的主從複製
注:兩個伺服器已經使用MySQL的基於二進位制日誌位置的複製協議作為主伺服器和從伺服器執行
在server1(主節點中)
配置主節點:啟用複製主節點,開啟gtid服務

vim /etc/my.cnf
log-bin=mysql-bin ##基於二進位制日誌位置的主從複製
server-id=1
gtid_mode=ON ##開啟gtid
enforce-gtid-consistency=OK
/etc/init.d/mysqld restart

在server2(從節點中)
配置從站slave開啟GTID的服務

vim /etc/my.cnf

server-id=2   ##基於二進位制日誌位置的主從複製
gtid_mode=ON  ##開啟gtid
enforce-gtid-consistency=ON

systemctl restart mariadb

配置從站slave使用基於GTID的自動定位。

mysql> stop slave; ##停止基於二進位制位置的複製

mysql> CHANGE MASTER TO
    -> MASTER_HOST = '172.25.20.1',
    -> MASTER_USER = 'repl',
    -> MASTER_PASSWORD = 'westos',
    -> MASTER_AUTO_POSITION = 1;

mysql> START SLAVE; ##開啟gtid的主從複製
mysql> SHOW SLAVE STATUS\G ##檢視複製狀態

測試:
在主節點server1中插入資料,在從節點server2中檢視。

半同步複製

半同步複製是介於全同步複製與全非同步複製之間的一種,主庫只需要等待至少一個從庫節點收到並且 Flush Binlog 到 Relay Log 檔案即可,主庫不需要等待所有從庫給主庫反饋。同時,這裡只是一個收到的反饋,而不是已經完全完成並且提交的反饋,如此,節省了很多時間。

介於非同步複製和全同步複製之間,主庫在執行完客戶端提交的事務後不是立刻返回給客戶端,而是等待至少一個從庫接收到並寫到relay log中才返回給客戶端。相對於非同步複製,半同步複製提高了資料的安全性,同時它也造成了一定程度的延遲,這個延遲最少是一個TCP/IP往返的時間。所以,半同步複製最好在低延時的網路中使用。

半同步複製為非同步複製協議添加了一個同步步驟。這意味著主庫在提交時等待至少一個從庫確認它已收到該事務,才會繼續提交操作。

對角箭頭表示伺服器之間交換的訊息或伺服器與客戶端應用程式之間交換的訊息。

在server1中:
主庫安裝服務外掛,並且開啟半同步複製:

mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (0.01 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=ON;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%semi%';    #環境變數
mysql> show status like '%rpl_semi_sync%';	#狀態變數

在server2中:
在從端也安裝外掛,開啟半同步複製:

mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (0.00 sec)

mysql> set global rpl_semi_sync_slave_enabled=ON;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%semi%'; 

注意: 要重啟從上的IO執行緒,如果沒有重啟,則預設還是非同步複製,重啟後,slave會在master上註冊為半同步複製的slave角色。

mysql> stop slave io_thread;
Query OK, 0 rows affected (0.00 sec)

mysql> start slave io_thread;
Query OK, 0 rows affected (0.00 sec)

mysql> show status like '%rpl%';
mysql> show variables like '%rpl%';

測試:半同步測試正常同步情況:

從端開啟IO:

mysql> start slave io_thread;
Query OK, 0 rows affected (0.00 sec)

主端插入新資料:
mysql> insert into userlist values ('user333','333');
Query OK, 1 row affected (0.01 sec)

mysql> select * from user_tb;

mysql> show status like '%rpl%'; 
#Rpl_semi_sync_master_yes_tx 變為1,成功一次

從端驗證同步結果:
mysql> select * from user_tb;