> 原文地址:http://imysql.com/2014/08/30/mysql-faq-howto-monitor-slave-lag.shtml
在MySQL復制環境中,我們通常只根據?Seconds_Behind_Master?的值來判斷SLAVE的延遲。這么做大部分情況下尚可接受,但并不夠準確,而應該考慮更多因素。
首先,我們先看下SLAVE的狀態:
~~~
yejr@imysql.com [(none)]> show slave status\G
*************************** 1\. row ***************************
Slave_IO_State: Waiting for master to send event
***
Master_Log_File: mysql-bin.000327
Read_Master_Log_Pos: 668711237
Relay_Log_File: mysql-relay-bin.002999
Relay_Log_Pos: 214736858
Relay_Master_Log_File: mysql-bin.000327
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
***
Skip_Counter: 0
Exec_Master_Log_Pos: 654409041
Relay_Log_Space: 229039311
***
Seconds_Behind_Master: 3296 ***
~~~
可以看到?Seconds_Behind_Master?的值是?3296,也就是SLAVE至少延遲了?3296?秒。
我們再來看下SLAVE上的2個REPLICATION進程狀態:
~~~
yejr@imysql.com [(none)]> show full processlist\G
*************************** 1\. row ***************************
Id: 6
User: system user
Host:
db: NULL
Command: Connect
Time: 22005006 State: Waiting for master to send event
Info: NULL
*************************** 2\. row ***************************
Id: 7
User: system user
Host:
db: NULL
Command: Connect
Time: 3293
State: Updating Info: UPDATE ** SET ** WHERE **
~~~
可以看到SQL線程一直在執行UPDATE操作,注意到 Time 的值是 3293,看起來像是這個UPDATE操作執行了3293秒,一個普通的SQL而已,肯定不至于需要這么久。
實際上,在REPLICATION進程中,Time 這列的值可能有幾種情況:
1、SQL線程當前執行的binlog(實際上是relay log)中的timestamp和IO線程最新的timestamp的差值,這就是通常大家認為的 Seconds_Behind_Master 值,并不是某個SQL的實際執行耗時;
2、SQL線程當前如果沒有活躍SQL在執行的話,Time值就是SQL線程的idle time;
而IO線程的Time值則是該線程自從啟動以來的總時長(多少秒),如果系統時間在IO線程啟動后發生修改的話,可能會導致該Time值異常,比如變成負數,或者非常大。
來看下面幾個狀態:
~~~
#設置pager,只查看關注的幾個status值
yejr@imysql.com [(none)]> pager cat | egrep -i 'system user|Exec_Master_Log_Pos|Seconds_Behind_Master|Read_Master_Log_Pos'
#這是沒有活躍SQL的情況,Time值是idle time,并且 Seconds_Behind_Master 為 0
yejr@imysql.com [(none)]> show processlist; show slave status\G
| 6 | system user | | NULL | Connect | 22004245 | Waiting for master to send event | NULL |
| 7 | system user | | NULL | Connect | 13 | Has read all relay log;**
Read_Master_Log_Pos: 445167889
Exec_Master_Log_Pos: 445167889
Seconds_Behind_Master: 0
#和上面一樣
yejr@imysql.com [(none)]> show processlist; show slave status\G
| 6 | system user | | NULL | Connect | 22004248 | Waiting for master to send event | NULL |
| 7 | system user | | NULL | Connect | 16 | Has read all relay log;**
Read_Master_Log_Pos: 445167889
Exec_Master_Log_Pos: 445167889
Seconds_Behind_Master: 0
#這時有活躍SQL了,Time值是和 Seconds_Behind_Master 一樣,即SQL線程比IO線程“慢”了1秒
yejr@imysql.com [(none)]> show processlist; show slave status\G
| 6 | system user | | NULL | Connect | 22004252 | Waiting for master to send event | NULL |
| 7 | system user | | floweradmin | Connect | 1 | Updating | update **
Read_Master_Log_Pos: 445182239
Exec_Master_Log_Pos: 445175263
Seconds_Behind_Master: 1
#和上面一樣
yejr@imysql.com [(none)]> show processlist; show slave status\G
| 6 | system user | | NULL | Connect | 22004254 | Waiting for master to send event | NULL |
| 7 | system user | | floweradmin | Connect | 1 | Updating | update **
Read_Master_Log_Pos: 445207174
Exec_Master_Log_Pos: 445196837
Seconds_Behind_Master: 1
~~~
好了,最后我們說下如何正確判斷SLAVE的延遲情況:
1、首先看?Relay_Master_Log_File?和?Master_Log_File?是否有差異;
2、如果Relay_Master_Log_File?和?Master_Log_File?是一樣的話,再來看Exec_Master_Log_Pos?和?Read_Master_Log_Pos?的差異,對比SQL線程比IO線程慢了多少個binlog事件;
3、如果Relay_Master_Log_File?和?Master_Log_File?不一樣,那說明延遲可能較大,需要從MASTER上取得binlog status,判斷當前的binlog和MASTER上的差距;
因此,相對更加嚴謹的做法是:
在第三方監控節點上,對MASTER和SLAVE同時發起SHOW BINARY LOGS和SHOW SLAVE STATUS\G的請求,最后判斷二者binlog的差異,以及?Exec_Master_Log_Pos?和?Read_Master_Log_Pos?的差異。
例如:
在MASTER上執行SHOW BINARY LOGS?的結果是:
~~~
+------------------+--------------+
| Log_name | File_size |
+------------------+--------------+
| mysql-bin.000009 | 1073742063 |
| mysql-bin.000010 | 107374193 |
+------------------+--------------+
~~~
而在SLAVE上執行SHOW SLAVE STATUS\G?的結果是:
~~~
Master_Log_File: mysql-bin.000009
Read_Master_Log_Pos: 668711237
Relay_Master_Log_File: mysql-bin.000009
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
***
Exec_Master_Log_Pos: 654409041
***
Seconds_Behind_Master: 3296
***
~~~
這時候,SLAVE實際的延遲應該是:
mysql-bin.000009?這個binlog中的binlog position?1073742063?和 SLAVE上讀取到的binlog position之間的差異延遲,即:
~~~
1073742063 - 654409041 = 419333022 個binlog event
~~~
并且還要加上?mysql-bin.000010這個binlog已經產生的107374193個binlog event,共
~~~
107374193 + 419333022 = 526707215 個binlog event
~~~
后記更新:
1、可以在MASTER上維護一個監控表,它只有一個字段,存儲這最新最新時間戳(高版本可以采用event_scheduler來更新,低版本可以用cron結合自動循環腳本來更新),在SLAVE上讀取該字段的時間,只要MASTER和SLAVE的系統時間一致,即可快速知道SLAVE和MASTER延遲差了多少。不過,在高并發的系統下,這個時間戳可以細化到毫秒,否則哪怕時間一致,也是有可能會延遲數千個binlog event的。
2、網友(李大玉,QQ:407361231)細心支出上面的計算延遲有誤,應該是mysql-bin.000009的最大事件數減去已經被執行完的事件數,即1073742063 – 654409041= 419333022個binlog event,再加上mysql-bin.000010這個binlog已經產生的107374193個binlog event,共526707215 個binlog event。
- 前言
- 為什么InnoDB表要建議用自增列做主鍵
- 線上環境到底要不要開啟query cache
- MySQL復制中slave延遲監控
- 如何安全地關閉MySQL實例
- 如何查看當前最新事務ID
- 從MyISAM轉到InnoDB需要注意什么
- 5.6版本GTID復制異常處理一例
- 不同的binlog_format會導致哪些SQL不會被記錄
- Spring框架中調用存儲過程失敗
- 如何將兩個表名對調
- mysqldump加-w參數備份
- 使用mysqldump備份時為什么要加上 -q 參數
- 修改my.cnf配置不生效
- 什么情況下會用到臨時表
- profiling中要關注哪些信息
- EXPLAIN結果中哪些信息要引起關注
- processlist中哪些狀態要引起關注
- MySQL無法啟動例一
- pt-table-checksum工具使用報錯一例
- 為什么要關閉query cache,如何關閉
- MySQL聯合索引是否支持不同排序規則
- SAVEPOINT語法錯誤一例
- 你所不知的table is full那些事
- 大數據量時如何部署MySQL Replication從庫
- 內存溢出案例