上篇文章介紹了單機環境下的MySQL主從異步複製和主從半同步複製的搭建過程。搭建過程很簡單,可是在實際使用過程當中,更多的是解決問題,本篇文章將介紹一下MySQL主從複製中常見的問題以及如何定位問題和如何解決問題。
1、從庫複製延遲問題mysql
一、可能的緣由以下
(1)主從服務器處於不一樣的網絡之中,因爲網絡延遲致使;
(2)主從服務器的硬件配置不一樣,從服務器的硬件配置(包括內存,CPU,網卡等)遠低於主服務器;
(3)主庫上有大量的寫入操做,致使從庫沒法實時重放主庫上的binlog;
(4)主庫上存在着大事務操做或者慢SQL,致使從庫在應用主庫binlog的過程過慢,造成延遲;
(5)數據庫實例的參數配置問題致使,如:從庫開啓了binlog,或者配置了每次事務都去作刷盤操做;sql
二、主從同步延遲問題判斷
(1)根據從庫上的狀態參數判斷數據庫
mysql-server-3307> SHOW SLAVE STATUS \G
在輸出結果中找到Seconds_Behind_Master參數,這個參數表示的是從庫上的IO線程和SQL線程相差的時間,而後根據該參數值判斷,這個值只是初步判斷,不能由這個值來下結論,有以下幾種狀況:
a、0:表示無延遲,理想狀態;
b、NULL:表示從庫上的IO線程和SQL線程中,有某一個線程出現問題,能夠再次查看Slave_IO_Running和Slave_SQL_Running的值是否都爲Yes;
c、大於0:表示主從已經出現延遲,這個值越大,表示從庫和主庫之間的延遲越嚴重;
d、小於0:這個值在官方文檔中沒有說明,一般不會出現。若是出現,那恭喜你中獎了,撞見MySQL的bug了;安全
(2)根據主從庫上面當前應用的二進制日誌文件名稱或者重放日誌的位置來判斷
① 同時打開兩個MySQL的命令行窗口,分別打開主庫和從庫,在第一個窗口上執行查看主庫當前狀態的命令服務器
mysql-server-3306> SHOW MASTER STATUS \G *************************** 1. row *************************** File: mysql-bin.000017 Position: 120 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 1 row in set (0.00 sec)
② 在第二個從庫的命令行窗口執行以下命令網絡
mysql-server-3307> SHOW SLAVE STATUS \G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event ... Connect_Retry: 60 Master_Log_File: mysql-bin.000017 Read_Master_Log_Pos: 120 Relay_Log_File: relay-log.000016 Relay_Log_Pos: 283 Relay_Master_Log_File: mysql-bin.000017 Slave_IO_Running: Yes Slave_SQL_Running: Yes ... Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 120 Relay_Log_Space: 613 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 ... Seconds_Behind_Master: 0 ... Replicate_Ignore_Server_Ids: Master_Server_Id: 3 Master_UUID: 2dbbf79b-5d9f-11e8-8004-000c29e28409 Master_Info_File: /mysql_data/3307/data/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL
③ 比較從庫上的Master_Log_File和Relay_Master_Log_File文件之間是否有差別
a、若是有差別,則說明主從延遲很嚴重;
b、若是沒有差別,則比較Read_Master_Log_Pos和Exec_Master_Log_Pos的差別,這倆參數分別表示從庫當前讀取到的主庫的二進制日誌文件位置點和已經執行到的位置點;
c、若是上述輸出都沒有差別,能夠經過主庫上"show master status"和從庫上"show slave status"的結果做比較。主要比較主庫的"File"和從庫的"Master_Log_File",主庫上的"Position"和從庫上的"Read_Master_Log_Pos";併發
三、主從延遲解決辦法
(1)判斷是否因爲網絡致使
方法:測試主從庫之間的網絡延遲,好比測試ping延遲。同時能夠檢查主從同步的時候是否使用了主庫的域名來同步,而域名解析速度可能會特別慢。或者使用其餘測試工具;
(2)判斷是否因爲硬件環境致使
方法:確認主從庫的硬件配置是否相差較大,若是配置參數相差較大,能夠排查從庫上的CPU,內存,IO使用率來判斷是否由於硬件配置致使;
(3)判斷是否在主庫上有大量的DML操做
方法:能夠再主庫上經過"show full processlist"命令查看當前正在執行的sql,查看是否有大量正在執行的SQL,或者觀察主庫的CPU和內存使用率,判斷是否有高併發操做;
(4)判斷是否有慢SQl,能夠再主庫上臨時打開慢SQL記錄,臨時打開方法以下異步
#開啓慢SQL功能並查看是否生效 mysql-server-3306> SET @@GLOBAL.slow_query_log = ON; mysql-server-3306> SHOW VARIABLES LIKE 'slow_query_log'; #設置慢SQL的時間並查看是否生效,單位爲s,表示大於多少秒的SQL會被記錄 mysql-server-3306> SET @@GLOBAL.long_query_time = 5; mysql-server-3306> SHOW VARIABLES LIKE 'long_query_time'; #設置慢SQL記錄日誌路徑並查看是否生效。注意,這個目錄必須對MySQL用戶有讀寫權限 mysql-server-3306> SET @@GLOBAL.slow_query_log_file = '/mysql_data/mysql-slow.log'; mysql-server-3306> SHOW VARIABLES LIKE 'slow_query_log_file';
(5)檢查從服務器參數配置是否合理
① 查看從庫是否開啓了binlog日誌,從庫上執行以下命令查看高併發
mysql-server-3307> SHOW VARIABLES LIKE 'log_bin';
若是開啓了binlog日誌,並且從庫未充當其餘庫的主庫時,能夠將從庫上的binlog關閉,不然會增長從庫負擔,每次重放完成主庫的binlog還要記錄到自身的binlog工具
② 查看從庫上的sync_binlog參數的值,這個參數表示的是事務提交多少次以後,由MySQL來將binlog_cache中的數據刷新到磁盤,有如下幾種值:
0:表示事務提交以後,MySQL不作刷新binlog_cache到磁盤的操做,而是由操做系統來定時自動完成刷盤操做,這種操做對性能損耗最少,可是也最不安全;
n:表示提交n次事務以後,由MySQL將binlog_cache中的數據刷新到磁盤,若是開啓,會對性能有必定程度的損耗。因此,從庫上若是延遲很嚴重,能夠考慮將該參數的值設爲0;
mysql-server-3307> SET @@GLOBAL.sync_binlog = 0; mysql-server-3307> SHOW VARIABLES LIKE 'sync_binlog'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | sync_binlog | 0 | +---------------+-------+ 1 row in set (0.00 sec)
③ 若是從庫中要同步的數據庫使用的是InnoDB存儲引擎,能夠查看innodb_flush_log_at_trx_commit參數。這個參數表示事務執行完成以後,多久的頻率刷新一第二天志到磁盤上,可用的值有以下幾種:
0:表示MySQL會將日誌緩衝區中的數據每秒一次地寫入日誌文件中,而且日誌文件的刷盤操做同時進行。該模式下在事務提交的時候,不會主動觸發寫入磁盤的操做,效率最搞,可是安全性也比較低,可能會丟失數據;
1:每一次事務提交都須要把日誌寫入磁盤,這個過程是特別耗時的操做;
2:每一次事務提交以後,不會自動觸發日誌刷盤的操做,而是由操做系統來決定何時來作刷新日誌的操做,在操做系統掛了的狀況下才會丟失數據;
若是在主從延遲很是嚴重的狀況下,能夠將從庫的該參數設置爲0,以提升從庫上重放主庫二進制日誌的效率。
mysql-server-3307> SET @@GLOBAL.innodb_flush_log_at_trx_commit = 0; mysql-server-3307> SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit'; +--------------------------------+-------+ | Variable_name | Value | +--------------------------------+-------+ | innodb_flush_log_at_trx_commit | 0 | +--------------------------------+-------+ 1 row in set (0.00 sec)
注意:上述設計到修改MySQL數據庫實例的操做中,修改以後會馬上生效,可是重啓實例以後,會失效,若是要永久修改,則須要編輯mysql配置文件,而後重啓。
至此,主從複製延遲的常見緣由就介紹完畢,還有更多其餘緣由須要實際問題實際解決,此處並未提到,歡迎你們評論提出!下篇文章將介紹MySQL數據庫的數據備份與恢復!
後續文章將更新在我的小站上,歡迎查看。