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 '^$' |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。
以上就是今天的內容,希望讀者朋友看完這篇文章后有所啟發。