目錄
- MySQL從庫Seconds_Behind_Master延遲總結
- 一、延遲分類
- 1、第一類(成服務器有較高的負載)
- 2、第二類(不會造成服務器有較高的負載)
- 二、相關測試
- 1、Innodb層的行鎖造成的延遲
- 2、MySQL層的MDL LOCK造成的延遲
- 三、總結
MySQL從庫Seconds_Behind_Master延遲總結
一、延遲分類
延遲我們可將其分為兩類:
1、第一類(成服務器有較高的負載)
這一類延遲情況可能造成服務器有較高的負載,可能是CPU/IO的負載。因為從庫在實際執行Event,如果我們服務器的負載比較高應該考慮這幾種情況,關于如何查看線程的負載可以參考29節。
大事務造成的延遲,其延遲不會從0開始增加,而是直接從主庫執行了多久開始。比如主庫執行這個事務花費的20秒,那么延遲就會從20開始,可以自己細心觀察一下很容易看到。這是因為Query Event中沒有準確的執行時間,這個在上一節的計算公式中詳細描述過了 ,可以參考第8節和第27節。
大表DDL造成的延遲,其延遲會從0開始增加,因為Query Event記錄了準確的執行時間。這個在上一節的計算公式中也詳細描述過了,可以參考第8節和第27節。
表沒有合理的使用主鍵或者唯一鍵造成的延遲。這種情況不要以為設置slave_rows_search_algorithms參數為 INDEX_SCAN,HASH_SCAN就可以完全解決問題,原因我們在第24節進行了描述。
由于參數sync_relay_log,sync_master_info,sync_relay_log_info不合理導致,特別是sync_relay_log會極大的影響從庫的性能。原因我們在第26節進行過描述,因為sync_relay_log設置為1會導致大量relay log刷盤操作。
是否從庫開啟了記錄binary log功能即log_slave_updates參數開啟,如果不是必要可以關閉掉。這種情況我遇到很多次了。
2、第二類(不會造成服務器有較高的負載)
這一類延遲情況往往不會造成服務器有較高的負載。它們要么沒有實際的執行Event,要么就是做了特殊的操作造成的。
- 長期未提交的事務可能造成延遲瞬間增加,因為GTID_EVENT和XID_EVENT是提交時間其他Event是命令發起的時間。這個我們在第27節中舉例描述過了。
- Innodb層的行鎖造成的延遲,這種是在從庫有修改操作并且和SQL線程修改的數據有沖突的情況下造成的,因為我們前面23節說過SQL線程執行Event也會開啟事務和獲取行鎖,下面我們進行測試。
- MySQL層的MDL LOCK造成的延遲,這種情況可能是由于SQL線程執行某些DDL操作但是從庫上做了鎖表操作造成,原因我們已經在23節描述過了,下面我們進行測試。
- MTS中不合理的設置參數slave_checkpoint_period參數導致,這個在第27節已經測試過了。
- 在從庫運行期間手動改大了從庫服務器時間,這個也在第27節已經測試過了。
二、相關測試
因為上面的延遲情形很多我們都已經測試和講述過了。下面我們測試鎖造成的延遲情形。
1、Innodb層的行鎖造成的延遲
這個很容測試,我只要先在從庫做一個事務和SQL線程修改的數據相同即可以出現,大概測試如下:
從庫:
mysqlgt; begin;
Query OK, 0 rows affected (0.00 sec)
mysqlgt; delete from tmpk;
Query OK, 4 rows affected (0.00 sec)
不要提交
主庫執行同樣的語句
mysqlgt; delete from tmpk;
Query OK, 4 rows affected (0.30 sec)
這個時候你會觀察到延遲如下:

如果查看sys.innodb_lock_waits能看到如下的結果:

當然如果查看INNODB_TRX也可以觀察到事務的存在,這里就不截圖了,大家可以自己試試。
2、MySQL層的MDL LOCK造成的延遲
這種情況也非常容易測試,我們只需要開啟一個事務做一個select,然后主庫對同樣的表做DDL就可以出現如下:
從庫:
mysqlgt; begin;
Query OK, 0 rows affected (0.00 sec)
mysqlgt;
mysqlgt;
mysqlgt; select * from tkkk limit 1;
+------+------+------+
| a | b | c |
+------+------+------+
| 3 | 3 | 100 |
+------+------+------+
1 row in set (0.00 sec)
不要提交,表上MDL LOCK就不會釋放
主庫執行語句:
mysqlgt; alter table tmpk add testc int ;
Query OK, 0 rows affected (1.14 sec)
Records: 0 Duplicates: 0 Warnings: 0
這個時候你將會看到如下的信息:

我們可以通過state看到這是等待MDL lock獲取而導致的延遲,關于MDL lock的詳情可以參考文章:
https://www.jb51.net/article/221412.htm
三、總結
通過整個系列,我們應該清楚了Seconds_Behind_Master計算的方法,同時如果出現了延遲,我們首先查看從庫是否有負載,根據是否有負載進行區別對待,注意這里的負載一定要使用top -H
查看io/sql/worker線程的負載。我曾不止一次的遇到朋友問我延遲問題,當我問他負載如何的時候他告訴我負載不高啊整體負載也就不到2,這里我們應該注意的是對于一個線程
只能使用到一個CPU核,雖然整體負載不到2但是可能io/sql/worker線程已經跑滿了,實際上負載已經很高了,我們來看下面的這個截圖就是sql線程負載高的截圖如下:

這個截圖我們發現雖然整體負載不高在1多一點,但是Lwp號20092的線程已經跑滿了,這個線程
就是我們的sql線程,這個時候出現延遲是很可能的,這個截圖正是來自一個沒有合理使用主鍵或者唯一鍵造成的延遲的案例,案例如下:
https://www.jb51.net/article/221396.htm
我們查看CPU負載應該使用top -H去查看,查看io負載可以使用iotop,iostat等工具。我需要強調一下看MySQL負載的時候我們必須用線程的眼光去看
以上就是MySQL從庫Seconds_Behind_Master延遲總結的詳細內容,更多關于從庫Seconds_Behind_Master延遲總結的資料請關注腳本之家其它相關文章!
您可能感興趣的文章:- MySQL 發生同步延遲時Seconds_Behind_Master還為0的原因
- 詳解MySQL的Seconds_Behind_Master
- python3文件復制、延遲文件復制任務的實現方法
- docker實現mysql主從復制的示例代碼
- MySQL數據庫 Load Data 多種用法
- MySQL數據庫Shell import_table數據導入
- Mysql數據庫的主從同步配置
- Mysql實現簡易版搜索引擎的示例代碼
- MySQL命令無法輸入中文問題的解決方式
- 當面試官問mysql中char與varchar的區別