pt-heartbeat是用來監控主從延遲的一款percona工具,現在我們大部分的MySQL架構還是基於主從複製,例如MHA,MMM,keepalived等解決方案。而主從環境的話,我們很關心的就是主從延遲的問題,一般情況下我們在從庫執行以下語句: mysql> show slave status ...
pt-heartbeat是用來監控主從延遲的一款percona工具,現在我們大部分的MySQL架構還是基於主從複製,例如MHA,MMM,keepalived等解決方案。而主從環境的話,我們很關心的就是主從延遲的問題,一般情況下我們在從庫執行以下語句:
mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.16.16.35 Master_User: root Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000016 Read_Master_Log_Pos: 299786938 Relay_Log_File: mxqmongodb2-relay-bin.000032 Relay_Log_Pos: 299787151 Relay_Master_Log_File: mysql-bin.000016 Slave_IO_Running: Yes Slave_SQL_Running: Yes 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: 299786938 Relay_Log_Space: 299787451 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: 353306 Master_UUID: 806ede0c-357e-11e7-9719-00505693235d Master_Info_File: mysql.slave_master_info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: 806ede0c-357e-11e7-9719-00505693235d:666-330347 Executed_Gtid_Set: 6a4ab82c-4029-11e7-86b0-00505693235d:1-3, 806ede0c-357e-11e7-9719-00505693235d:1-330347 Auto_Position: 1 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 1 row in set (0.00 sec)
就可以很明顯看得到主從的狀態,一般我們都會監控以下兩個進程的狀態確定主從延遲是否出現錯誤: Slave_IO_Running: Yes Slave_SQL_Running: Yes 對於主從延遲來說,我們可能監控最多的就是通過SMB(Seconds_Behind_Master)來監控,但是這個也並不是很靠譜的。或者我們通過監控Read_Master_Log_Pos-Exec_Master_Log_Pos的差值來看從庫是否有延遲,是否和主庫會有一定的延遲。但是這個也並不是很完美。首先看SMB,這個參數是怎麼比較出來的呢,SMB是通過將伺服器當前的時間戳與二進位日誌中的事件時間戳相對比得到的,而且是會產生誤報的情況。比如主庫執行一個大事物,時間執行很久,從庫接收以後對比時間戳發現已經延遲了,就會瞬間增大SMB的值。Read_Master_Log_Pos-Exec_Master_Log_Pos的值也並不是完全可靠。現在pt-heartbeat就能幫我們解決這個問題。 下麵我們來看一下pt-heartbeat的原理: pt-heartbeat會在master上創建一張表,按照一定的時間頻率更新該表的欄位,向該表寫入當前的時間戳,然後對比從庫的時間戳和pt-heartbeat所在機器的時間戳來判斷主從延遲。 其實這裡就有一個問題了,如果pt-heartbeat部署在從庫的話,要保證主從機器的時間是同步的,這個一般都是系統會每天自動對時間,是可以實現的。如果pt-heartbeat部署在主庫就不會有這個問題。其實個人感覺比較好的方法就是對比主從兩個庫的這張表的時間戳來得出延遲更為靠譜一點,當然這也要考慮到主從查詢的問題。 下麵看一下基本的用法: 先創建表:
[root@mxqmongodb2 bin]# ./pt-heartbeat --host=172.16.16.35 --port=3306 --user=root --password=123456 --database=test --update --create-table --daemonize
看一下表結構:
mysql> desc heartbeat; +-----------------------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-----------------------+---------------------+------+-----+---------+-------+ | ts | varchar(26) | NO | | NULL | | | server_id | int(10) unsigned | NO | PRI | NULL | | | file | varchar(255) | YES | | NULL | | | position | bigint(20) unsigned | YES | | NULL | | | relay_master_log_file | varchar(255) | YES | | NULL | | | exec_master_log_pos | bigint(20) unsigned | YES | | NULL | | +-----------------------+---------------------+------+-----+---------+-------+ 6 rows in set (0.01 sec) mysql> select * from heartbeat\G *************************** 1. row *************************** ts: 2017-06-23T09:27:49.001580 server_id: 353306 file: mysql-bin.000016 position: 299837221 relay_master_log_file: NULL exec_master_log_pos: NULL 1 row in set (0.00 sec)
具體看一下,我們看一下資料庫的鏈接,發現有一個更新操作:
UPDATE `test`.`heartbeat` SET ts='2017-06-23T09:32:47.001330', file='mysql-bin.000016', position='29
其實下麵的操作只是開啟了一個進程,對heartbeat表不停的進行更新,以獲取最新的數據。
[root@mxqmongodb2 bin]# ./pt-heartbeat --host=172.16.16.35 --port=3306 --user=root --password=123456 --database=test --update --daemonize
接下來我們開啟監控進程,這個是不停的刷新的:
[root@mxqmongodb2 bin]# ./pt-heartbeat -D test --monitor -h 172.16.16.34 -uroot -P3306 -p123456 0.00s [ 0.00s, 0.00s, 0.00s ] 0.00s [ 0.00s, 0.00s, 0.00s ] 0.00s [ 0.00s, 0.00s, 0.00s ] 0.00s [ 0.00s, 0.00s, 0.00s ] 0.00s [ 0.00s, 0.00s, 0.00s ]
我們指定會發現是沒有延遲的,我們現在開啟壓測,再觀察一下:
[root@mxqmongodb2 tpcc-mysql]# ./tpcc_start -h127.0.0.1 -P3306 -d tpcc -u root -p123456 -w 10 -c 20 -r 10 -l 600
觀察延遲的情況:
0.71s [ 0.68s, 0.16s, 0.05s ] 1.71s [ 0.71s, 0.17s, 0.06s ] 0.85s [ 0.72s, 0.17s, 0.06s ] 0.93s [ 0.74s, 0.18s, 0.06s ] 0.00s [ 0.74s, 0.18s, 0.06s ] 0.82s [ 0.73s, 0.18s, 0.06s ] 0.66s [ 0.75s, 0.18s, 0.06s ] 0.00s [ 0.75s, 0.18s, 0.06s ] 0.88s [ 0.74s, 0.18s, 0.06s ] 1.00s [ 0.74s, 0.19s, 0.06s ]
我們可以看到延遲情況,我們可以把這些輸出結果重定向到一個文件,對主從延遲進行監控,這也是很有效果的。 我們現在手動再從庫停掉sql_thread:
mysql> stop slave sql_thread; Query OK, 0 rows affected (0.03 sec)
然後再看輸出結果:
53.00s [ 23.85s, 6.77s, 4.20s ] 54.00s [ 24.75s, 6.94s, 4.26s ] 55.00s [ 25.67s, 7.12s, 4.32s ] 56.00s [ 26.60s, 7.30s, 4.39s ] 57.00s [ 27.55s, 7.48s, 4.45s ] 58.00s [ 28.52s, 7.67s, 4.51s ] 59.00s [ 29.50s, 7.86s, 4.58s ] 60.00s [ 30.50s, 8.05s, 4.65s ] 61.00s [ 31.50s, 8.23s, 4.71s ] 62.00s [ 32.50s, 8.42s, 4.78s ] 63.00s [ 33.50s, 8.61s, 4.85s ] 64.00s [ 34.50s, 8.80s, 4.92s ] 65.00s [ 35.50s, 8.98s, 5.00s ]
發現是不停的遞增的,一次間隔時間為一秒鐘。我們再啟動這個sql_thread,從庫很快就跟上了主庫。 或者我們可以通過下麵進行監控:
[root@mxqmongodb2 bin]# ./pt-heartbeat -D test --check -h 172.16.16.34 -uroot -P3306 -p123456 1.00 [root@mxqmongodb2 bin]# ./pt-heartbeat -D test --check -h 172.16.16.34 -uroot -P3306 -p123456 0.00
他是會直接返回一個延遲的秒數,這個也是比較靠譜的。我們可以直接拿這個值進行監控。