MySQL5.6 主從復制的配置
環境
操作系統:CentOS-6.6-x86_64
MySQL 版本:mysql-5.6.26.tar.gz
主節點 IP:192.168.31.57 主機名:edu-mysql-01
從節點 IP:192.168.31.59 主機名:edu-mysql-02
MySQL 主從復制官方文檔
MySQL 主從復制(也稱 A/B 復制)的原理
- Master 將數據改變記錄到二進制日志(binary log)中,也就是配置文件 log-bin 指定的文件,這些記錄叫做二進制日志事件(binary log events);
- Slave 通過 I/O 線程讀取 Master 中的 binary log events 並寫入到它的 中繼日志(relay log);
- Slave 重做中繼日志中的事件,把中繼日志中的事件信息一條一條的在 本地執行一次,完成數據在本地的存儲,從而實現將改變反映到它自己的 數據(數據重放)。
主從配置需要注意的點
- 主從服務器操作系統版本和位數一致;主從服務器的 hostname 不要一致。
- Master 和 Slave 數據庫的版本要一致;
- Master 和 Slave 數據庫中的數據要一致;
- Master 開啟二進制日志,Master 和 Slave 的 server_id 在局域網內必 須唯一;
- Master 和 Slave 都創建數據庫 mbank,表 testuser ;
Master 配置
1、Master(192.168.31.57)和 Slave(192.168.31.59) 注意:兩台數據庫服務器的的 selinux 都要 disable(永久關閉 selinux,請 修改/etc/selinux/config,將 SELINUX 改為 disabled)
2、修改 Master 的配置文件
/etc/my.cnf [root@edu-mysql-01 ~]# vi /etc/my.cnf # 在 [mysqld] 中增加以下配置項 # 設置 server_id,一般設置為 IP server_id=57 # 復制過濾:需要備份的數據庫,輸出 binlog binlog-do-db=mbank # 復制過濾:不需要備份的數據庫,不輸出(mysql 庫一般不同步) binlog-ignore-db=mysql # 開啟二進制日志功能,可以隨便取,最好有含義 log-bin=edu-mysql-bin # 為每個 session 分配的內存,在事務過程中用來存儲二進制日志的緩存 binlog_cache_size=1M # 主從復制的格式(mixed,statement,row,默認格式是 statement) binlog_format=mixed # 二進制日志自動刪除/過期的天數。默認值為 0,表示不自動刪除。 expire_logs_days=7 # 跳過主從復制中遇到的所有錯誤或指定類型的錯誤,避免 slave 端復制中斷。 # 如:1062 錯誤是指一些主鍵重復,1032 錯誤是因為主從數據庫數據不一 致 slave_skip_errors=1062 # 如果需要同步函數或者存儲過程 log_bin_trust_function_creators=true
(如想了解以上參數的更多詳細解析,可以直接百度參數名)
2.1 復制過濾可以讓你只復制服務器中的一部分數據,有兩種復制過濾:
- 在 Master 上過濾二進制日志中的事件;
- 在 Slave 上過濾中繼日志中的事件。
2.2 MySQL 對於二進制日志 (binlog)的復制類型
- 基於語句的復制:在 Master 上執行的 SQL 語句,在 Slave 上執行同樣的語句。MySQL 默認采用基於語句的復制,效率比較高。一旦發現沒法精 確復制時,會自動選着基於行的復制。
- 基於行的復制:把改變的內容復制到 Slave,而不是把命令在 Slave 上 執行一遍。從 MySQL5.0 開始支持。
- 混合類型的復制:默認采用基於語句的復制,一旦發現基於語句的無法 精確的復制時,就會采用基於行的復制。
3、啟動/重啟 Master 數據庫服務,登錄數據庫,創建數據同步用戶,並授予相應的權限
[root@edu-mysql-01 ~]# service mysql restart Shutting down MySQL..[ OK ] Starting MySQL..[ OK ] [root@edu-mysql-01 ~]# mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.6.26-log Source distribution Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reser ved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input stat ement. #創建數據同步用戶,並授予相應的權限 mysql> grant replication slave, replication client on *.* to 'repl'@'192. 168.31.59' identified by '123456'; Query OK, 0 rows affected (0.00 sec) # 刷新授權表信息 mysql> flush privileges; Query OK, 0 rows affected (0.00 sec) # 查看 MySQL 現在有哪些用戶及對應的 IP 權限 mysql> select user,host from mysql.user; # 查看 position 號,記下 position 號(從機上需要用到這個 position 號和現 在的日志文件) mysql> show master status; Master 重啟后會修改 mysql-bin 文件名(序號加 1)
4、接下來處理 Slave(192.168.31.59),配置文件只需修改一項,其余配 置用命令來操作
[root@edu-mysql-02 ~]# vi /etc/my.cnf ## 在 [mysqld] 中增加以下配置項 # 設置 server_id,一般設置為 IP server_id=59 # 復制過濾:需要備份的數據庫,輸出 binlog binlog-do-db=mbank #復制過濾:不需要備份的數據庫,不輸出(mysql 庫一般不同步) binlog-ignore-db=mysql # 開啟二進制日志,以備 Slave 作為其它 Slave 的 Master 時使用 log-bin=edu-mysql-slave1-bin # 為每個 session 分配的內存,在事務過程中用來存儲二進制日志的緩存 binlog_cache_size = 1M # 主從復制的格式(mixed,statement,row,默認格式是 statement) binlog_format=mixed # 二進制日志自動刪除/過期的天數。默認值為 0,表示不自動刪除。 expire_logs_days=7 # 跳過主從復制中遇到的所有錯誤或指定類型的錯誤,避免 slave 端復制中 斷。 # 如:1062 錯誤是指一些主鍵重復,1032 錯誤是因為主從數據庫數據不一 致 slave_skip_errors=1062 # relay_log 配置中繼日志 relay_log=edu-mysql-relay-bin # log_slave_updates 表示 slave 將復制事件寫進自己的二進制日志 log_slave_updates=1 # 防止改變數據(除了特殊的線程) read_only=1
如果 Slave 為其它 Slave 的 Master 時,必須設置 bin_log。在這里,我們 開啟了二進制日志,而且顯式的命名(默認名稱為 hostname,但是,如果 h ostname 改變則會出現問題)。
relay_log 配置中繼日志,log_slave_updates 表示 slave 將復制事件寫進自 己的二進制日志。
當設置 log_slave_updates 時,你可以讓 slave 扮演其它 slave 的 master。 此時,slave 把 SQL 線程執行的事件寫進行自己的二進制日志 (binary log), 然后,它的 slave 可以獲取這些事件並執行它.
5、保存后重啟 MySQL 服務,還原備份數據
[root@edu-mysql-02 ~]# service mysql restart
Shutting down MySQL..[ OK ] Starting MySQL..[ OK ]
6、登錄 Slave 數據庫,添加相關參數
###Master 的 IP、端口、同步用戶、密碼、position 號、讀取哪個日志文件
[root@edu-mysql-02 ~]# mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.6.26-log Source distribution Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights rese rved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input stat ement. mysql> change master to master_host='192.168.31.57', master_user=' repl', master_password='123456', master_port=3306, master_log_file=' edu-mysql-bin.000001', master_log_pos=429, master_connect_retry=3 0; Query OK, 0 rows affected, 2 warnings (0.01 sec)
上面執行的命令的解釋:
master_host='192.168.31.57' ## Master 的 IP 地址
master_user='repl' ## 用於同步數據的用戶(在 Master 中授權的用戶)
master_password='123456' ## 同步數據用戶的密碼
master_port=3306 ## Master 數據庫服務的端口
master_log_file='edu-mysql-bin.000001' ##指定 Slave 從哪個日志文 件開始讀復制數據(可在 Master 上使用 show master status 查看到日志 文件名)
master_log_pos=429 ## 從哪個 POSITION 號開始讀
master_connect_retry=30 ##當重新建立主從連接時,如果連接 建立失敗,間隔多久后重試。單位為秒,默認設置為 60 秒,同步延遲調優 參數。
## 查看主從同步狀態
mysql> show slave status\G;
可看到 Slave_IO_State 為空, Slave_IO_Running 和 Slave_SQL_Runnin g 是 No,表明 Slave 還沒有開始復制過程。
## 開啟主從同步
mysql> start slave; Query OK, 0 rows affected (0.00 sec)
## 再查看主從同步狀態
mysql> show slave status\G;
主要看以下兩個參數,這兩個參數如果是 Yes 就表示主從同步正常
Slave_IO_Running: Yes Slave_SQL_Running: Yes
由截圖中的主從同步狀態信息可以看出,我們配置的主從同步是正常的。
可查看 master 和 slave 上線程的狀態。在 master 上,可以看到 slave 的 I
/O 線程創建的連接:
Master : mysql> show processlist\G;
(1)row 為處理 slave 的 I/O 線程的連接。
(2)row 為處理 MySQL 客戶端連接線程。
(3)row 為處理本地命令行的線程。
Slave :
mysql> show processlist\G;
(1) row 為 I/O 線程狀態。
(2) row 為 SQL 線程狀態。
(3) row 為處理本地命令行的線程。
7、主從數據復制同步測試
(1) 在 Master 中的 mbank 庫上變更數據的同步測試;
mysql> INSERT INTO `testuser`(`usercode`,`username`) VALUES (`1`, '同步測試 1'),( `2`,'同步測試 2');
Master 中添加完之后,登錄 Slave 中查看數據是否已同步。
8、測試過程中,如果遇到同步出錯,可在 Slave 上重置主從復制設置(選 操作):
mysql> reset slave; mysql> change master to master_host='192.168.31.57', master_user='repl', master_password='123456', master_port=3306, master_log_file='edu-mysql-bin.00000x', master_log_pos=xx, master_connect_retry=30;
(此時,master_log_file 和 master_log_pos 要在 Master 中用 show maste
r status 命令查看)
注意:如果在 Slave 沒做只讀控制的情況下,千萬不要在 Slave 中手動插 入數據,那樣數據就會不一致,主從就會斷開,就需要重新配置了。
上面所搭建的是單向復制的主從,也是用的比較多的,而雙向主從其實 就是 Master 和 Slave 都開啟日志功能,然后在 Master 執行授權用戶
(這 里授權的是自己作為從服務器,也就是這里的 IP 地址是 Master 的 IP 地址), 然后再在 Master 上進行 chang master 操作。
基於局域網的 Master/Slave 機制在通常情況下已經可以滿足“實時”備份 的要求了。如果延遲比較大,可以從以下幾個因素進行排查:
- 網絡延遲;
- Master 負載過高;
- Slave 負載過高;
一般的做法是使用多台 Slave 來分攤讀請求,再單獨配置一台 Slave 只作 為備份用,不進行其他任何操作,就能相對最大限度地達到“實時”的要 求了。
我在部署的時候遇到的問題: 由於我的從服務器是主服務器復制過來的,mysql 的 server_id 一樣,在同步的時候出錯了:
Fatal error: The slave I/O thread stops because master and slave have equal MySQ L server UUIDs; these UUIDs must be different for replication to work.
(1)首先檢查:
mysql> show variables like ‘server_id'; +—————+——-+ | Variable_name | Value | +—————+——-+ | server_id | 3 | +—————+——-+
主從不能不一樣。
(2)如果還不行,繼續排查。進入 mysql 的 data 目錄,打開 auto.cnf 文件,里面記錄了 數據庫的 uuid,每個庫的 uuid 應該是不一樣的。
[auto]
server-uuid=6dcee5be-8cdb-11e2-9408-90e2ba2e2ea6
解決辦法,按照這個 16 進制格式,隨便改下,重啟 mysql 即可。