天天看點

關于使用pt-heartbeat監測MySQL主從複制延遲的方法

作者:mj談雲技術

pt-heartbeat的工作原理通過使用時間戳方式在主庫上更新特定表,然後在從庫上讀取被更新特定表裡的時間戳,再與本地系統時間對比來得出其延遲。

具體流程:

1)在主庫上建立一張heartbeat表,按照一定的時間頻率更新該表的字段(把時間更新); 監控操作運作後,heartbeat表能促使主從同步。

2)連接配接到從庫上檢查複制的時間記錄,和從庫的目前系統時間進行比較,得出時間的差異。

一、使用方法(主從和從庫上都可以執行監控操作):

pt-heartbeat [OPTIONS] [DSN] —update | —monitor | —check | —stop

注意:需要指定的參數至少有 --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,
position              bigint unsigned DEFAULT NULL,
relay_master_log_file varchar(255) DEFAULT NULL,
exec_master_log_pos   bigint unsigned DEFAULT NULL
);
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,5m,15m] 在--monitor裡輸出的[]裡的記錄段,預設是1m,5m,15m。可以指定1個;如:--frames=1s,多個用逗号隔開。可用機關有秒(s)、分鐘(m)、小時(h)、天(d)。
--interval 檢查、更新的間隔時間。預設是見是1s。最小的機關是0.01s,最大精度為小數點後兩位,是以0.016将自動調整至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。           

二、示範使用pt-heartbeat

# --master-server-id參數(主庫my.cnf裡配置的server-id值)
a、首先添加表
# pt-heartbeat --user=root --password=pwd -S /tmp/mysql.sock -D test --master-server-id=1 --create-table --update
MASTER> select * from heartbeat;
+----------------------------+-----------+------------------+-----------+-----------------------+---------------------+
| ts | server_id | file             | position  | relay_master_log_file | exec_master_log_pos |
+----------------------------+-----------+------------------+-----------+-----------------------+---------------------+
| 2022-09-22T09:48:14.003020 | 1 | mysql-bin.000391  | 677136957 | mysql-bin.000180      |                 120 |
+----------------------------+-----------+------------------+-----------+-----------------------+---------------------+
b、更新主庫上的heartbeat(背景運作)
# pt-heartbeat --user=root --password=pwd -S /tmp/mysql.sock -D test --master-server-id=1 --update &
[1] 31249
c、從庫上監控延遲
# pt-heartbeat --user=root --password=pwd -S /tmp/mysql.sock -D test --master-server-id=1 --monitor --print-master-server-id
1.00s [ 0.02s,  0.00s,  0.00s ] 1  #實時延遲: 1分鐘延遲,5分鐘延遲,15分鐘延遲
1.00s [ 0.03s,  0.01s,  0.00s ] 1  
1.00s [ 0.05s,  0.01s,  0.00s ] 1
1.00s [ 0.07s,  0.01s,  0.00s ] 1
1.00s [ 0.08s,  0.02s,  0.01s ] 1
1.00s [ 0.10s,  0.02s,  0.01s ] 1
1.00s [ 0.12s,  0.02s,  0.01s ] 1
1.00s [ 0.13s,  0.03s,  0.01s ] 1
d、其他操作示例
#将主庫上的update使用守護程序方式排程
# pt-heartbeat --user=root --password=pwd -S /tmp/mysql.sock -D test --master-server-id=1 --update --daemonize
#修改主庫上的更新間隔為2s
# pt-heartbeat --user=root --password=pwd -S /tmp/mysql.sock -D test --master-server-id=1 --update --daemonize --interval=2
#停止主庫上的pt-heartbeat守護程序
# pt-heartbeat --stop
Successfully created file /tmp/pt-heartbeat-sentinel
# rm -rf /tmp/pt-heartbeat-sentinel
#單次檢視從庫上的延遲情況
# pt-heartbeat --user=root --password=pwd -S /tmp/mysql.sock -D test --master-server-id=1 --check
1.00
#使用守護程序監控從庫并輸出日志
# pt-heartbeat --user=root --password=pwd -S /tmp/mysql.sock -D test --master-server-id=1 --monitor --print-master-server-id --daemonize --log=/tmp/slave-heart.log           

三、自動化監控

注意:
如果想把這個輸出結果加入自動化監控,那麼可以使用如下指令使監控輸出寫到檔案,然後使用腳本定期過濾檔案中的最大值作為預警即可:
注意--log選項必須在有--daemonize參數的時候才會列印到檔案中,且這個檔案的路徑最好在/tmp下,否則可能因為權限問題無法建立
# pt-heartbeat -D test --table=heartbeat --monitor --user=root --password=pwd --log=/opt/master-slave-delay.log --daemonize
[root@master-server ~]# tail -f /opt/master-slave-delay.txt //可以測試,在主庫上更新資料時,從庫上是否及時同步,如不同步,可以在這裡看到監控的延遲資料
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.00s [ 0.00s, 0.00s, 0.00s ]
.......
下面是編寫的主從同步延遲監控腳本,就是定期過濾--log檔案中最大值(此腳本運作的前提是:啟動更新主庫heartbeat指令以及帶上--log的同步延遲檢測指令)。如果發生延遲,發送報警。
# cat /root/check-slave-monitor.sh           
#!/bin/bash
cat /opt/master-slave-delay.log > /opt/master_slave_delay.log
echo -e > /opt/master-slave-delat.log
max_time=`cat /opt/master_slave_delay.log |grep -v '^#39; |awk '{print $1}' |sort -k1nr |head -1`
NUM=$(echo "$max_time"|cut -d"s" -f1)
if [ $NUM == "0.00" ];then
echo "MySQL主從同步延遲一緻"
else
echo "Mysql主從資料同步有延遲"
# TODO 這裡添加報警
fi           
結合crontab,每隔一分鐘檢查一次
# mysql主從同步延遲檢查
* * * * * /bin/bash -x /root/check-slave-monitor.sh > /dev/null 2>&1           

關閉上面在主庫上執行heartbeat的守護程序

方法一:可以用參數--stop去關閉
# pt-heartbeat --stop
Successfully created file /tmp/pt-heartbeat-sentinel
這樣就把在主上開啟的程序殺掉了。
但是後續要繼續開啟背景進行的話,記住一定要先把/tmp/pt-heartbeat-sentinel 檔案删除,否則啟動不了
方法二:直接kill掉程序pid(推薦這種方法)
#ps -ef|grep heartbeat
kill -9 15152           

最後總結:

通過pt-heartbeart工具可以很好地彌補預設主從延遲的問題,但需要搞清楚該工具的原理。

重點了:預設的Seconds_Behind_Master值是通過将伺服器目前的時間戳與二進制日志中的事件時間戳相對比得到的,是以隻有在執行事件時才能報告延遲。從庫複制線程沒有運作,也會報延遲。

還有一種情況:大事務,一個事務更新資料長達一個小時,最後送出。這條更新将比它實際發生時間要晚一個小時才記錄到二進制日志中。當從庫執行這條語句時,會臨時地報告備庫延遲為一個小時,執行完後又很快變成0。

以上就是今天的内容,希望讀者朋友看完這篇文章後有所啟發。

繼續閱讀