不要用SECONDS_BEHIND_MASTER來衡量MYSQL主備的延遲時間,原因如下:
A:備庫Seconds_behand_master值是通過將服務器當前的時間戳與二進制日志中的事件的時間戳對比得到的,所以只有在執行事件時才能報告延遲
B:如果備庫復制線程沒有運行,就會報延遲為null
C:一些錯誤,如主備的max_allowed_packet不匹配或者網絡不穩定時,可能中斷復制或者停止復制線程,但Seconds_behand_master將顯示為0而不是顯示錯誤
D:即使備庫線程正在運行,備庫有時候可能無法計算延遲時,如果發生這種情況,備庫會報0或者null
E:一個較大的事務可能導致延遲波動,如:有一個事務更新數據長達一個小時,最后提交,這條更新將比它實際發生時間要晚一個小時才記錄到二進制日志中,當備庫執行這條語句時,會臨時地報告備庫延遲一個小時,然后很快又變回0
F:如果分發主庫落后了,並且其本身也有已經追趕上它的備庫,備庫的延遲將顯示為0,而事實上備庫和源主庫之間此時是有延遲的。
解決這些問題的辦法是忽略這個值,並使用一些可以直接觀察和衡量的方式來監控備庫延遲,最好的解決辦法是使用heartbeat record,這是一個在主庫上每秒更新一次的時間戳,為了計算延遲,可以直接用備庫當前的時間戳減去心跳記錄的值,這個方法能夠解決剛剛提到的所有問題,另外一個額外的好處是我們還可以通過時間戳知道備庫當前的復制狀況,包含在percona toolkit里的pt-heartbeat腳本是復制心跳的最流行的一種實現。
心跳還有其他好處,記錄在二進制日志中的心跳記錄擁有許多用途,如:在一些很難解決的場景下可以用於災難恢復。
pt-heartbeat介紹:
工作原理:
1,在主上創建一張heartbeat表,按照一定的時間頻率更新該表的字段(把時間更新進去)。
2,從主庫連接到從上檢查復制的時間記錄,和從庫的當前系統時間進行比較,得出時間的差異。
使用方法:
shell > pt-heartbeat [OPTIONS] [DSN] --update|--monitor|--check|--stop
在主庫上創建一個測試庫,測試庫里創建好heartbeat表,然后開啟守護進程來更新xiaoboluo.heartbeat表:
mysql > create database xiaoboluo;
mysql > CREATE TABLE heartbeat (
ts varchar(26) NOT NULL,
server_id int unsigned NOT NULL PRIMARY KEY,
file varchar(255) DEFAULT NULL, -- SHOW MASTER STATUS
position bigint unsigned DEFAULT NULL, -- SHOW MASTER STATUS
relay_master_log_file varchar(255) DEFAULT NULL, -- SHOW SLAVE STATUS
exec_master_log_pos bigint unsigned DEFAULT NULL -- SHOW SLAVE STATUS
);
shell > pt-heartbeat -D xiaoboluo --update -h localhost --user=username --password=password --daemonize
在主庫上監控從的延遲情況:
shell > pt-heartbeat -D xiaoboluo --monitor -h slave-server #一直執行,不退出pt-heartbeat -D xiaoboluo --check h=slave-server #執行一次就退出
常用參數:
注意:需要指定的參數至少有 --stop,--update,--monitor,--check。其中--update,--monitor和--check是互斥的,--daemonize和--check也是互斥。
--ask-pass 隱式輸入MySQL密碼 --charset 字符集設置 --check 檢查從的延遲,檢查一次就退出,除非指定了--recurse會遞歸的檢查所有的從服務器。 --check-read-only 如果從服務器開啟了只讀模式,該工具會跳過任何插入。 --create-table 在主上創建心跳監控的表,如果該表不存在。可以自己建立,建議存儲引擎改成memory。通過更新該表知道主從延遲的差距。 CREATE TABLE heartbeat ( ts varchar(26) NOT NULL, server_id int unsigned NOT NULL PRIMARY KEY, file varchar(255) DEFAULT NULL, -- SHOW MASTER STATUS position bigint unsigned DEFAULT NULL, -- SHOW MASTER STATUS relay_master_log_file varchar(255) DEFAULT NULL, -- SHOW SLAVE STATUS exec_master_log_pos bigint unsigned DEFAULT NULL -- SHOW SLAVE STATUS
);
heratbeat表一直在更改ts和position,而ts是我們檢查復制延遲的關鍵。
--daemonize
執行時,放入到后台執行
--user
-u,連接數據庫的帳號
--database
-D,連接數據庫的名稱
--host
-h,連接的數據庫地址
--password
-p,連接數據庫的密碼
--port
-P,連接數據庫的端口
--socket
-S,連接數據庫的套接字文件
--file 【--file=output.txt】
打印--monitor最新的記錄到指定的文件,很好的防止滿屏幕都是數據的煩惱。
--frames 【--frames=1m,2m,3m】
在--monitor里輸出的[]里的記錄段,默認是1m,5m,15m。可以指定1個,如:--frames=1s,多個用逗號隔開。可用單位有秒(s)、分鍾(m)、小時(h)、天(d)。
--interval
檢查、更新的間隔時間。默認是見是1s。最小的單位是0.01s,最大精度為小數點后兩位,因此0.015將調整至0.02。
--log
開啟daemonized模式的所有日志將會被打印到制定的文件中。
--monitor
持續監控從的延遲情況。通過--interval指定的間隔時間,打印出從的延遲信息,通過--file則可以把這些信息打印到指定的文件。
--master-server-id
指定主的server_id,若沒有指定則該工具會連到主上查找其server_id。
--print-master-server-id
在--monitor和--check 模式下,指定該參數則打印出主的server_id。
--recurse
多級復制的檢查深度。模式M-S-S...不是最后的一個從都需要開啟log_slave_updates,這樣才能檢查到。
--recursion-method
指定復制檢查的方式,默認為processlist,hosts。
--update
更新主上的心跳表。
--replace
使用--replace代替--update模式更新心跳表里的時間字段,這樣的好處是不用管表里是否有行。
--stop
停止運行該工具(--daemonize),在/tmp/目錄下創建一個“pt-heartbeat-sentinel” 文件。后面想重新開啟則需要把該臨時文件刪除,才能開啟(--daemonize)。
--table
指定心跳表名,默認heartbeat。
測試環境:
Master 192.168.0.68:3306
Slave 192.168.0.38:3306
1,在主上運行:--daemonize表示守護進程,后台運行。
[root@xiaoboluo_192.168.0.68 ~]# pt-heartbeat --user=root --ask-pass --host=127.0.0.1 --create-table -D xiaoboluo --interval=1 --update --replace --daemonize
Enter password:
[root@xiaoboluo_192.168.0.68 ~]#
[root@xiaoboluo_192.168.0.68 ~]# pgrep -fl pt-heartbeat4156perl /usr/bin/pt-heartbeat -D xiaoboluo --table=heartbeat --create-table --update -h 127.0.0.1 -uroot --ask-pass --daemonize
[root@xiaoboluo_192.168.0.68 ~]#
3.在主上運行監測復制延遲
[root@xiaoboluo_192.168.0.68 ~]# pt-heartbeat -D xiaoboluo --table=heartbeat --monitor -h 192.168.0.68
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 ]
0表示從沒有延遲。 [ 0.00s, 0.00s, 0.00s ] 表示1m,5m,15m的平均值。可以通過--frames去設置。
我們這里看見復制沒有延遲,那么我們可以使用壓力工具測試一下(這里因為是虛擬機做測試,性能比較差,所以直接使用存儲過程循環插入數據做測試了)。在主庫創建測試數據庫sbtest,隨便創建一個測試表:sbtest;
mysql>create database sbtest;
Query OK, 1 row affected (0.00 sec)
mysql>create table sbtest(id int unsigned not null auto_increment primary key,test varchar(20));
創建存儲過程:
mysql > delimiter $$
再次檢測復制延時:
[root@xiaoboluo_192.168.0.68 ~]# pt-heartbeat -D xiaoboluo --table=heartbeat --monitor -h 192.168.0.38
1.07s [ 0.11s, 0.02s, 0.01s ]
我們還可以使用--check監測一次就退出:
[root@xiaoboluo_192.168.0.68 ~]# pt-heartbeat -D xiaoboluo --table=heartbeat --check -h 192.168.0.38
0.00
[root@xiaoboluo_192.168.0.68 ~]#
注意:如果想把這個輸出結果加入自動化監控,那么可以使用如下命令使監控輸出寫到文件,然后使用腳本定期過濾文件中的最大值作為預警即可:
echo "$max_time"
2,如何關閉主上面執行的后台進程。可以用參數--stop 去關閉:
[root@xiaoboluo_192.168.0.68 ~]# pt-heartbeat --stop #注意,這個命令會把所有的pt-heartbeat進程都停掉
Successfully created file /tmp/pt-heartbeat-sentinel
[root@xiaoboluo_192.168.0.68 ~]#
這樣就把在主上開啟的進程殺掉了,后續要繼續開啟后台進行的話,需要把/tmp/pt-heartbeat-sentinel 文件刪除,否則啟動不了