MySQL Replication之主從切換


在生產環境中,我們的架構很多都是一主多從。比如一個主數據庫服務器M,兩個從數據庫服務器S1,S2同時指向主數據庫服務器M。當主服務器M因為意外情況宕機,需要將其中的一個從數據庫服務器(假設選擇S1)切換成主數據庫服務器,同時修改另一個從數據庫(S2)的配置,使其指向新的主數據庫(S1)。此外還需要通知應用修改主數據庫的IP地址,如果可能,將出現故障的主數據庫(M)修復或者重置成新的從數據庫。通常我們還有其他的方案來實現高可用,比如MHA,MySQL Cluster,MMM,這些將在后續的文章中慢慢道來。現在我們先看簡單的一主多從切換的情況。^_^

下面詳細介紹切換主從的操作步驟。

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)有權限進行連接

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啟動復制:

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同步錯誤。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM