【MySQL】MySQL一主二从复制环境切换主从库


假设有一个一主二从的环境,当主库M出现故障时,需要将其中一个从库S1切换为主库,同时将S2指向新的主库S1,如果可能,需要将故障的主库M修复并重置为新的从库。

搭建一主二从复制环境可参考:MySQL搭建主从复制环境

下面将演示一主二从复制环境主从库的切换,具体如下:

1、环境信息;
  1. Mater:192.168.1.110  
  2. Slave1:192.168.1.111  
  3. Slave2:192.168.1.112  
Mater:192.168.1.110
Slave1:192.168.1.111
Slave2:192.168.1.112
2、查看主备库状态;
Master库:
  1. mysql> show processlist;  
  2. +----+------+---------------------+------+-------------+------+---------------------------------------------------------------+------------------+  
  3. | Id | User | Host                | db   | Command     | Time | State                                                         | Info             |  
  4. +----+------+---------------------+------+-------------+------+---------------------------------------------------------------+------------------+  
  5. |  2 | root | localhost           | NULL | Query       |    0 | starting                                                      | show processlist |  
  6. |  3 | repl | 192.168.1.112:49819 | NULL | Binlog Dump |  207 | Master has sent all binlog to slave; waiting for more updates | NULL             |  
  7. |  4 | repl | 192.168.1.111:53017 | NULL | Binlog Dump |  165 | Master has sent all binlog to slave; waiting for more updates | NULL             |  
  8. +----+------+---------------------+------+-------------+------+---------------------------------------------------------------+------------------+  
  9. rows in set (0.00 sec)  
  10.   
  11. mysql> use test;  
  12. Reading table information for completion of table and column names  
  13. You can turn off this feature to get a quicker startup with -A  
  14.   
  15. Database changed  
  16. mysql> select *from t_repl;  
  17. +------+-------+---------------------+  
  18. | id   | name  | cdate               |  
  19. +------+-------+---------------------+  
  20. |    1 | Alen  | 2018-03-04 17:56:57 |  
  21. |    2 | Repl  | 2018-03-04 20:10:45 |  
  22. |    3 | USA   | 2018-03-04 22:19:48 |  
  23. |    4 | China | 2018-03-04 22:19:48 |  
  24. |    5 | Japan | 2018-03-04 22:23:28 |  
  25. |    6 | UK    | 2018-03-04 22:23:28 |  
  26. +------+-------+---------------------+  
  27. rows in set (0.00 sec)  
  28.   
  29. mysql> insert into t_repl(id,namevalues(7,'Jacky'),(8,'Tom');  
  30. Query OK, 2 rows affected (0.03 sec)  
  31. Records: 2  Duplicates: 0  Warnings: 0  
  32.   
  33. mysql>   
mysql> show processlist;
+----+------+---------------------+------+-------------+------+---------------------------------------------------------------+------------------+
| Id | User | Host                | db   | Command     | Time | State                                                         | Info             |
+----+------+---------------------+------+-------------+------+---------------------------------------------------------------+------------------+
|  2 | root | localhost           | NULL | Query       |    0 | starting                                                      | show processlist |
|  3 | repl | 192.168.1.112:49819 | NULL | Binlog Dump |  207 | Master has sent all binlog to slave; waiting for more updates | NULL             |
|  4 | repl | 192.168.1.111:53017 | NULL | Binlog Dump |  165 | Master has sent all binlog to slave; waiting for more updates | NULL             |
+----+------+---------------------+------+-------------+------+---------------------------------------------------------------+------------------+
3 rows in set (0.00 sec)

mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select *from t_repl;
+------+-------+---------------------+
| id   | name  | cdate               |
+------+-------+---------------------+
|    1 | Alen  | 2018-03-04 17:56:57 |
|    2 | Repl  | 2018-03-04 20:10:45 |
|    3 | USA   | 2018-03-04 22:19:48 |
|    4 | China | 2018-03-04 22:19:48 |
|    5 | Japan | 2018-03-04 22:23:28 |
|    6 | UK    | 2018-03-04 22:23:28 |
+------+-------+---------------------+
6 rows in set (0.00 sec)

mysql> insert into t_repl(id,name) values(7,'Jacky'),(8,'Tom');
Query OK, 2 rows affected (0.03 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> 
Slave1库:
  1. mysql> show processlist;  
  2. +----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+  
  3. | Id | User        | Host      | db   | Command | Time | State                                                  | Info             |  
  4. +----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+  
  5. |  1 | system user |           | NULL | Connect |  299 | Waiting for master to send event                       | NULL             |  
  6. |  2 | system user |           | NULL | Connect |  173 | Slave has read all relay log; waiting for more updates | NULL             |  
  7. |  4 | root        | localhost | NULL | Query   |    0 | starting                                               | show processlist |  
  8. +----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+  
  9. rows in set (0.00 sec)  
  10.   
  11. mysql> use test;  
  12. Reading table information for completion of table and column names  
  13. You can turn off this feature to get a quicker startup with -A  
  14.   
  15. Database changed  
  16. mysql> select *from t_repl;  
  17. +------+-------+---------------------+  
  18. | id   | name  | cdate               |  
  19. +------+-------+---------------------+  
  20. |    1 | Alen  | 2018-03-04 17:56:57 |  
  21. |    2 | Repl  | 2018-03-04 20:10:45 |  
  22. |    3 | USA   | 2018-03-04 22:19:48 |  
  23. |    4 | China | 2018-03-04 22:19:48 |  
  24. |    5 | Japan | 2018-03-04 22:23:28 |  
  25. |    6 | UK    | 2018-03-04 22:23:28 |  
  26. |    7 | Jacky | 2018-03-05 18:55:32 |  
  27. |    8 | Tom   | 2018-03-05 18:55:32 |  
  28. +------+-------+---------------------+  
  29. rows in set (0.00 sec)  
  30.   
  31. mysql>   
mysql> show processlist;
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
| Id | User        | Host      | db   | Command | Time | State                                                  | Info             |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
|  1 | system user |           | NULL | Connect |  299 | Waiting for master to send event                       | NULL             |
|  2 | system user |           | NULL | Connect |  173 | Slave has read all relay log; waiting for more updates | NULL             |
|  4 | root        | localhost | NULL | Query   |    0 | starting                                               | show processlist |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
3 rows in set (0.00 sec)

mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select *from t_repl;
+------+-------+---------------------+
| id   | name  | cdate               |
+------+-------+---------------------+
|    1 | Alen  | 2018-03-04 17:56:57 |
|    2 | Repl  | 2018-03-04 20:10:45 |
|    3 | USA   | 2018-03-04 22:19:48 |
|    4 | China | 2018-03-04 22:19:48 |
|    5 | Japan | 2018-03-04 22:23:28 |
|    6 | UK    | 2018-03-04 22:23:28 |
|    7 | Jacky | 2018-03-05 18:55:32 |
|    8 | Tom   | 2018-03-05 18:55:32 |
+------+-------+---------------------+
8 rows in set (0.00 sec)

mysql> 
Slave2库:
  1. mysql> show processlist;  
  2. +----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+  
  3. | Id | User        | Host      | db   | Command | Time | State                                                  | Info             |  
  4. +----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+  
  5. |  1 | system user |           | NULL | Connect |  356 | Waiting for master to send event                       | NULL             |  
  6. |  2 | system user |           | NULL | Connect |  291 | Slave has read all relay log; waiting for more updates | NULL             |  
  7. |  4 | root        | localhost | test | Query   |    0 | starting                                               | show processlist |  
  8. +----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+  
  9. rows in set (0.00 sec)  
  10.   
  11. mysql> select *from t_repl;  
  12. +------+-------+---------------------+  
  13. | id   | name  | cdate               |  
  14. +------+-------+---------------------+  
  15. |    1 | Alen  | 2018-03-04 17:56:57 |  
  16. |    2 | Repl  | 2018-03-04 20:10:45 |  
  17. |    3 | USA   | 2018-03-04 22:19:48 |  
  18. |    4 | China | 2018-03-04 22:19:48 |  
  19. |    5 | Japan | 2018-03-04 22:23:28 |  
  20. |    6 | UK    | 2018-03-04 22:23:28 |  
  21. |    7 | Jacky | 2018-03-05 18:55:32 |  
  22. |    8 | Tom   | 2018-03-05 18:55:32 |  
  23. +------+-------+---------------------+  
  24. rows in set (0.00 sec)  
  25.   
  26. mysql>   
mysql> show processlist;
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
| Id | User        | Host      | db   | Command | Time | State                                                  | Info             |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
|  1 | system user |           | NULL | Connect |  356 | Waiting for master to send event                       | NULL             |
|  2 | system user |           | NULL | Connect |  291 | Slave has read all relay log; waiting for more updates | NULL             |
|  4 | root        | localhost | test | Query   |    0 | starting                                               | show processlist |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
3 rows in set (0.00 sec)

mysql> select *from t_repl;
+------+-------+---------------------+
| id   | name  | cdate               |
+------+-------+---------------------+
|    1 | Alen  | 2018-03-04 17:56:57 |
|    2 | Repl  | 2018-03-04 20:10:45 |
|    3 | USA   | 2018-03-04 22:19:48 |
|    4 | China | 2018-03-04 22:19:48 |
|    5 | Japan | 2018-03-04 22:23:28 |
|    6 | UK    | 2018-03-04 22:23:28 |
|    7 | Jacky | 2018-03-05 18:55:32 |
|    8 | Tom   | 2018-03-05 18:55:32 |
+------+-------+---------------------+
8 rows in set (0.00 sec)

mysql> 
3、模拟主库Master宕机;
  1. mysql> shutdown;  
  2. Query OK, 0 rows affected (0.01 sec)  
  3.   
  4. mysql> system service mysql.server status;  
  5.  ERROR! MySQL is not running, but lock file (/var/lock/subsys/mysql) exists  
  6. mysql>   
mysql> shutdown;
Query OK, 0 rows affected (0.01 sec)

mysql> system service mysql.server status;
 ERROR! MySQL is not running, but lock file (/var/lock/subsys/mysql) exists
mysql> 
4、确保从库都执行了relay log的全部更新,在每个从库上执行stop slave io_thread,然后检查show processlist的输出,状态是Slave has read all relay log; waiting for more updates,表示更新都执行完毕;
  1. mysql> stop slave io_thread;  
  2. Query OK, 0 rows affected (0.01 sec)  
  3.   
  4. mysql> show processlist;  
  5. +----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+  
  6. | Id | User        | Host      | db   | Command | Time | State                                                  | Info             |  
  7. +----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+  
  8. |  2 | system user |           | NULL | Connect | 7500 | Slave has read all relay log; waiting for more updates | NULL             |  
  9. |  4 | root        | localhost | test | Query   |    0 | starting                                               | show processlist |  
  10. +----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+  
  11. rows in set (0.00 sec)  
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.01 sec)

mysql> show processlist;
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
| Id | User        | Host      | db   | Command | Time | State                                                  | Info             |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
|  2 | system user |           | NULL | Connect | 7500 | Slave has read all relay log; waiting for more updates | NULL             |
|  4 | root        | localhost | test | Query   |    0 | starting                                               | show processlist |
+----+-------------+-----------+------+---------+------+--------------------------------------------------------+------------------+
2 rows in set (0.00 sec)
5、在从库Slave1上,执行stop slave来停止从服务,然后执行reset master重置成主库;
  1. mysql> show master status;  
  2. Empty set (0.00 sec)  
  3.   
  4. mysql> stop slave;  
  5. Query OK, 0 rows affected (0.00 sec)  
  6.   
  7. mysql> reset master;  
  8. Query OK, 0 rows affected (0.00 sec)  
mysql> show master status;
Empty set (0.00 sec)

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

mysql> reset master;
Query OK, 0 rows affected (0.00 sec)
6、检查从库Slave1的log-bin是否打开,没打开则打开;
7、删除从库Slave1上的master.info和relay-log.info,否则下次重启则按照从库启动;再/usr/lcoal/mysql/data目录下面
8、在Slave2上,执行stop slave停止从库服务,然后执行change master to重新指向主库slave1,再执行start slave启动从库;
注意再slave1上添加同步的账号

  1. mysql> stop slave;  
  2. Query OK, 0 rows affected (0.01 sec)  
  3.   
  4. mysql> change master to   
  5.     -> master_host='192.168.1.111';  
  6. Query OK, 0 rows affected (0.02 sec)  
  7.   
  8. mysql> start slave;  
  9. Query OK, 0 rows affected (0.02 sec)  
  10.   
  11. mysql>   
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)

mysql> change master to 
    -> master_host='192.168.1.111';
Query OK, 0 rows affected (0.02 sec)

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

mysql> 
9、检查Slave2的状态,发现已经指向新的主库Slave1;
  1. mysql> show slave status\G;  
  2. *************************** 1. row ***************************  
  3.                Slave_IO_State: Waiting for master to send event  
  4.                   Master_Host: 192.168.1.111  
  5.                   Master_User: repl  
  6.                   Master_Port: 3306  
  7.                 Connect_Retry: 60  
  8.               Master_Log_File: mysql111-bin.000002  
  9.           Read_Master_Log_Pos: 154  
  10.                Relay_Log_File: mysql-relay-bin.000003  
  11.                 Relay_Log_Pos: 373  
  12.         Relay_Master_Log_File: mysql111-bin.000002  
  13.              Slave_IO_Running: Yes  
  14.             Slave_SQL_Running: Yes  
  15.               Replicate_Do_DB:   
  16.           Replicate_Ignore_DB:   
  17.            Replicate_Do_Table:   
  18.        Replicate_Ignore_Table:   
  19.       Replicate_Wild_Do_Table:   
  20.   Replicate_Wild_Ignore_Table:   
  21.                    Last_Errno: 0  
  22.                    Last_Error:   
  23.                  Skip_Counter: 0  
  24.           Exec_Master_Log_Pos: 154  
  25.               Relay_Log_Space: 799  
  26.               Until_Condition: None  
  27.                Until_Log_File:   
  28.                 Until_Log_Pos: 0  
  29.            Master_SSL_Allowed: No  
  30.            Master_SSL_CA_File:   
  31.            Master_SSL_CA_Path:   
  32.               Master_SSL_Cert:   
  33.             Master_SSL_Cipher:   
  34.                Master_SSL_Key:   
  35.         Seconds_Behind_Master: 0  
  36. Master_SSL_Verify_Server_Cert: No  
  37.                 Last_IO_Errno: 0  
  38.                 Last_IO_Error:   
  39.                Last_SQL_Errno: 0  
  40.                Last_SQL_Error:   
  41.   Replicate_Ignore_Server_Ids:   
  42.              Master_Server_Id: 111  
  43.                   Master_UUID: c8368e4a-1fa4-11e8-aa25-000c299f40a9  
  44.              Master_Info_File: /usr/local/mysql-5.7.21-linux-glibc2.12-x86_64/data/master.info  
  45.                     SQL_Delay: 0  
  46.           SQL_Remaining_Delay: NULL  
  47.       Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates  
  48.            Master_Retry_Count: 86400  
  49.                   Master_Bind:   
  50.       Last_IO_Error_Timestamp:   
  51.      Last_SQL_Error_Timestamp:   
  52.                Master_SSL_Crl:   
  53.            Master_SSL_Crlpath:   
  54.            Retrieved_Gtid_Set:   
  55.             Executed_Gtid_Set:   
  56.                 Auto_Position: 0  
  57.          Replicate_Rewrite_DB:   
  58.                  Channel_Name:   
  59.            Master_TLS_Version:   
  60. 1 row in set (0.00 sec)  
  61.   
  62. ERROR:   
  63. No query specified  
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.111
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql111-bin.000002
          Read_Master_Log_Pos: 154
               Relay_Log_File: mysql-relay-bin.000003
                Relay_Log_Pos: 373
        Relay_Master_Log_File: mysql111-bin.000002
             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: 154
              Relay_Log_Space: 799
              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: 111
                  Master_UUID: c8368e4a-1fa4-11e8-aa25-000c299f40a9
             Master_Info_File: /usr/local/mysql-5.7.21-linux-glibc2.12-x86_64/data/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)

ERROR: 
No query specified
10、将应用程序指向新的主库Slave1,这样Slave1的所有更新写入到Slave1的Binlog中,从而同步到新的从库Slave2中;
新的主库Slave1:
  1. mysql> use test;  
  2. Reading table information for completion of table and column names  
  3. You can turn off this feature to get a quicker startup with -A  
  4.   
  5. Database changed  
  6. mysql> select *from t_repl;  
  7. +------+-------+---------------------+  
  8. | id   | name  | cdate               |  
  9. +------+-------+---------------------+  
  10. |    1 | Alen  | 2018-03-04 17:56:57 |  
  11. |    2 | Repl  | 2018-03-04 20:10:45 |  
  12. |    3 | USA   | 2018-03-04 22:19:48 |  
  13. |    4 | China | 2018-03-04 22:19:48 |  
  14. |    5 | Japan | 2018-03-04 22:23:28 |  
  15. |    6 | UK    | 2018-03-04 22:23:28 |  
  16. |    7 | Jacky | 2018-03-05 18:55:32 |  
  17. |    8 | Tom   | 2018-03-05 18:55:32 |  
  18. +------+-------+---------------------+  
  19. rows in set (0.00 sec)  
  20.   
  21. mysql> insert into t_repl(id,namevalues(9,'Slave1-->Master');  
  22. Query OK, 1 row affected (0.01 sec)  
  23.   
  24. mysql>   
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select *from t_repl;
+------+-------+---------------------+
| id   | name  | cdate               |
+------+-------+---------------------+
|    1 | Alen  | 2018-03-04 17:56:57 |
|    2 | Repl  | 2018-03-04 20:10:45 |
|    3 | USA   | 2018-03-04 22:19:48 |
|    4 | China | 2018-03-04 22:19:48 |
|    5 | Japan | 2018-03-04 22:23:28 |
|    6 | UK    | 2018-03-04 22:23:28 |
|    7 | Jacky | 2018-03-05 18:55:32 |
|    8 | Tom   | 2018-03-05 18:55:32 |
+------+-------+---------------------+
8 rows in set (0.00 sec)

mysql> insert into t_repl(id,name) values(9,'Slave1-->Master');
Query OK, 1 row affected (0.01 sec)

mysql> 
新的从库Slave2:

  1. mysql> use test ;  
  2. Database changed  
  3. mysql> select *from t_repl;  
  4. +------+-----------------+---------------------+  
  5. | id   | name            | cdate               |  
  6. +------+-----------------+---------------------+  
  7. |    1 | Alen            | 2018-03-04 17:56:57 |  
  8. |    2 | Repl            | 2018-03-04 20:10:45 |  
  9. |    3 | USA             | 2018-03-04 22:19:48 |  
  10. |    4 | China           | 2018-03-04 22:19:48 |  
  11. |    5 | Japan           | 2018-03-04 22:23:28 |  
  12. |    6 | UK              | 2018-03-04 22:23:28 |  
  13. |    7 | Jacky           | 2018-03-05 18:55:32 |  
  14. |    8 | Tom             | 2018-03-05 18:55:32 |  
  15. |    9 | Slave1-->Master | 2018-03-05 21:28:54 |  
  16. +------+-----------------+---------------------+  
  17. rows in set (0.00 sec)  
mysql> use test ;
Database changed
mysql> select *from t_repl;
+------+-----------------+---------------------+
| id   | name            | cdate               |
+------+-----------------+---------------------+
|    1 | Alen            | 2018-03-04 17:56:57 |
|    2 | Repl            | 2018-03-04 20:10:45 |
|    3 | USA             | 2018-03-04 22:19:48 |
|    4 | China           | 2018-03-04 22:19:48 |
|    5 | Japan           | 2018-03-04 22:23:28 |
|    6 | UK              | 2018-03-04 22:23:28 |
|    7 | Jacky           | 2018-03-05 18:55:32 |
|    8 | Tom             | 2018-03-05 18:55:32 |
|    9 | Slave1-->Master | 2018-03-05 21:28:54 |
+------+-----------------+---------------------+
9 rows in set (0.00 sec)

11、最后,如果主库Master修复,则将其重新配置成Slave1的从库;

猜你喜欢

转载自blog.csdn.net/lvshanhshan/article/details/80543584