WALの遅延と肥大化とは?
PostgreSQLの非同期レプリケーションで最も多く発生するトラブルが、WALの遅延と肥大化です。
WALの遅延と肥大化とは、プライマリの変更情報がスタンバイ側に反映されるのが遅れ、その結果、反映されないWALが溜まってディスク容量を圧迫する事をいいます。
WALが遅延・肥大化するとどうなる?
スタンバイの同期不能
未だスタンバイに反映されていないWALが削除され、スタンバイの再構築が必要になります。
フェルオーバーが不可能になる
スタンバイが遅延してもプライマリは動作を続ける為、プライマリの状態に追いつけなくなります。よって、プライマリが故障した場合、スタンバイがプライマリとして動作できなくなります。
ディスク容量不足によるPostgreSQLの停止
WALファイルは プライマリ側のpg_wal ディレクトリに蓄積されますが、最終的に書き込み不能となり、PostgeSQLが停止します。
バックアップが失敗する
WALアーカイブが遅延すると、PITR(ポイントインリカバリ)が不可能になります。
- PITR(ポイントインリカバリ)
ベースバックアップ(物理バックアップ)とWALアーカイブを使用してバックアップ取得時点から任意の時刻までWALを「再生」する機能。障害直前や指定時刻の状態に復元できる。

WAL遅延の原因
スタンバイ側のI/O性能不足
HDDや低IOPSのクラウドストレージでは、WALの書き込み・適用が追いつかず replay_lag が発生しやすくなります。特に読み取りクエリと競合する場合、顕著になります。
- IOPS(アイオプス)
1秒間に何回の「読み込み(Read)」や「書き込み(Write)」操作ができるかの指標 replay_lag
スタンバイサーバがプライマリサーバにどれだけ遅れているかを示す指標
例)00:00:03.456→ 約3.4秒の遅延
ネットワーク帯域の不足・不安定な接続
プライマリ→スタンバイ間のWAL転送が詰まり、write_lag や flush_lag が発生します。VPNやクラウド間通信で多発し易い遅延です。
write_lag
プライマリがWALを送信してから、スタンバイがそれを受信してメモリに書き込むまでにかかった時間flush_lag
スタンバイがWALをディスクに書き込むまでにかかった時間
スタンバイのWAL適用処理の遅延
スタンバイでのクエリ実行やバックグラウンドプロセスがWALの適用を妨げたり、CPU競合やメモリ不足により発生する遅延です。
プライマリ側の送信プロセス不足(max_wal_senders)
複数のスタンバイがある場合、送信プロセスが足りずにWAL送信が滞り発生します。
max_wal_senders
PostgreSQL の設定パラメータ。WALをスタンバイやバックアップツールに送信するプロセスの最大数を指定する。
wal_keep_size の不足によるWAL早期削除
スタンバイが遅延しているのに、プライマリが未反映のWALを削除してしまいます。
wal_keep_size
PostgreSQL の設定パラメータ。プライマリサーバが保持しておくWALファイルのサイズを指定する。
アーカイブ処理の詰まり(archive_command)
アーカイブ先の容量不足やスクリプトエラーによってWALが溜まり、遅延や肥大化が発生します。
archive_command
WALを外部に保存(アーカイブ)するためのコマンド。特に PITR(Point-In-Time Recovery)や長期バックアップ、スタンバイ再同期において重要な役割を果たします。

遅延状況の確認方法 と LSN(Log Sequence Number)
- LSN(Log Sequence Number)
WALファイルの中で「どの位置までWALが処理されたか」を示す表記方法。WALの位置を上下32ビットで、X/Y の様に表記します。- X:0 ⇀ WALセグメントの先頭(最初のファイル)
- Y:16B6C60 ⇀ そのセグメント内のオフセット位置(バイト単位)
LSNの進み方(イメージ)
0/00000000 → 0/00001000 → 0/00002000 → ... → 0/16B6C60 → ...
WALが書き込まれるたびに、LSNは進みます。スタンバイが replay_lsn を報告することで、プライマリは「どこまで追いついているか」を把握できます。
- 遅延状況の確認
SELECT
application_name,
write_lag,
flush_lag,
replay_lag,
write_lsn,
flush_lsn,
replay_lsn
FROM pg_stat_replication;
- write_lag
プライマリがWALを送信してからスタンバイが受信してメモリに書き込むまでにかかった時間 - flush_lag
スタンバイがWALをディスクに書き込むまでにかかった時間 - replay_lag
スタンバイサーバがプライマリサーバにどれだけ遅れているかの時間 - write_lsn
スタンバイが WALをメモリ上に書き込んだLSN - flush_lsn
スタンバイがWALをディスクにフラッシュ(書き込み)LSN - replay_lsn
スタンバイがWALを適用し、データベース状態に反映したLSN

WAL遅延と肥大化を防ぐ対処法
スタンバイ側 I/O性能の向上
- スタンバイ側のSSDへの移行
HDDではflush_lagやreplay_lagが顕著に出るため、SSD化は最優先の対処法となります。 - IOPS保証付きインスタンス選定
クラウド環境では IOPS制限が遅延要因になります。 - スタンバイでのクエリ制限
読み取り専用用途に限定し、WAL適用を妨げないようにします。
ネットワーク帯域の不足・不安定な接続の解消
- 同一AZ配置
クラウドではプライマリ・スタンバイを同一地域の独立したセンター郡に配置します。 - VPNやファイアウォールの最適化
パケットロスや遅延の原因を排除します。
スタンバイ WAL適用処理の遅延対策
- スタンバイのhot_standby_feedbackの設定
設定を on にし、VACUUMとの衝突を防いでWAL適用をスムーズに実行できるようにします。- VACUUM
不要になったデータ(デッドタプル)を物理的に除去し、テーブルのサイズやパフォーマンスを最適化するメンテナンス処理
- VACUUM
プライマリ側の送信プロセス不足対策
- プライマリ側の送信プロセス数を増やす
例)max_wal_senders = 10
wal_keep_size の不足によるWAL早期削除 対策
- プライマリ側でWALを保持できるファイルサイズを増やす
例)wal_keep_size = ‘512MB’ # スタンバイの遅延に応じて調整
アーカイブ処理の詰まり 対策
- アーカイブ先の容量を十分に確保すると共に、容量を監視する
- 強制アーカイブの実施
WALセグメントが満たされていなくても、定期的にWALファイルをアーカイブ先へ排出します。その結果、pg_wal内のWALを早めに削除でき、肥大化やスタンバイの遅延を抑制できます。
archive_timeout = 60 # 60秒ごとにWALを強制アーカイブ
【広告】書籍:[改訂3版]内部構造から学ぶPostgreSQL―設計・運用計画の鉄則
PostgreSQLのコアな技術力を持つ専門家の視点から、システム構築や運用時に重要な要素を、PostgreSQLの内部構造と照らし合わせる形で解説します。内部構造を知っているからこそわかる運用ノウハウやチューニング方法が満載です。
まとめ
WAL遅延と肥大化は上述したように、適切な監視と対応を実施すれば防ぐ事が可能です。使用していて異常が感じられないからといって、そのままにしておくと、ある日 突然 異常が発生し、業務が停止するばかりでなく、原因の究明と復旧に時間と労力を費やす事となります。又、場合によっては大きな損失を被る事になりまねません。
そうならないためにも、適切な監視を実施して異常を早めに発見し、対策する事が重要です。

