一、MySQL主從複製概述
1、主從複製簡介
MySQL主從複製就是將一個MySQL實例(Master)中的數據實時複製到另一個MySQL實例(slave)中,而且這個複製是一個異步複製的過程。
實現整個複製操作主要由三個進程完成的,其中兩個進程在Slave(sql_thread和IO_thread),另外一個進程在 Master(IO進程)上。
2、主從複製原理、機制
要實施複製,首先必須打開Master端的binary log(bin-log)功能,否則無法實現。因爲整個複製過程實際上就是Slave從Master端獲取該日誌然後再在自己身上完全順序的執行日誌中所記錄的各種操作。
複製的基本過程如下:
1)、Slave上面的IO_thread連接上Master,並請求從指定日誌文件的指定位置(或者從最開始的日誌)之後的日誌內容;
2)、Master接收到來自Slave的IO_thread的請求後,通過負責複製的IO進程根據請求信息讀取制定日誌指定位置之後的日誌信息,返回給Slave 的IO_thread。返回信息中除了日誌所包含的信息之外,還包括本次返回的信息已經到Master端的bin-log file的以及bin-log pos;
3)、Slave的IO_thread接收到信息後,將接收到的日誌內容依次添加到Slave端的relay-log文件的最末端,並將讀取到的Master端的 bin-log的文件名和位置記錄到master-info文件中,以便在下一次讀取的時候能夠清楚的告訴Master“我需要從某個bin-log的哪 個位置開始往後的日誌內容,請發給我”;
4)、Slave的Sql_thread檢測到relay-log中新增加了內容後,會馬上解析relay-log的內容成爲在Master端真實執行時候的那些可執行的內容,並在本數據庫中執行。
3、主從複製原理圖
二、MySQL主從複製搭建
MySQL主從複製搭建主要步驟有:Master端配置部署、Slave端配置部署、建立主從同步
1、Master端配置部署
a、 配置參數:
[mysqld] server-id=101 # 這個要保證一個主從複製環境中,不要有相同的server-id log-bin=/data/mysql6001/binlog/mysql-bin.log log-bin-index=/data/mysql6001/binlog/mysql-bin.index expire_logs_days=30 |
b、 創建用戶,並賦予權限:
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY PASSWORD '******';
2、Slave端配置部署
a、 配置參數:
[mysqld] server-id=102 relay-log=/data/mysql6001/relaylog/mysql-relay-bin.log relay-log-index=/data/mysql6001/relaylog/mysql-relay-bin.index relay_log_purge=on |
3、建立主從同步
(重建備庫也是使用該方法)
建立主從同步可以從主庫上導出數據,也可以從已有的從庫上導出數據,然後再導入到新的從庫中,change master to建立同步。
3.1 、導出數據
在主庫上導出數據:
mysqldump -u*** -p*** -S /data/mysql6001/mysql.sock --default-character-set=utf8 -q --single-transaction --master-data -A > /tmp/all_database.sql
(或者)在從庫上導出數據:
mysqldump -u*** -p*** -S /data/mysql6001/mysql.sock --default-character-set=utf8 -q --single-transaction --dump-slave -A > /tmp/all_database.sql
NOTES:
--master-data和--dump-slave導出的備份中,會包含master_log_file和master_log_pos信息。
3.2 、從庫導入數據
mysql -u*** -p*** --default-character-set=utf8 < all_database.sql
NOTES:
此處導入腳本,就已經在從庫中執行了以下操作:
change_master_to master_log_file=' mysql-bin.000xxx', master_log_pos=xxxxxx; |
3.3 、從庫與主機建立同步
以下爲建立主從同步最基本的6個項:
change master to master_host='xxx.xxx.xxx.xxx', # 主庫IP master_port=6001, # 主庫mysqld的端口 master_user='repl', # 主庫中創建的有REPLICATION SLAVE 權限的用戶 master_password='xxxxxxxx', # 該用戶的密碼 master_log_file=' mysql-bin.000xxx', # 已在導入時指定了 master_log_pos=xxxxxx; #已在導入時指定了 |
指定與主庫同步的基本信息後,就可以啓動slave進程了:(IO_thread和sql_thread)
start slave; |
三、主從複製狀態檢查及異常處理
1、主從複製狀態檢查
主庫查看binlog情況:
show master status\G *************************** 1. row *************************** File: mysql-bin.000303 Position: 18711563 Binlog_Do_DB: Binlog_Ignore_DB: |
在從庫上主要是使用以下命令查看從庫與主庫的同步狀態:
show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.43.128 #主庫IP Master_User: repl #主庫複製的用戶 Master_Port: 6001 #主庫mysqld端口 Connect_Retry: 60 Master_Log_File: mysql-bin.000303 #io_thread讀取主庫master_log_file Read_Master_Log_Pos: 18711563 # io_thread讀取主庫master_log_pos Relay_Log_File: mysql-relay-bin.000900 Relay_Log_Pos: 18711709 Relay_Master_Log_File: mysql-bin.000303 #sql_thread執行主庫的master_log_file Slave_IO_Running: Yes #關鍵的,io_thread是否running Slave_SQL_Running: Yes #關鍵的,sql_thread是否running 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: 18711563 #sql_thread執行主庫的master_log_pos Relay_Log_Space: 18711908 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: 101 1 row in set (0.00 sec) |
2、IO_thread異常
IO_thread異常,狀態往往是Slave_IO_Running: Connecting 或NO。
IO_thread是向Master發送請求讀取master binlog,如果處於Connecting狀態,說明無法正確地與Master進行連接,可能的原因有:
a、網絡不通(是否打開防火牆)
b、複製用戶的密碼不對
c、指定的master_port端口不對
d、master上的mysql-bin.xxxxxx被誤刪
e、主庫磁盤空間滿了
通過show slave status\G可以看到相關錯誤信息,例如:
show slave status\G Last_IO_Errno: 2003 Last_IO_Error: error connecting to master '[email protected]:3306' - retry-time: 60 retries: 86400 |
或者通過錯誤日誌看到相關信息,如:
140828 15:47:20 [ERROR] Slave I/O: error connecting to master '[email protected]:3306' - retry-time: 60 retries: 86400, Error_code: 2003 140828 15:47:21 [Note] Event Scheduler: Loaded 0 events 140828 15:47:21 [Note] /home/mysql/mysql/bin/mysqld: ready for connections. |
3、sql_thread異常
sql_thread發生異常,狀態就會變爲Slave_SQL_Running: NO。
sql_thread發生異常的情況非常多,發生異常後,需要通過以下方法排查和解決:
a、對比主庫和從庫的二進制日誌的情況:
主庫: show master status\G File: mysql-bin.000303 Position: 18711563 |
從庫: show slave status\G Master_Log_File: mysql-bin.000303 --IO_thread Read_Master_Log_Pos: 18711563 --IO_thread Relay_Master_Log_File: mysql-bin.000303 --sql_thread Exec_Master_Log_Pos: 18711163 --sql_thread |
b、通過show slave status\G查看錯誤信息:
show slave status\G Last_SQL_Errno: 1062 Last_SQL_Error: Error 'Duplicate entry '1' for key 'PRIMARY'' on query. Default database: 'test'. Query: 'insert into test values(1,2,3,4,5,6)' |
c、 通過錯誤日誌查看錯誤信息:
140828 16:27:51 [ERROR] Slave SQL: Error 'Duplicate entry '1' for key 'PRIMARY'' on query. Default database: 'test'. Query: 'insert into test values(1,2,3,4,5,6)', Error_code: 1062 140828 16:27:51 [Warning] Slave: Duplicate entry '1' for key 'PRIMARY' Error_code: 1062 140828 16:27:51 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'mysql-bin.000303' position 18711163 |
根據這些報錯信息,往往就能夠定位到發生異常的原因。如果我們瞭解產生異常的具體事件,而且能夠掌控,可以通過設置sql_slave_skip_counter參數來跳過當前錯誤。
set global sql_slave_skip_counter=1; |
或者使用slave_skip_errors參數(read only variable),指定跳過某種類型的錯誤:
參數文件中設置: slave_skip_errors=1062 #跳過1062錯誤 |
遇到錯誤時,不要一通百度後,然後根據看起來很類似的操作直接來進行操作。因爲網上大部分解決sql_thread異常的方法是:
a、直接set global sql_slave_skip_counter=n; (n設置很大的值,即:跳過所有錯誤),
b、設置slave_skip_errors=all; 跳過所有類型的錯誤
c、直接查看主庫的binlog,然後在從庫上直接執行change master to。
這些方法都會導致主從數據不一致。
如果發現從庫與主庫差異太大,無法通過手動操作或數據修改重新建立同步。可以參考上述"MySQL主從複製搭建" 重新搭建從庫。
4、主從複製延遲
主從複製延遲,可能的原因有:
a、主從同步延遲與系統時間的關係,查看主從兩臺機器間系統時間差
b、主從同步延遲與壓力、網絡、機器性能的關係,查看從庫的io,cpu,mem及網絡 壓 力
c、主從同步延遲與lock鎖的關係(myisam表讀時會堵塞寫),儘量避免使用myisam 表。 一個實例裏面儘量減少數據庫的數量。
d、主從複製發生異常而中斷,過很久之後才發現複製異常。可通過查看master與slave的status估算相差的日誌。如果相差太大,則可以考慮重做從庫。
原文鏈接:http://blog.itpub.net/26355921/viewspace-1273303/
MySQL主從複製和讀寫分離 實現:http://jayluns.iteye.com/blog/2275690