1. 程式人生 > >mysql 5.7 主從配置

mysql 5.7 主從配置

原理:

MySQL使用3個執行緒來執行復制功能(其中1個在【主伺服器】上,另兩個在【從伺服器】上。
當【從伺服器】發出START SLAVE時,【從伺服器】建立一個I/O執行緒,以連線【主伺服器】並讓它傳送記錄在其二進位制日誌中的語句。
【主伺服器】建立一個執行緒將二進位制日誌中的內容傳送到【從伺服器】。該執行緒可以識別為【主伺服器】上SHOW PROCESSLIST的輸出中的Binlog Dump執行緒。
【從伺服器】I/O執行緒讀取主伺服器Binlog Dump執行緒傳送的內容並將該資料拷貝到【從伺服器】資料目錄中的本地檔案中,即中繼日誌。第3個執行緒是SQL執行緒,是【從伺服器】建立用於讀取中繼日誌並執行日誌中包含的更新。

我準備的環境:

[root@localhost ~]# cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)

使用oneinstack安裝mysql

MySQL [(none)]> status;
--------------
mysql  Ver 14.14 Distrib 5.7.19, for linux-glibc2.12 (x86_64) using  EditLine wrapper
........
Server version: 5.7.19-log MySQL Community Server (GPL)

【主伺服器】

首先檢視mysql的配置檔案

[root@localhost ~]# vi /etc/my.cnf

查詢log_bin = mysql-bin,如果此行是#開頭,去掉#。如果不存在此行,手動新增。
查詢server-id = 1,記住【主伺服器】的id,不能和【從伺服器】重複。數字推薦寫ip尾數。
如果修改了配置檔案,需要重啟mysql。

然後檢視log_bin是否開啟

MySQL [(none)]> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON | +---------------+-------+ 1 row in set (0.00 sec)

接下來,檢視master狀態:

MySQL [(none)]> show master status;
+------------------+----------+---
| File             | Position | 
+------------------+----------+---
| mysql-bin.000017 |      503 | 
+------------------+----------+---
1 row in set (0.00 sec)

File列顯示日誌名,而Position顯示偏移量。在該例子中,二進位制日誌值為mysql-bin.000017,偏移量為503。記錄該值。以後設定從伺服器時需要使用這些值。它們表示複製座標,【從伺服器】應從該點開始從【主伺服器】上進行新的更新。

建立使用者,用來給【從伺服器】訪問。

語句:GRANT REPLICATION SLAVE ON 資料庫名.表名 TO '使用者名稱'@'來源' IDENTIFIED BY '使用者密碼';

本例:
MySQL [(none)]> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.%' IDENTIFIED BY 'mysql';

【從伺服器】

首先檢視mysql的配置檔案

[root@localhost ~]# vi /etc/my.cnf

查詢server-id = 1,改成別的,不能和【主伺服器】重複。
然後檢視

[root@localhost ~]# vi /data/mysql/auto.cnf
[auto]
server-uuid=8a886b36-7b9e-11e7-9c15-080027bbb6b4

這裡的server-uuid的值必須與主伺服器不同,否則會報錯。筆者是用的複製虛擬機器,所以會遇到這種情況。

下面關鍵部分來了:

MySQL [(none)]> CHANGE MASTER TO
    -> MASTER_HOST='192.168.1.103',
    -> MASTER_USER='repl',
    -> MASTER_PASSWORD='mysql',
    -> MASTER_LOG_FILE='mysql-bin.000017',
    -> MASTER_LOG_POS=503;

所有配置都要與【主伺服器】的資訊匹配。
然後

MySQL [(none)]> start slave;

如果需要修改前面的項:

MySQL [(none)]> stop slave;
MySQL [(none)]> reset slave;
MySQL [(none)]> CHANGE MASTER TO
    -> MASTER_HOST='192.168.1.103',
    -> MASTER_USER='repl',
    -> MASTER_PASSWORD='mysql',
    -> MASTER_LOG_FILE='mysql-bin.000017',
    -> MASTER_LOG_POS=503;
MySQL [(none)]> start slave;

設定完成後,檢視【從伺服器】狀態:

MySQL [(none)]> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.103
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000017
          Read_Master_Log_Pos: 503
               Relay_Log_File: localhost-relay-bin.000003
                Relay_Log_Pos: 669
        Relay_Master_Log_File: mysql-bin.000017
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

最後2行,必須都是Yes,如果是No或者Connecting都不行,可檢視mysql-error.log,以排查問題。

MySQL [(none)]> show variables like 'log_error%';
+---------------------+-----------------------------+
| Variable_name       | Value                       |
+---------------------+-----------------------------+
| log_error           | /data/mysql/mysql-error.log |
| log_error_verbosity | 3                           |
+---------------------+-----------------------------+
2 rows in set (0.00 sec)

配置完成後,【從伺服器】會自動與【主伺服器】同步。

經本人測試,如果【主伺服器】重啟mysql服務,【從伺服器】會等待與【主伺服器】重連,此時可檢視到這些異常狀態:

MySQL [(none)]> show slave status \G;
Slave_IO_State: Reconnecting after a failed master event read
Last_IO_Errno: 2003
Last_IO_Error: error reconnecting to master 
Last_IO_Error_Timestamp: 170810 00:43:09

當主伺服器恢復正常後,從伺服器會自動重新連線上主伺服器,並正常同步資料。

最後要補充一點百度知道上搜的,還沒測:
設定主從同步或雙主同步的話證明兩臺伺服器日誌模式都是bin-log模式,如果其中有一臺伺服器意外宕機,此時會導致同步中斷。
恢復方法很簡單:進入主機伺服器(正常機器),在bin-log中找到出錯時最接近錯誤標記的一個position,然後將宕機的伺服器資料庫執行change master,將master_log_file和master_log_pos重新指定一下就可以了
檢視binlog:

MySQL [(none)]> show binlog events in 'mysql-bin.000017';