Amazon RDS for PostgreSQL DB インスタンスのリードレプリカをクエリすると発生する、"リカバリとの競合によりステートメントをキャンセルします" というエラーのトラブルシューティング方法を教えてください。

所要時間1分
0

Amazon Relational Database Service (Amazon RDS) for PostgreSQL インスタンスでリードレプリカを設定しました。そのリードレプリカをクエリすると、"リカバリとの競合によりステートメントをキャンセルします" というエラーが発生します。

解決策

プライマリインスタンスとリードレプリカの間でレプリケーションの競合が発生すると、cancelling statement エラーが発生します。変更により、リードレプリカで発生しているアクティビティがブロックされる可能性があるため、PostgreSQL はリードレプリカに先行書き込みログの情報を適用できません。たとえば、リードレプリカ内の削除対象テーブルで SELECT ステートメントが実行されているときに、プライマリインスタンスで DROP ステートメントを実行した場合、リードレプリカが先行書き込みログのレコードを適用して SELECT ステートメントをキャンセルすると、cancelling statement エラーが発生します。

cancelling statement エラーを解決するには、エラーメッセージの詳細に基づいてリードレプリカにカスタムパラメータを設定します。

リードレプリカの pg_stat_database_conflicts ビューを参考に、復元における競合が原因でキャンセルされたステートメントに関する統計情報を確認することもできます。詳細については、PostgreSQL のウェブサイトで 「27.2.18 pg_stat_database_conflicts」 を参照してください。

エラーメッセージの詳細 "ユーザーがリレーションロックを長時間保持していました"

この問題を解決するには、max_standby_stream_delay または max_standby_archive_delay パラメータを変更し、リードレプリカが競合している待機ステートメントをキャンセルするまでの時間を長くします。リードレプリカがストリーミングのレプリケーションから先行書き込みログデータを読み取る場合は、max_standby_stream_delay パラメータを変更します。リードレプリカが Amazon Simple Storage Service (Amazon S3) 内のアーカイブの場所から先行書き込みログデータを読み取る場合は、max_standby_archive_delay パラメータを変更します。

これらのパラメータの詳細については、PostgreSQL のウェブサイトで「max_standby_streaming_delay (integer)」および「max_standby_archive_delay (integer)」を参照してください。

パラメータ値を 0 に設定すると、リードレプリカは競合するクエリをキャンセルし、レプリカインスタンスに先行書き込みログのエントリを適用します。値を -1 に設定すると、レプリカインスタンスはクエリが競合するまで無期限に待機するため、レプリケーションの遅延が増加します。ユースケースに基づいてこれらのパラメータの値を調整し、クエリのキャンセルやレプリケーションの遅延のバランスを取ります。

注: max_standby_archive_delay を増やし、読み取り側先行書き込みログのアーカイブエントリと競合するクエリを維持する場合、max_standby_streaming_delay も増やすことでキャンセルを防ぐことがベストプラクティスです。

エラーメッセージの詳細 "ユーザークエリにおいて、削除する必要のある行バージョンを確認する必要があった可能性があります"

この問題は一般的には、リードレプリカ上のトランザクションがプライマリインスタンスで削除対象に設定されたタプルを読み取っている場合に発生します。この問題を解決するには、hot_standby_feedback パラメータを有効にしなければならない場合があります。

hot_standby_feedback を有効にすると、リードレプリカは最も古いアクティブなトランザクションに関する情報を含むフィードバックメッセージをプライマリインスタンスに送信します。したがって、プライマリインスタンスにより、トランザクションに必要なレコードが削除されることがなくなります。このパラメータの詳細については、PostgreSQL のウェブサイトで「hot_standby_feedback (boolean)」を参照してください。

重要: hot_standby_feedback パラメータは、デフォルトでは無効になっています。リードレプリカで hot_standby_feedback を有効にすると、リードレプリカでクエリを長く実行した場合に、プライマリインスタンスのテーブルが肥大化する可能性があります。Vacuum 操作では、長時間実行されるクエリが必要とする可能性のあるデッドタプル (肥大化) は削除されません。肥大化のリスクを軽減するためには、autovacuum_threshold および autovacuum_vacuum_scale_factor を減らし、autovacuum_cost_limit を増やすことがベストプラクティスです。

コメントはありません

関連するコンテンツ