RDS for PostgreSQL DB インスタンスでレプリケーションの遅延とエラーが発生しているのはなぜですか?
PostgreSQL インスタンスの Amazon Relational Database Service (Amazon RDS) でレプリケーションエラーと遅延が発生しています。
簡単な説明
Amazon RDS for PostgreSQL DB インスタンスにリードレプリカを追加することで、インスタンスの読み取りをスケールできます。RDS for PostgreSQL は、PostgreSQL ネイティブストリーミングレプリケーションを使用して、ソース DB インスタンスの読み取り専用コピーを作成します。このリードレプリカ DB インスタンスは、ソース DB インスタンスの非同期に作成された物理レプリカです。これは、レプリカがプライマリ DB インスタンスに追いつけないことがあることを意味しています。その結果、レプリケーションの遅延が発生する可能性があります。レプリカ DB は、ソース DB インスタンスからリードレプリカにログ先行書き込み (WAL) データを送信する特別な接続によって作成されます。そのため、リードレプリカは WAL ログを確認して、プライマリインスタンスで行われた変更をレプリケートします。リードレプリカがプライマリインスタンスで WAL を見つけられない場合、リードレプリカは Amazon Simple Storage Service (Amazon S3) にアーカイブされた WAL データから復元されます。詳細については、「How streaming replication works for different RDS for PostgreSQL versions (異なる RDS for PostgreSQL バージョンごとのストリーミングレプリケーションの動作方法)」を参照してください。
Amazon RDS ReplicaLag メトリクスを表示することで、Amazon CloudWatch のレプリケーションの遅延をモニタリングできます。このメトリクスは、リードレプリカがソース DB インスタンスからどれだけ遅れているかを示します。Amazon RDS は、リードレプリカのレプリケーションステータスをモニタリングします。次に、何らかの理由でレプリケーションが停止した場合、Amazon RDS コンソールの [Replication State] (レプリケーション状態) フィールドを [Error] (エラー) に更新します。ReplicaLag メトリクスは、リードレプリカがソース DB インスタンスにどの程度追いついているか、およびソース DB インスタンスと特定のリードインスタンス間の遅延を示します。
解決方法
レプリカの遅延が増加すると、RDS for PostgreSQL エラーログに次のエラーのいずれかが表示されることがあります。
- Streaming replication has stopped (ストリーミングレプリケーションが停止しました): このエラーは、プライマリインスタンスとレプリカインスタンス間のストリーミングレプリケーションが停止した場合に発生します。この場合、レプリケーションは Amazon S3 のアーカイブの場所からリプレイを開始し、レプリカの遅延がさらに増加します。
- Streaming replication has been terminated (ストリーミングレプリケーションが終了しました): このエラーは、手動またはレプリケーションエラーが原因で、レプリケーションが連続して 30 日を超えて停止した場合に発生します。この場合、Amazon RDS はプライマリ DB インスタンスとすべてのリードレプリカ間のレプリケーションを終了し、プライマリインスタンスのストレージ要件の増加やフェイルオーバー時間の延長を防止します。
リードレプリカインスタンスは、レプリケーションが終了した後でも使用できます。ただし、レプリケーションが終了すると、リードレプリカに必要なトランザクションログがプライマリインスタンスから削除されるため、レプリケーションを再開できません。
レプリカの遅延が増加する最も一般的な理由は次の通りです。
- プライマリインスタンスとレプリカインスタンスの設定の違い
- プライマリインスタンスでの書き込みワークロードの負荷が高い
- 長時間実行されているトランザクション
- プライマリインスタンステーブルに対する排他ロック
- 破損または欠落している WAL ファイル
- ネットワークの問題
- 正しくないパラメータ設定
- トランザクションがない
プライマリインスタンスとリードレプリカの設定の違い
レプリカインスタンスの設定が正しくないと、レプリケーションのパフォーマンスに影響する恐れがあります。リードレプリカは、追加の読み取りクエリと共にソースインスタンスと同様の書き込みワークロードを処理します。そのため、ソースインスタンスと同じかそれ以上のインスタンスクラスとストレージタイプのレプリカを使用してください。レプリカはソースインスタンスと同じ書き込みアクティビティをリプレイする必要があるため、下位インスタンスクラスのレプリカを使用すると、レプリカの遅延が長くなり、レプリケーションの遅延が増加する場合があります。ストレージの設定が一致していないと、レプリケーションの遅延も増加します。
プライマリインスタンスでの書き込みワークロードの負荷が高い
プライマリインスタンスに大量の書き込みワークロードがあると、大量の WAL ファイルが流入する場合があります。WAL ファイルの数が増加し、これらのファイルをリードレプリカでリプレイすると、全体的なレプリケーションパフォーマンスが低下する恐れがあります。このため、レプリカの遅延が増加した場合は、必ずプライマリインスタンスの書き込みアクティビティを確認してください。CloudWatch メトリクスまたは拡張モニタリングを使用して、このワークロードを分析できます。transactionLogsDiskUsage、TransactionLogsGeneration、WriteIOPS、WriteThroughput、WriteLatency の値を表示して、ソースインスタンスの書き込みワークロードの負荷が高くなっていないか確認します。スループットレベルでボトルネックを確認することもできます。各インスタンスタイプには専用のスループットがあります。詳細については、「DB インスタンスクラスのハードウェア仕様」を参照してください。
この問題を回避するには、ソースインスタンスの書き込みアクティビティを制御して分散します。多数の書き込みアクティビティを一緒に実行する代わりに、タスクをより小さなタスクバンドルに分割し、これらのバンドルを複数のトランザクションに均等に分散します。Writelatency や WriteIOPS などのメトリクスに CloudWatch アラートを使用して、ソースインスタンスでの大量の書き込みについて通知を受けることができます。
長時間実行されているトランザクション
データベースで長時間実行されているアクティブなトランザクションは、WAL レプリケーションプロセスに干渉し、レプリケーションの遅延を増加させます。このため、PostgreSQL pg_stat_activity ビューでアクティブなトランザクションの実行時間を必ずモニタリングしてください。
次のようなクエリをプライマリインスタンスで実行して、長時間実行されているクエリのプロセス ID (PID) を見つけます。
SELECT datname, pid,usename, client_addr, backend_start, xact_start, current_timestamp - xact_start AS xact_runtime, state, backend_xmin FROM pg_stat_activity WHERE state='active';
クエリの PID を特定したら、クエリを終了することを選択できます。
次のようなクエリをプライマリインスタンスで実行して、クエリを終了します。
SELECT pg_terminate_backend(PID);
また、長時間実行されているトランザクションを回避するために、クエリの書き換えや調整を選択することもできます。
プライマリインスタンステーブルに対する排他ロック
プライマリインスタンスで DROP TABLE、TRUNCATE、REINDEX、VACUUM FULL、REFRESH MATERIALIZED VIEW (CONCURRENTLY なし) などのコマンドを実行すると、PostgreSQL はアクセス排他ロックを処理します。このロックは、ロックの保持期間中、他のすべてのトランザクションがテーブルにアクセスするのを防ぎます。通常、テーブルはトランザクションが終了するまでロックされたままです。このロックアクティビティは WAL に記録され、リードレプリカによってリプレイおよび保持されます。テーブルにアクセス排他ロックが適用されたままの時間が長いほど、レプリケーションの遅延も長くなります。
この問題を回避するには、pg_locks および pg_stat_activity カタログテーブルを定期的にクエリしてトランザクションをモニタリングすることがベストプラクティスです。
例:
SELECT pid, usename, pg_blocking_pids(pid) AS blocked_by, QUERY AS blocked_query<br>FROM pg_stat_activity<br>WHERE cardinality(pg_blocking_pids(pid)) > 0;
破損または欠落している WAL ファイル
WAL ファイルが破損または欠落していると、レプリカの遅延が発生する場合があります。この場合、WAL を開くことができないことを示すエラーが PostgreSQL ログに表示されます。また、「要求された WAL セグメント XXX は既に削除されています」というエラーが表示される場合もあります。
ネットワークの問題
プライマリインスタンスとレプリカインスタンス間のネットワークの中断により、ストリーミングレプリケーションで問題が発生し、レプリカの遅延が増加する場合があります。
正しくないパラメータ設定
サーバー設定パラメータグループのカスタムパラメータの一部を誤って設定すると、レプリカの遅延が増加する場合があります。正しく設定する必要があるパラメータの一部を以下に示します。
- wal_keep_segments: このパラメータは、プライマリインスタンスが pg_wal ディレクトリに保持する WAL ファイルの数を指定します。このパラメータのデフォルト値は 32 に設定されています。このパラメータがデプロイに対して十分に高い値に設定されていない場合、リードレプリカが遅延し、ストリーミングレプリケーションが停止する場合があります。この場合、RDS はレプリケーションエラーを生成し、プライマリインスタンスのアーカイブされた WAL データを S3 からリプレイすることにより、リードレプリカの復旧を開始します。この復旧プロセスは、リードレプリカがストリーミングレプリケーションを継続できるまで続きます。
注: PostgreSQL バージョン 13 では、wal_keep_segments パラメータの名前は wal_keep_size です。このパラメータは wal_keep_segments と同じ目的を果たします。ただし、このパラメータのデフォルト値は、ファイル数ではなく MB (2,048 MB) で定義されています。 - max_wal_senders: このパラメータは、ストリーミングレプリケーションプロトコルでプライマリインスタンスが同時にサポートできる接続の最大数を指定します。RDS for PostgreSQL 13 以降のリリースのこのパラメータのデフォルト値は 20 です。このパラメータは、実際のリードレプリカ数よりわずかに大きい値に設定する必要があります。このパラメータがリードレプリカの数よりも小さい値に設定されている場合、レプリケーションは停止します。
- hot_standby_feedback: このパラメータは、レプリカインスタンスで現在実行されているクエリについて、レプリカインスタンスからプライマリインスタンスにフィードバックを送信するかどうかを指定します。このパラメータを有効にすると、レプリカインスタンスの読み取りクエリが完了しない限り、ソースインスタンスで次のエラーメッセージを表示し、関連テーブルに対する VACUUM 操作を延期できます。そのため、hot_standby_feedback が有効になっているレプリカインスタンスは、長時間実行されるクエリを処理できます。ただし、このパラメータによりソースインスタンスでテーブルが肥大化する恐れがあります。プライマリインスタンスでのストレージ不足やトランザクション ID のラップアラウンドなどの重大な問題を回避するために、レプリカインスタンスで長時間実行されるクエリを必ずモニタリングしてください。
ERROR: canceling statement due to conflict with recovery Detail: User query might have needed to see row versions that must be removed
- max_standby_streaming_delay/max_standby_archive_delay: 長時間実行されている読み取りクエリを完了するために、レプリカインスタンスで max_standby_archive_delay や max_standby_streaming_delay などのパラメータを有効にできます。これらのパラメータは、読み取りクエリがレプリカで実行されているときにソースデータが変更された場合、レプリカの WAL リプレイを一時停止します。これらのパラメータの値が -1 の場合、WAL リプレイは読み取りクエリが完了するまで待機します。ただし、この一時停止によってレプリケーションの遅延が無制限に増加し、WAL の蓄積によりソースでのストレージ消費量が増加します。
トランザクションがない
ソース DB インスタンスでユーザートランザクションが発生していない場合、PostgreSQL リードレプリカは最大 5 分のレプリケーションの遅延を報告します。
関連情報
Amazon RDS for PostgreSQL でのリードレプリカの使用
サーバー設定に関する PostgreSQL ドキュメント
関連するコンテンツ
- 質問済み 8日前lg...
- 質問済み 9ヶ月前lg...
- AWS公式更新しました 2年前
- AWS公式更新しました 2年前