在生產環境中,咱們的架構不少都是一主多從。好比一個主數據庫服務器M,兩個從數據庫服務器S1,S2同時指向主數據庫服務器M。當主服務器M由於意外狀況宕機,須要將其中的一個從數據庫服務器(假設選擇S1)切換成主數據庫服務器,同時修改另外一個從數據庫(S2)的配置,使其指向新的主數據庫(S1)。此外還須要通知應用修改主數據庫的IP地址,若是可能,將出現故障的主數據庫(M)修復或者重置成新的從數據庫。一般咱們還有其餘的方案來實現高可用,好比MHA,MySQL Cluster,MMM,這些將在後續的文章中慢慢道來。如今咱們先看簡單的一主多從切換的狀況。^_^mysql
下面詳細介紹切換主從的操做步驟。sql
1.首先要確保全部的從數據庫都已經執行了relay log中的所有更新,在每一個從庫上,執行stop slave io_thread,中止IO線程,而後檢查show processlist的輸出,直到看到狀態是Slave has read all relay log; waiting for the slave I/O thread to update it,表示更新都執行完畢數據庫
S1(從庫1操做):服務器
mysql> stop slave io_thread; Query OK, 0 rows affected (0.06 sec) mysql> show processlist\G *************************** 1. row *************************** Id: 3 User: system user Host: db: NULL Command: Connect Time: 2601 State: Slave has read all relay log; waiting for the slave I/O thread to update it Info: NULL *************************** 2. row *************************** Id: 4 User: root Host: localhost db: NULL Command: Query Time: 0 State: NULL Info: show processlist 2 rows in set (0.00 sec) mysql>
S2(從庫2操做):架構
mysql> stop slave io_thread; Query OK, 0 rows affected (0.00 sec) mysql> show processlist\G *************************** 1. row *************************** Id: 4 User: system user Host: db: NULL Command: Connect Time: 2721 State: Slave has read all relay log; waiting for the slave I/O thread to update it Info: NULL *************************** 2. row *************************** Id: 5 User: root Host: localhost db: NULL Command: Query Time: 0 State: NULL Info: show processlist 2 rows in set (0.00 sec) mysql>
2.在從庫S1上,執行stop slave中止從服務,而後執行reset master以重置成主數據庫,而且進行受權帳號,讓S2(從庫2)有權限進行鏈接ide
S1(從庫1操做):測試
mysql> stop slave; Query OK, 0 rows affected (0.01 sec) mysql> reset master; Query OK, 0 rows affected (0.06 sec) mysql> grant replication slave on *.* to 'repl'@'192.168.0.100' identified by '123456'; Query OK, 0 rows affected (0.00 sec) mysql>
3.在S2(從庫2)上,執行stop slave中止從服務,而後執行change master to master_host='S1'以從新設置主數據庫,而後再執行start slave啓動複製:spa
S2(從庫2操做):線程
mysql> stop slave; Query OK, 0 rows affected (0.01 sec) mysql> change master to master_host='192.168.0.20'; Query OK, 0 rows affected (0.06 sec) mysql> start slave; Query OK, 0 rows affected (0.00 sec) mysql>
4.查看S2(從庫2)複製狀態是否正常:日誌
mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.0.20 Master_User: repl Master_Port: 3306 Connect_Retry: 2 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 261 Relay_Log_File: MySQL-02-relay-bin.000002 Relay_Log_Pos: 407 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: yayun.% Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 261 Relay_Log_Space: 566 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: 2 1 row in set (0.00 sec) mysql>
查看原來的從庫S1,如今的主庫的show processlist狀況:
mysql> show processlist\G *************************** 1. row *************************** Id: 4 User: root Host: localhost db: NULL Command: Query Time: 0 State: NULL Info: show processlist *************************** 2. row *************************** Id: 7 User: repl Host: 192.168.0.100:60235 db: NULL Command: Binlog Dump Time: 184 State: Master has sent all binlog to slave; waiting for binlog to be updated Info: NULL 2 rows in set (0.00 sec) mysql>
5.通知全部的客戶端將應用指向S1(已提高爲主庫),這樣客戶端發送的全部的更新變化將記錄到S1的二進制日誌。
6.刪除S1(新的主庫)服務器上的master.info和relay-log.info文件,不然下次重啓時還會按照從庫啓動。咱們也能夠設置該參數:
skip_slave_start
7.最後,若是M服務器修復之後,則能夠按照S2的方法配置成S1的從庫。
總結:
上面的測試步驟中S1默認都是打開log-bin選項的,這樣重置成主數據庫後能夠將二進制日誌記錄下來,並傳送到其餘從庫,這是提高爲主庫必須的。其次,S1沒有打開log-slave-updates參數,不然重置成主庫之後,可能會將已經執行過的二進制日誌重複傳送給S2,致使S2同步錯誤。