前言
MySQL同步功能由3個線程(master上1個,slave上2個)來實現,簡單的說就是:master發送日志一個,slave接收日志一個,slave運行日志一個。
主從延遲判斷的方法,通常有兩種方法:Seconds_Behind_Master和pt-heartbeat
1.Seconds_Behind_Master
通過監控show slave status\G命令輸出的Seconds_Behind_Master參數的值來判斷,是否有發生主從延時。
mysql> show slave status\G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: Master_User: Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000022 Read_Master_Log_Pos: 879720441 Relay_Log_File: ***-relay-bin.000011 Relay_Log_Pos: 250520472 Relay_Master_Log_File: mysql-bin.000022 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: retail 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: 879720441 Relay_Log_Space: 565133487 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: 2 1 row in set (0.00 sec)
解釋一下 show slave status 中重要的幾個參數:
Slave_IO_Running: I/O線程是否被啟動並成功地連接到主服務器上。
Slave_SQL_Running: SQL線程是否被啟動。
Seconds_Behind_Master:其值可能為NULL、0、大於0
Seconds_Behind_Master
的計算規則是:從庫當前的時間戳 - 從庫SQL線程當前正在執行的事件記錄的主庫的時間戳
- 當從庫sql線程上沒有事件被執行時,
Seconds_Behind_Master
的值為0,表示主從復制良好,可以認為延遲不存在。 Seconds_Behind_Master
有可能為NULL值,當SQL線程或IO線程沒有在執行,或者IO線程在執行但連不上主庫時。
1.1.Seconds_Behind_Master可能帶來的問題:
我們都知道的relay-log和主庫的bin-log里面的內容完全一樣,在記錄sql語句的同時會被記錄上當時的ts,所以比較參考的值來自於binlog,其實主從沒有必要與NTP進行同步,也就是說無需保證主從時鍾的一致。你也會發現,其實比較真正是發生在io_thread與sql_thread之間,而io_thread才真正與主庫有關聯,於是,問題就出來了,當主庫I/O負載很大或是網絡阻塞,io_thread不能及時復制binlog(沒有中斷,也在復制),而sql_thread一直都能跟上io_thread的腳本,這時Seconds_Behind_Master的值是0,也就是我們認為的無延時,但是,實際上不是,你懂得。這也就是為什么大家要批判用這個參數來監控數據庫是否發生延時不准的原因,但是這個值並不是總是不准,如果當io_thread與master網絡很好的情況下,那么該值也是很有價值的。之前,提到Seconds_Behind_Master這個參數會有負值出現,我們已經知道該值是io_thread的最近跟新的ts與sql_thread執行到的ts差值,前者始終是大於后者的,唯一的肯能就是某個event的ts發生了錯誤,比之前的小了,那么當這種情況發生時,負值出現就成為可能。
2.pt-heartbeat
其工作原理為:
- 在主庫上創建一張表,然后由一個進程間隔一定時間不斷地去更新這張表記錄的當前主庫的時間戳
- 由另一個進程間隔一定時間不斷地去從庫查詢這張表記錄的主庫時間戳,再跟當前時間戳相減得到主從復制的延遲