MySQL 5.5+ 引入複制心跳功能,解決傳統複制中「網路中斷無感知、Slave 狀態顯示正常實際延遲」的核心痛點。本文詳細解析原理、配置、監控指標。
傳統複制協議:Slave 發送 COM_BINLOG_DUMP 後,完全由 Master 推送數據。若 Master 無寫入,無數據流;若網路中斷,TCP 連接未必立即斷開,Slave 無法區分「Master 閒置」與「連接斷開」,導致:
Slave_IO_Running=Yes、Slave_SQL_Running=Yes 但實際未同步Seconds_Behind_Master 不準確slave_net_timeout=3600 (1小時) 才會嘗試重連master_heartbeat_period 秒發送一個心跳包Slave_last_heartbeat 時間戳slave_net_timeout 秒未收到任何數據(含心跳),Slave IO 線程判定超時,主動重連STOP SLAVE;
-- 設定心跳間隔 10 秒 (單位:秒,支援毫秒精度如 10.5)
CHANGE MASTER TO MASTER_HEARTBEAT_PERIOD = 10;
-- 設定網路超時 25 秒 (需大於心跳間隔,建議 2-3 倍)
SET GLOBAL SLAVE_NET_TIMEOUT = 25;
START SLAVE;
關鍵公式: slave_net_timeout > master_heartbeat_period * 2,避免誤判。
mysql> SHOW STATUS LIKE 'Slave%';
+----------------------------+---------------------+
| Variable_name | Value |
+----------------------------+---------------------+
| Slave_heartbeat_period | 5.000 | -- 當前心跳間隔
| Slave_last_heartbeat | 2014-05-08 11:48:57 | -- 最後收到心跳時間
| Slave_received_heartbeats | 1645 | -- 累計收到心跳次數
| Slave_open_temp_tables | 0 |
| Slave_retried_transactions | 0 |
| Slave_running | ON |
+----------------------------+---------------------+
注意: master_heartbeat_period 無法從 SHOW SLAVE STATUS 看到,必須用 SHOW STATUS 查看。
| 版本 | 心跳支援 | 建議配置 |
|---|---|---|
| 5.5 - 5.6 | 引入 | heartbeat=10, timeout=30 |
| 5.7 | 增強 | heartbeat=5, timeout=15; 支援 GTID 自動定位 |
| 8.0 | 預設優化 | 可依賴預設值;結合 SOURCE_CONNECTION_AUTO_FAILOVER 實現自動故障轉移 |
slave_net_timeout-- 1. 確認心跳生效
SHOW STATUS LIKE 'Slave_heartbeat_period';
-- 2. 確認網路超時設定
SHOW VARIABLES LIKE 'slave_net_timeout';
-- 3. 模擬網路中斷測試
# Master 防火牆封鎖 Slave IP
# 觀察 Slave 多久後 IO 線程重連 (應接近 slave_net_timeout)
-- 4. 檢查錯誤日誌
grep -i "heartbeat\|timeout\|reconnect" /var/log/mysql/error.log