一、mysql主從延遲的判斷指標
方法一:延遲時間
Seconds_Behind_Master: 0 此值作為監控主從延遲不是那么准確,此值計算的是主庫的binlog的時間和從庫的執行relay log的時間差,如果主從存在很大的網絡延遲,那么這個值就不是那么的准確,可以參考如下鏈接
https://www.sohu.com/a/317335842_610509
方法二: 主庫: mysql> show master status ;
從庫: [root@db01 data]# mysql -e "show slave status \G"|grep "Master_Log" 已經拿到的主庫日志量(master.info):判斷傳輸有沒有延時 Master_Log_File: mysql-bin.000004 Read_Master_Log_Pos: 151847
已經執行的主庫日志(relay-log.info): 判斷回放有沒有延時 Relay_Master_Log_File: mysql-bin.000004 Exec_Master_Log_Pos: 141847
計算主從復制延時日志量。
從庫執行判斷腳本(得出的值為Read_Master_Log_Pos-Exec_Master_Log_Pos的值,單位為KB,可以監控此值來判斷延遲多少數據量)
/usr/local/mysql/bin/mysql -uroot -pxxxxxx -e "show slave status \G" 2>/dev/null|grep "Master_Log"|awk '{print $2}'|sed -n '2p;4p'|awk 'NR==1 {tmp=$1} NR>1 {print tmp-$1;tmp=$1}'
二、延遲原因排查
1.主庫原因分析
binlog記錄不及時,表現形式就是主庫的show master的gtid大於slave接受的gtid號,有可能主庫的IO壓力太大,主庫dump線程壓力太大,也有可能網絡延遲嚴重,在向從庫同步binlog的時候,速度有延遲。
解決:可以降低雙一標准,提高IO和網絡延遲
例如如下:
mysql> select @@sync_binlog;
+---------------+
|@@sync_binlog |
+---------------+
| 1 |
+---------------+
參數說明:
1 : 每次事務提交都立即刷新binlog到磁盤。
0 : 由操作系統決定,什么刷新磁盤。
sync_binlog:這個參數是對於MySQL系統來說是至關重要的,他不僅影響到Binlog對MySQL所帶來的性能損耗,而且還影響到MySQL中數據的完整性。對於“sync_binlog”參數的各種設置的說明如下:
sync_binlog=0,當事務提交之后,MySQL不做fsync之類的磁盤同步指令刷新binlog_cache中的信息到磁盤,而讓Filesystem自行決定什么時候來做同步,或者cache滿了之后才同步到磁盤。
sync_binlog=n,當每進行n次事務提交之后,MySQL將進行一次fsync之類的磁盤同步指令來將binlog_cache中的數據強制寫入磁盤。
在MySQL中系統默認的設置是sync_binlog=0,也就是不做任何強制性的磁盤刷新指令,這時候的性能是最好的,但是風險也是最大的。因為一旦系統Crash,在binlog_cache中的所有binlog信息都會被丟失。而當設置為“1”的時候,是最 安全但是性能損耗最大的設置。因為當設置為1的時候,即使系統Crash,也最多丟失binlog_cache中未完成的一個事務,對實際數據沒有任何實質性影響。
從以往經驗和相關測試來看,對於高並發事務的系統來說,“sync_binlog”設置為0和設置為1的系統寫入性能差距可能高達5倍甚至更多。
show variables like 'sync_binlog';
set global sync_binlog=0;
***優化方式***:
調整雙一標准:
sync_binlog=n
innodb_flush_log_at_trx_commit=2
調整數據庫事務隔離級別為RC:
select @@tx_isolation; 查看當前的隔離級別
set global tx_isolation = 'READ-COMMITTED' 在線調整隔離級別
set session transaction isolation level read committed;設置當前事務的隔離級別
永久生效:修改/etc/my.cnf
transaction-isolation = READ-COMMITTED
參考如下鏈接:
https://blog.csdn.net/weixin_30800151/article/details/113196750
2.從庫原因分析
# IO線程:
從庫IO比較慢。relay 落地慢。可以將realy放到 SSD
# SQL 線程: 串行回放。
從庫串行回放的條件:
主庫開啟組提交,只有主庫在同一個commit組提交的事務從庫的SQL線程才可以並行回放。
主庫開啟組提交的方式:
https://www.cnblogs.com/liuxiuxiu/p/12720242.html
主庫可以並行事務,從庫SQL線程串行回放。
所以:並發事務高、大事務、DDL
解決方法: 5.6 版本: 開啟GTID后,可以多SQL線程,只能針對不同的庫的事務進行並行SQL恢復。
5.7 版本: 做了增強,基於邏輯時鍾的並行回放。MTS。 LAST_COMMIT(BINLOG_GROUP_COMMIT) SEQ_NUM.
5.7 的從庫並發配置方法。
gtid_mode=ON
enforce_gtid_consistency=ON
log_slave_updates=ON
slave-parallel-type=LOGICAL_CLOCK
slave-parallel-workers=4
master_info_repository=TABLE
relay_log_info_repository=TABL
3. 從庫延遲sql線程卡在某個Gtid上不向下執行,可能是從主庫上同步的大的事務,執行時間比較久,判斷是什么事務的方式:
1)mysql> show slave status\G 查看目前sql線程執行的事務對應的主庫的binlog的GTID
2)mysql> show slave status\G 查看目前sql線程執行的事務對應的從庫的的relay log的GTID
如果剛好卡在某個事務不動了,可以通過在主庫上:
mysqlbinlog --no-defaults --base64-output=decode-rows -vv mysql-bin.000311 >/tmp/171.sql 找到對應的gtid 比如上圖的166523036,看看是什么大事物導致的
或者:
在從庫上:
mysqlbinlog --no-defaults --base64-output=decode-rows -vv redmine_slave-relay-bin.000618 >/tmp/171.sql 找到對應的gtid 比如上圖的17929872,看看是什么大事物導致的
也可以show processlist看看是否有什么sql在跑。