症状
MySQL レプリケーションで Seconds_Behind_Master が増加し続ける、または高い値のまま減少しない
結論:まずこれを確認
SHOW SLAVE STATUS\GでSlave_IO_RunningとSlave_SQL_Runningが両方Yesか確認Seconds_Behind_Masterの値と推移を確認(増加中か、一定か)- スレーブ側の CPU・ディスク I/O 負荷を確認
トラブルシューティングフロー
flowchart TD
A[Seconds_Behind_Master が高い] --> B{Slave_IO_Running は Yes?}
B -->|No| C[ネットワーク/マスター接続の問題]
B -->|Yes| D{Slave_SQL_Running は Yes?}
D -->|No| E[SQL スレッドエラーを確認]
D -->|Yes| F{遅延は増加中?}
F -->|Yes| G[スレーブの処理能力不足]
F -->|No| H{大量の更新があった?}
H -->|Yes| I[一時的な遅延 - 待機]
H -->|No| J[長時間クエリ/ロック確認]
C --> K[マスター側ログ・ネットワーク確認]
E --> L[Last_SQL_Error を確認]
G --> M[スレーブスペック/設定確認]
J --> N[SHOW PROCESSLIST 確認]
よくある原因
- マスターでの大量更新 - バッチ処理やデータ移行で一時的に遅延が発生
- スレーブのディスク I/O 不足 - HDD使用時やIOPS制限がある環境で発生しやすい
- スレーブの CPU 不足 - シングルスレッドの SQL スレッドがボトルネックになる
- 長時間実行クエリ - マスターで実行された ALTER TABLE などがスレーブで再実行される
- ネットワーク帯域不足 - バイナリログの転送が追いつかない
- テーブルロック競合 - スレーブ上の読み取りクエリとの競合
- 不適切な設定 -
sync_binlog、innodb_flush_log_at_trx_commitの設定不整合
確認手順
ステップ1: レプリケーション状態を確認する
mysql -e "SHOW SLAVE STATUS\G" | grep -E "(Slave_IO_Running|Slave_SQL_Running|Seconds_Behind_Master|Last_SQL_Error|Master_Log_File|Relay_Master_Log_File)"
🔍 チェックポイント: Slave_IO_Running: Yes、Slave_SQL_Running: Yes であれば基本的な接続は正常
ステップ2: 遅延の推移を確認する
# 5秒ごとに10回確認
for i in {1..10}; do
mysql -e "SHOW SLAVE STATUS\G" | grep "Seconds_Behind_Master"
sleep 5
done
🔍 チェックポイント: 値が増加中なら処理が追いついていない、一定なら安定しつつも遅れている状態
ステップ3: スレーブのリソース状況を確認する
# CPU使用率
top -bn1 | head -20
# ディスクI/O
iostat -x 1 5
# MySQL プロセスの状態
mysql -e "SHOW PROCESSLIST\G" | grep -A5 "system user"
🔍 チェックポイント: CPU使用率が100%に張り付いている、iowait が高い場合はリソース不足
ステップ4: 実行中の処理を確認する
mysql -e "SHOW PROCESSLIST\G" | grep -B2 -A8 "State:"
🔍 チェックポイント: State: Waiting for table metadata lock などが表示されていればロック競合の可能性
ステップ5: バイナリログの差分を確認する
mysql -e "SHOW SLAVE STATUS\G" | grep -E "(Master_Log_File|Read_Master_Log_Pos|Relay_Master_Log_File|Exec_Master_Log_Pos)"
🔍 チェックポイント: Master_Log_File と Relay_Master_Log_File が大きく異なる場合、I/O スレッドの転送も遅れている
ステップ6: マスター側の更新量を確認する
マスター側で実行:
mysql -e "SHOW MASTER STATUS\G"
mysql -e "SHOW GLOBAL STATUS LIKE 'Com_%'" | grep -E "(insert|update|delete)"
🔍 チェックポイント: マスターで大量の更新があった直後は遅延が発生しやすい
NG行動(やってはいけないこと)
- 遅延中にスレーブを再起動する - リレーログの再取得が必要になり、さらに遅延が増える可能性
- STOP SLAVE を安易に実行する - 遅延がリセットされず、再開時に混乱の原因になる
- マスターの binlog を削除する - スレーブが追いつく前に削除すると復旧不能になる
- 遅延中にスレーブでスキーマ変更する - レプリケーション不整合の原因になる
- Seconds_Behind_Master = 0 だけを見て安心する - I/O スレッドが停止していても 0 になる場合がある
よくある質問(FAQ)
Q1: Seconds_Behind_Master が NULL になっている場合は?
A: Slave_IO_Running または Slave_SQL_Running が No になっている可能性が高い。SHOW SLAVE STATUS\G の Last_IO_Error または Last_SQL_Error を確認する
Q2: 遅延を許容できる範囲に抑えるにはどうする?
A: スレーブのスペック向上、並列レプリケーション(slave_parallel_workers)の設定、SSD への換装などを検討する。根本的にはマスターの更新量削減が有効
Q3: pt-heartbeat などのツールを使うべき?
A: Seconds_Behind_Master は精度に問題がある場合があるため、正確な遅延監視が必要なら pt-heartbeat(Percona Toolkit)の導入を検討する
関連するエラー・症状
準備中
解決しない場合
- MySQL 公式ドキュメント - Replication
- Percona - Replication Lag
- 確認すべきログファイル:
- スレーブのエラーログ(
/var/log/mysql/error.logなど) - スローログ(有効にしている場合)
- スレーブのエラーログ(
- 次に調べるキーワード:
mysql parallel replicationpt-slave-delayGTID replication troubleshooting