前幾天跟幾我的討論到MySQL監控這塊。發現自身有所欠缺,因此最近加班加點研究了一下。寫個博文總結一下。mysql
通常來講對於mysql監控,會監控主庫、從庫的可用性。主從複製狀態監控、數據庫性能監控、數據庫日誌監控。sql
對於可用性的監控,能夠經過按期去執行sql實現。這裏須要注意的是主庫須要監控可寫入性。數據庫
數據庫性能的監控,就是去監控數據庫的一些狀態值,對這些狀態進行直接、間接(不一樣狀態值計算)的監控。這個須要對mysql的一些參數有詳細的瞭解。服務器
重點來講說mysql複製監控這塊:網絡
不少人都知道能夠經過監控show slave status\G命令輸出的Seconds_Behind_Master參數的值來判斷,是否有發生主從延時。性能
同時不少人也知道這個不許確,可是爲何不許確呢????線程
首先來看看show slave status\G重點項:日誌
Seconds_Behind_Master計算方式:接口
是經過比較sql_thread執行的event的timestamp和io_thread複製好的event的timestamp(簡寫爲ts)進行比較,而獲得的這麼一個差值。事件
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發生了錯誤,比以前的小了,那麼當這種狀況發生時,負值出現就成爲可能。
因此簡單點說,當IO線程有延遲的時候Seconds_Behind_Master這個值是不許的。
那麼如何正確查看以及監控MySQL主從?
一、根據主從POS點比較
二、在主庫創建監控表(心跳),定時寫入(帶時間戳)。去從庫中查詢對應的記錄,就能夠依據記錄內的時間戳信息來確認延時了多少。
第二種方式單獨細說。
詳細說下第一種:
先說下主從查看延遲的流程。
在監控節點上,對MASTER和slave同時發起SHOW BINARY LOGS和SHOW slave STATUS\G的請求,最後判斷兩者binlog的差別,以及 Exec_Master_Log_Pos 和Read_Master_Log_Pos 的差別。
例如:
在MASTER上執行SHOW BINARY LOGS 的結果是:
+------------------+--------------+
| Log_name | File_size |
+------------------+--------------+
| mysql-bin.000009 | 1073742063 |
| mysql-bin.000010 | 107374193 |
+------------------+--------------+
而在slave上執行SHOW slave STATUS\G 的結果是:
Master_Log_File: mysql-bin.000009
Read_Master_Log_Pos: 668711237
Relay_Master_Log_File: mysql-bin.000009
slave_IO_Running: Yes
slave_SQL_Running: Yes
***
Exec_Master_Log_Pos: 654409041
***
Seconds_Behind_Master: 3296
***
這時候,slave實際的延遲應該是:
mysql-bin.000009 這個binlog中的binlog position 1073742063 和 slave上讀取到的binlog position之間的差別延遲,即:
1073742063 - 654409041 = 419333022 個binlog event
而且還要加上 mysql-bin.000010這個binlog已經產生的107374193個binlog event,共
107374193 + 419333022 = 526707215 個binlog event
附:
Slave_IO_State:等待 master 發生事件
Master_Host:當前的主服務器主機
Master_User:被用於鏈接主服務器的當前用戶
Master_Port:當前的主服務器接口
Connect_Retry:master-connect-retry選項的當前值
Master_Log_File:I/O線程當前正在讀取的主服務器二進制日誌文件的名稱
Read_Master_Log_Pos:在當前的主服務器二進制日誌中,I/O線程已經讀取的位置
Relay_Log_File:SQL線程當前正在讀取和執行的中繼日誌文件的名稱
Relay_Log_Pos:在當前的中繼日誌中,SQL線程已讀取和執行的位置
Relay_Master_Log_File:由SQL線程執行的包含多數近期事件的主服務器二進制日誌文件的名稱
Slave_IO_Running:I/O線程是否被啓動併成功地鏈接到主服務器上
Slave_SQL_Running:SQL線程是否被啓動
Replicate_Do_DB:replicate-do-db選項的當前值
Replicate_Ignore_DB:replicate-ignore-db選項的當前值
Replicate_Do_Table:replicate-do-table選項的當前值
Replicate_Ignore_Table:replicate-ignore-table選項的當前值
Replicate_Wild_Do_Table:replicate-wild-do-table選項的當前值
Replicate_Wild_Ignore_Table:replicate-wild-ignore_table選項的當前值
Last_Errno:最近一次錯誤碼
Last_Error:最近一次錯誤內容
Skip_Counter:最近被使用的用於SQL_SLAVE_SKIP_COUNTER的值
Exec_Master_Log_Pos:來自主服務器的二進制日誌的由SQL線程執行的上一個時間的位置(Relay_Master_Log_File)。在主服務器的二進制日誌中的(Relay_Master_Log_File,Exec_Master_Log_Pos)對應於在中繼日誌中的(Relay_Log_File,Relay_Log_Pos)
Relay_Log_Space:全部原有的中繼日誌結合起來的總大小
Until_Condition:若是沒有指定UNTIL子句,則沒有值。若是從屬服務器正在讀取,直到達到主服務器的二進制日誌的給定位置爲止,則值爲Master。若是從屬服務器正在讀取,直到達到其中繼日誌的給定位置爲止,則值爲Relay
Until_Log_File:用於指示日誌文件名,日誌文件名和位置值定義了SQL線程在哪一個點停止執行
Until_Log_Pos:用於指示日誌位置值,日誌文件名和位置值定義了SQL線程在哪一個點停止執行
Master_SSL_Allowed:若是容許對主服務器進行SSL鏈接,則值爲Yes。若是不容許對主服務器進行SSL鏈接,則值爲No。若是容許SSL鏈接,可是從屬服務器沒有讓SSL支持被啓用,則值爲Ignored。
Master_SSL_CA_File:master-ca選項的當前值
Master_SSL_CA_Path:master-capath選項的當前值
Master_SSL_Cert:master-cert選項的當前值
Master_SSL_Cipher:master-cipher選項的當前值
Master_SSL_Key:master-key選項的當前值
Seconds_Behind_Master:本字段是從屬服務器「落後」多少的一個指示。當從屬SQL線程正在運行時(處理更新),本字段爲在主服務器上由此線程執行的最近的一個事件的時間標記開始,已通過的秒數。當此線程被從屬服務器I/O線程遇上,並進入閒置狀態,等待來自I/O線程的更多的事件時,本字段爲零。總之,本字段測量從屬服務器SQL線程和從屬服務器I/O線程之間的時間差距,單位以秒計。若是主服務器和從屬服務器之間的網絡鏈接較快,則從屬服務器I/O線程會很是接近主服務器,因此本字段可以十分近似地指示,從屬服務器SQL線程比主服務器落後多少。若是網絡較慢,則這種指示不許確;從屬SQL線程常常會遇上讀取速度較慢地從屬服務器I/O線程,所以,Seconds_Behind_Master常常顯示值爲0。即便I/O線程落後於主服務器時,也是如此。換句話說,本列只對速度快的網絡有用。即便主服務器和從屬服務器不具備相同的時鐘,時間差計算也會起做用(當從屬服務器I/O線程啓動時,計算時間差。並假定今後時之後,時間差保持不變)。若是從屬SQL線程不運行,或者若是從屬服務器I/O線程不運行或未與主服務器鏈接,則Seconds_Behind_Master爲NULL(意義爲「未知」)。舉例說明,若是在從新鏈接以前,從屬服務器I/O線程休眠了master-connect-retry秒,則顯示NULL,由於從屬服務器不知道主服務器正在作什麼,也不能有把握地說落後多少。本字段有一個限制。時間標記經過複製被保留,這意味着,若是一個主服務器M1自己是一個從屬服務器M0,則來自M1的binlog的任何事件(經過複製來自M0的binlog的事件而產生),與原事件具備相同的時間標記。這可使MySQL成功地複製TIMESTAMP。可是,Seconds_Behind_Master的缺點是,若是M1也收到來自客戶端的直接更新,則值會隨機變化,由於有時最近的M1時間來自M0,有時來自直接更新,最近的時間標記也是如此。