WAL(先行書き込みログ)は、チェックポインター プロセスが削除できない場合に蓄積されます。これは通常、レプリケーションスロットが WAL ログを保持している、WAL 関連パラメーターが過剰に設定されている、または書き込み処理がクリーンアップ処理を上回っていることが原因です。本トピックでは、プライマリデータベースおよび読み取り専用インスタンスにおける WAL ログの蓄積を診断・解決する方法について説明します。
背景情報
WAL は PostgreSQL においてデータセキュリティを確保し、システムの信頼性とパフォーマンスを向上させるための重要なコンポーネントです。WAL により、複数の障害ポイントが発生した場合でもデータ損失を防ぎ、信頼性の高い方法でデータを復元できます。
プライマリデータベースにおける WAL ログの蓄積
非アクティブなレプリケーションスロットまたは未報告のログシーケンス番号
レプリケーションスロットは PostgreSQL で高可用性およびディザスタリカバリを実現するための重要なツールです。レプリケーションスロットは、コンシューマーが WAL ログを処理するまで PostgreSQL に対してその削除を停止させます。コンシューマーがログシーケンス番号(LSN)の報告を停止してスロットが非アクティブになると、そのスロットに関連付けられた WAL ログは無期限に蓄積され続けます。
ステップ 1:WAL 削除を妨げているスロットを特定します。
各スロットがどの程度 WAL を保持しているかを確認するには、pg_replication_slots システムビューに対して次のクエリを実行します。
SELECT slot_name, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_insert_lsn(), restart_lsn)) AS delay_size
FROM pg_replication_slots;特定のスロットの delay_size が大きいか、観測される WAL 蓄積量と一致している場合、そのスロットが削除を妨げている可能性があります。
ステップ 2:非アクティブなスロットを削除します。
ビジネス要件に基づき、該当スロットがまだ必要かどうかを評価し、不要であれば削除してください。
SELECT pg_drop_replication_slot('<slot_name>');レプリケーションスロットを削除すると、そのスロットは完全に削除されます。削除前に、スロットが実際に非アクティブであり、下流のコンシューマーが存在しないことを確認してください。
ステップ 3:削除を確認します。
ステップ 1 の特定クエリを再度実行し、スロットが削除されたことを確認します。
レプリケーションスロットの管理に関する詳細については、「WAL ログ管理機能の使用」をご参照ください。
不適切なパラメーター設定
wal_keep_segments(PostgreSQL 12 以前)、wal_keep_size、または max_wal_size が過剰に設定されていると、PostgreSQL は必要な量よりもはるかに多くの WAL を保持します。現在の値を確認し、実際のレプリケーションおよびリカバリ要件に合わせて適切な値に下げてください。
WAL 関連パラメーターの現在の値を確認するには、次の SQL ステートメントを実行します。
select * from pg_settings where name like '%wal%';wal_keep_size は、pg_wal ディレクトリに保持される WAL ログの最小サイズを制御します。このパラメーターは 1,024 MB を超えないように設定してください。このパラメーターは、RDS コンソールのパラメータ設定ページから変更するか、ModifyParameter API オペレーションを呼び出して変更できます。
max_wal_size は、インスタンスの仕様に基づいてシステムが動的に計算します。計算式は LEAST(GREATEST(DBInstanceClassMemory/2097152,2048),16384) です。このパラメーターを手動で設定する必要はありません。
PostgreSQL 13 以降では、wal_keep_size が wal_keep_segments に置き換えられます。PostgreSQL 9.5 以降では、max_wal_size が checkpoint_segments に置き換えられます。PostgreSQL 14 以降を実行する RDS インスタンスは新しいパラメーターのみをサポートします。
異常なバックアップポリシー
バックアップ完了後のチェックポイント操作時に、カーネルが自動的に WAL ログをクリアします。バックアップポリシーが誤って設定されているか、バックアップコンポーネントが失敗していると、WAL ログがバックアップされず蓄積されます。
RDS コンソールにログインし、インスタンス詳細ページで [バックアップとリストア] > [バックアップポリシー] を選択します。ログバックアップが有効になっているか、およびその保持期間を確認します。ログバックアップが [Never Clear] に設定されている場合、WAL ログは無期限に保持されますが、これは想定された動作です。
DBS コンソール にログインし、バックアップスケジュール一覧を確認してバックアップタスクのステータスおよびアップロード進捗をレビューします。異常なバックアップタスクやアップロード遅延は、ローカルでの WAL 蓄積を引き起こす可能性があります。DBS コンソールでバックアップスケジュールの詳細を確認し、タスクの失敗をトラブルシューティングできます。
VACUUM ストームおよび高負荷な書き込み処理
VACUUM ストーム(多数の自動または手動 VACUUM 操作が同時に実行されること)は、短時間で大量の WAL ログを生成します。これにより I/O 負荷が急増し、WAL クリーンアップが遅延する可能性があります。影響を軽減するには、VACUUM 関連パラメーターを調整し、VACUUM 実行を分散させて負荷を時間的に平準化してください。
高スループットな書き込み処理も同様の影響を及ぼします。可能であれば、バルク書き込みはオフピーク時間帯にスケジュールしてください。
読み取り専用インスタンスにおける WAL ログの蓄積
レプリケーション遅延
読み取り専用インスタンス上で WAL ログが蓄積するのは、リプレイ処理が遅れている場合です。主な原因は以下の 2 つです。
リプレイをブロックする長時間トランザクション。 読み取り専用インスタンス上の長時間トランザクションが WAL ログのリプレイと競合することがあります。
hot_standby_feedbackおよびmax_standby_streaming_delayの設定を確認してください。たとえば、hot_standby_feedbackがoffで、max_standby_streaming_delayが大きな値に設定されている場合、読み取り専用インスタンス上の長時間クエリがリプレイを大幅に遅延させる可能性があります。スペックが不足している読み取り専用インスタンス。 読み取り専用インスタンスの計算リソースまたはストレージの仕様がプライマリデータベースよりも低い場合、レプリケーションストリームに追いつかず、リプレイされていない WAL ログは削除できません。ビジネス要件に基づき、読み取り専用データベースに適切なインスタンスの仕様を選定してください。
次のステップ
上記の手順を実施しても WAL ログの蓄積が継続する場合は、ApsaraDB RDS for PostgreSQL のテクニカルサポートチームにお問い合わせください。
参考資料
非アクティブなレプリケーションスロットを手動で削除することで、AliPG が自動的に WAL ログを削除できるようになります。詳細については、「WAL ログ管理機能の使用」をご参照ください。