一、概述
1.1 背景介紹
復制延遲一上來,很多人先盯Seconds_Behind_Master。這個指標當然要看,但它只能告訴你“延遲已經(jīng)發(fā)生了”,不能告訴你是網(wǎng)絡拉取慢、Relay Log 堆積、SQL 線程執(zhí)行慢、并行復制沒吃滿,還是下游被長事務、DDL、熱點表拖住了。
生產(chǎn)環(huán)境更穩(wěn)的排查方式是:先分清 IO 線程和 SQL 線程,再判斷是拉不到、寫不進、還是應用不過來。如果只是看單個秒數(shù),最容易把真正的問題藏掉。
1.2 技術(shù)特點
從復制鏈路拆問題:Source → 網(wǎng)絡 → IO Thread → Relay Log → SQL / Applier Thread。
兼顧新舊版本字段:MySQL 8.0 推薦SHOW REPLICA STATUS,舊環(huán)境仍可能看到Seconds_Behind_Master。
貼近線上治理:不僅說怎么查,也說怎么避免復制被長事務拖死。
1.3 適用場景
場景一:業(yè)務讀流量打到從庫,延遲突然升高導致讀到舊數(shù)據(jù)。
場景二:主庫寫入正常,從庫relay log堆積。
場景三:發(fā)布、DDL、批處理后復制延遲持續(xù)幾分鐘甚至幾十分鐘。
1.4 環(huán)境要求
| 組件 | 版本要求 | 說明 |
|---|---|---|
| MySQL | 8.0+ 推薦 | 示例以SHOW REPLICA STATUS為主 |
| 復制模式 | GTID 或傳統(tǒng) binlog 位點 | 兩者命令略有差異 |
| 指標采集 | mysqld_exporter | 監(jiān)控復制延遲與線程狀態(tài) |
| 權(quán)限 | 具備復制和性能視圖查詢權(quán)限 | 需要查performance_schema |
二、詳細步驟
2.1 準備工作
2.1.1 系統(tǒng)檢查
SHOWREPLICASTATUSG SHOWPROCESSLIST; SHOWVARIABLESLIKE'server_id'; SHOWVARIABLESLIKE'gtid_mode'; SHOWVARIABLESLIKE'slave_parallel_workers';
先回答:
IO 線程是否正常拉日志
SQL / Applier 線程是否正常執(zhí)行
延遲是持續(xù)增長還是可追平
并行復制有沒有啟用,是否真的吃滿
2.1.2 安裝依賴
sudo apt update ||true sudo apt install -y mysql-client jq ||true sudo yum install -y mysql jq ||true
2.1.3 第一輪確認
SHOWREPLICASTATUSG SELECT*FROMperformance_schema.replication_connection_statusG SELECT*FROMperformance_schema.replication_applier_status_by_workerG
2.2 核心配置
2.2.1 第一步:先區(qū)分“拉取慢”還是“執(zhí)行慢”
核心判斷字段:
Replica_IO_Running/Slave_IO_Running
Replica_SQL_Running/Slave_SQL_Running
Seconds_Behind_Source/Seconds_Behind_Master
Relay_Log_Space
Last_IO_Error、Last_SQL_Error
如果 IO 線程不正常,優(yōu)先查:
SHOWREPLICASTATUSG
如果 SQL 線程正常但追不上,優(yōu)先查:
SELECTWORKER_ID, LAST_APPLIED_TRANSACTION, APPLYING_TRANSACTION, LAST_APPLIED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP, LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP FROMperformance_schema.replication_applier_status_by_worker;
2.2.2 第二步:標準配置示例
# 文件路徑:/etc/my.cnf.d/replication.cnf [mysqld] server_id=102 log_bin=mysql-bin binlog_format=ROW gtid_mode=ON enforce_gtid_consistency=ON relay_log_recovery=ON slave_parallel_type=LOGICAL_CLOCK slave_parallel_workers=8 read_only=ON super_read_only=ON
參數(shù)說明:
binlog_format=ROW:復制一致性更穩(wěn)
relay_log_recovery=ON:異常重啟后更容易恢復 relay log 狀態(tài)
slave_parallel_workers=8:并行復制要按業(yè)務寫入模型調(diào),不是越大越好
super_read_only=ON:避免業(yè)務誤寫從庫
2.2.3 第三步:按三條線下鉆
看復制狀態(tài):
SHOWREPLICASTATUSG SHOWBINARYLOGSTATUS;
看熱點事務和鎖:
SHOWPROCESSLIST; SELECT*FROMinformation_schema.innodb_trxG SHOWENGINEINNODBSTATUSG
看延遲是否卡在單個事務:
SELECTTHREAD_ID, EVENT_NAME, TIMER_WAIT FROMperformance_schema.events_stages_current WHEREEVENT_NAMELIKE'stage/sql/%';
2.3 啟動和驗證
2.3.1 啟動服務
STOPREPLICA; STARTREPLICA; SHOWREPLICASTATUSG
2.3.2 功能驗證
SHOWREPLICASTATUSG SELECT*FROMperformance_schema.replication_connection_statusG SELECT*FROMperformance_schema.replication_applier_status_by_workerG
三、示例代碼和配置
3.1 完整配置示例
3.1.1 主配置文件
# 文件路徑:/etc/my.cnf.d/replication.cnf [mysqld] server_id=102 log_bin=mysql-bin binlog_format=ROW gtid_mode=ON enforce_gtid_consistency=ON relay_log_recovery=ON slave_parallel_type=LOGICAL_CLOCK slave_parallel_workers=8 read_only=ON super_read_only=ON
3.1.2 輔助腳本
#!/usr/bin/env bash set-euo pipefail MYSQL_CMD="${MYSQL_CMD:-mysql -uroot -p}" OUT_DIR="/tmp/mysql-replica-$(date +%F-%H%M%S)" mkdir -p"$OUT_DIR" $MYSQL_CMD-e"SHOW REPLICA STATUSG">"$OUT_DIR/replica-status.txt" $MYSQL_CMD-e"SHOW PROCESSLIST">"$OUT_DIR/processlist.txt" $MYSQL_CMD-e"SELECT * FROM performance_schema.replication_connection_statusG">"$OUT_DIR/connection-status.txt" $MYSQL_CMD-e"SELECT * FROM performance_schema.replication_applier_status_by_workerG">"$OUT_DIR/applier-status.txt" $MYSQL_CMD-e"SHOW ENGINE INNODB STATUSG">"$OUT_DIR/innodb-status.txt" echo"artifacts saved to$OUT_DIR"
3.2 實際應用案例
案例一:不是網(wǎng)絡慢,是單個大事務把 SQL 線程卡住
場景描述:從庫延遲從幾十毫秒漲到 18 分鐘,主庫沒報錯,網(wǎng)絡也正常。
實現(xiàn)代碼:
SHOWREPLICASTATUSG SHOWPROCESSLIST; SELECT*FROMinformation_schema.innodb_trxG
運行結(jié)果:
Seconds_Behind_Source: 1087 Replica_IO_Running: Yes Replica_SQL_Running: Yes Relay_Log_Space: 1293844832
根因是主庫一次性提交了超大批量更新事務,從庫 SQL 線程長時間卡在單事務 apply。處理動作:
把批處理切小批次
大表更新改成分段執(zhí)行
保留并行復制但別指望它能拆開單個超大事務
案例二:不是 SQL 線程慢,是 IO 線程拉不到新 binlog
場景描述:主從延遲持續(xù)增長,Relay_Log_Space卻不大。
實現(xiàn)步驟:
看 IO/SQL 線程
SHOWREPLICASTATUSG
看錯誤信息
SHOWREPLICASTATUSG
查網(wǎng)絡和權(quán)限
mysql -hsource-db -e"SHOW BINARY LOG STATUS;" telnetsource-db 3306
根因是復制鏈路網(wǎng)絡抖動疊加復制賬號權(quán)限異常,IO 線程斷續(xù)重連,延遲不斷累積。
案例三:DDL 和元數(shù)據(jù)鎖把復制線程長期卡住
場景描述:某次結(jié)構(gòu)變更后,從庫延遲持續(xù) 40 多分鐘。IO 線程正常,Relay Log 也在增長,但 SQL 線程一直追不上。
實現(xiàn)步驟:
看復制狀態(tài)
SHOWREPLICASTATUSG
查元數(shù)據(jù)鎖和事務
SELECT*FROMperformance_schema.metadata_locksG SELECT*FROMinformation_schema.innodb_trxG SHOWPROCESSLIST;
看是否被 DDL 卡住
SHOWENGINEINNODBSTATUSG
運行結(jié)果:
Waiting for table metadata lock
根因是主庫 DDL 進入復制鏈路后,從庫上又有長查詢占著元數(shù)據(jù)鎖,SQL 線程一直卡在同一條語句。處理動作:
先終止阻塞復制的長查詢
大表 DDL 改到低峰窗口
對高風險 DDL 預演復制影響
這類延遲如果只看Seconds_Behind_Source,你知道它慢了,但不知道它為什么永遠追不上。
四、最佳實踐和注意事項
4.1 最佳實踐
4.1.1 性能優(yōu)化
優(yōu)化點一:并行復制要開,但要結(jié)合業(yè)務寫入模式驗證,熱點表和單大事務不會因為 worker 多就 magically 變快。
優(yōu)化點二:批處理、DDL、大事務必須做節(jié)流和窗口管理。
優(yōu)化點三:主從延遲監(jiān)控不能只看秒數(shù),還要看 IO/SQL 線程狀態(tài)和 Relay Log 增長速度。
4.1.2 安全加固
安全措施一:從庫保持super_read_only=ON,避免誤寫。
安全措施二:復制賬號最小權(quán)限,定期輪換密碼。
安全措施三:復制鏈路變更先在從庫灰度驗證。
4.1.3 高可用配置
HA 方案一:關(guān)鍵讀流量不要只綁一臺從庫,延遲高時可自動摘流。
HA 方案二:復制監(jiān)控和業(yè)務讀延遲監(jiān)控聯(lián)動。
備份策略:保留關(guān)鍵時段SHOW REPLICA STATUS和performance_schema快照。
4.2 注意事項
4.2.1 配置注意事項
警告:Seconds_Behind_Master或Seconds_Behind_Source為0,不等于絕對沒問題。復制線程斷開、SQL thread 卡住、延遲剛好被短暫追平,都可能讓你誤判。
大事務和 DDL 是復制延遲的常見放大器
并行復制沒配置好,延遲會長期追不上
從庫性能不足時,復制延遲本質(zhì)上是資源問題
4.2.2 常見錯誤
| 錯誤現(xiàn)象 | 原因分析 | 解決方案 |
|---|---|---|
| 秒數(shù)很高,但線程都正常 | SQL 線程在追大事務 | 查長事務、DDL、熱點表 |
| 秒數(shù)不高,但讀流量讀到舊數(shù)據(jù) | 監(jiān)控窗口太粗或剛短暫追平 | 增加更細粒度采樣 |
| Relay Log 持續(xù)增長 | IO 正常拉取,SQL 執(zhí)行跟不上 | 查 apply 能力、鎖等待、資源 |
4.2.3 兼容性問題
版本兼容:8.0 新舊字段名有差異,腳本里要兼容Master/Source命名。
平臺兼容:云盤性能、跨可用區(qū)網(wǎng)絡時延會直接影響復制。
組件依賴:GTID、MTS、binlog 格式和 DDL 策略都會影響復制行為。
五、故障排查和監(jiān)控
5.1 故障排查
5.1.1 日志查看
grep -Ei'replica|slave|relay|error'/var/log/mysqld.log | tail -50
5.1.2 常見問題排查
問題一:延遲升高,但Relay_Log_Space不大
SHOWREPLICASTATUSG
解決方案:優(yōu)先查 IO 線程、網(wǎng)絡、權(quán)限、主庫 binlog 獲取。
問題二:Relay_Log_Space很大,秒數(shù)持續(xù)增加
SHOWREPLICASTATUSG SHOWPROCESSLIST;
解決方案:優(yōu)先查 SQL 線程 apply 慢、鎖等待、大事務。
問題三:并行復制開了,還是追不上
癥狀:slave_parallel_workers大于 0,但延遲長期不降
排查:
SHOWVARIABLESLIKE'slave_parallel%'; SELECT*FROMperformance_schema.replication_applier_status_by_workerG
解決:判斷寫入是否具備并行空間,熱點表和單大事務場景要從業(yè)務側(cè)拆解
5.1.3 調(diào)試模式
SHOWREPLICASTATUSG SHOWENGINEINNODBSTATUSG
5.2 性能監(jiān)控
5.2.1 關(guān)鍵指標監(jiān)控
SHOWREPLICASTATUSG
5.2.2 監(jiān)控指標說明
| 指標名稱 | 正常范圍 | 告警閾值 | 說明 |
|---|---|---|---|
| 復制延遲秒數(shù) | < 1s | > 10s 持續(xù)5m | 只做結(jié)果告警 |
| IO 線程狀態(tài) | Running | 非 Running | 日志拉取異常 |
| SQL 線程狀態(tài) | Running | 非 Running | Apply 異常 |
| Relay Log 空間 | 平穩(wěn) | 持續(xù)增長15m | 執(zhí)行跟不上 |
5.2.3 監(jiān)控告警配置
groups: -name:mysql-replication rules: -alert:MySQLReplicationLagHigh expr:mysql_slave_status_seconds_behind_master>10 for:5m -alert:MySQLReplicationSQLThreadDown expr:mysql_slave_status_sql_running==0 for:1m -alert:MySQLReplicationIOThreadDown expr:mysql_slave_status_slave_io_running==0 for:1m
5.3 備份與恢復
5.3.1 備份策略
#!/usr/bin/env bash set-euo pipefail mysql -uroot -p -e"SHOW REPLICA STATUSG"> /backup/replica-status-$(date +%F).txt mysql -uroot -p -e"SHOW MASTER STATUSG"> /backup/master-status-$(date +%F).txt
5.3.2 恢復流程
采樣現(xiàn)場:bash ./mysql-replica-collect.sh
停止復制:STOP REPLICA;
修復根因后恢復:START REPLICA;
驗證追平:SHOW REPLICA STATUSG
六、總結(jié)
6.1 技術(shù)要點回顧
主從延遲不能只看秒數(shù)
先分 IO 線程和 SQL 線程,再看 Relay Log 和事務特征
大事務、DDL、熱點表是最常見的復制放大器
并行復制能提速,但救不了單個超大事務
6.2 進階學習方向
GTID 與復制拓撲治理
并行復制與事務拆分
只讀流量摘流與延遲感知路由
6.3 參考資料
MySQL Replication Status- 復制狀態(tài)字段說明
Performance Schema Replication Tables- 復制相關(guān)性能視圖
MySQL Replication Options- 從庫復制參數(shù)
附錄
A. 命令速查表
SHOWREPLICASTATUSG SHOWPROCESSLIST; SELECT*FROMperformance_schema.replication_connection_statusG SELECT*FROMperformance_schema.replication_applier_status_by_workerG SHOWENGINEINNODBSTATUSG
B. 配置參數(shù)詳解
slave_parallel_workers:并行復制 worker 數(shù)
relay_log_recovery:異常重啟后 relay log 恢復
super_read_only:更嚴格的只讀保護
C. 術(shù)語表
| 術(shù)語 | 英文 | 解釋 |
|---|---|---|
| 復制延遲 | Replication Lag | 從庫應用事務落后主庫的時間差 |
| 中繼日志 | Relay Log | 從庫拉取主庫 binlog 后本地保存的日志 |
| 應用線程 | SQL / Applier Thread | 在從庫執(zhí)行事務的線程 |
| GTID | Global Transaction Identifier | 全局事務標識 |
-
MySQL
+關(guān)注
關(guān)注
1文章
911瀏覽量
29620 -
線程
+關(guān)注
關(guān)注
0文章
510瀏覽量
20836
原文標題:MySQL 主從延遲排查全流程:不是只看 Seconds_Behind_Master
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
簡單介紹MySQL延遲主從復制
利用MySQL進行一主一從的主從復制
MySQL主從復制原理詳解
一個操作把MySQL主從復制整崩了
MySQL主從延遲排查全流程
評論