適用対象: Azure Database for PostgreSQL - フレキシブル サーバー
この記事は、読み取りレプリカに対するクエリの実行中に発生する問題を解決するのに役立ちます。
現象
- 読み取りレプリカでクエリを実行しようとすると、クエリが予期せず終了します。
- "復旧との競合によるステートメントの取り消し" などのエラー メッセージがログまたはクエリ出力に表示されます。
- プライマリから読み取りレプリカへのレプリケーションに顕著な遅延またはラグが発生する可能性があります。
提供されているスクリーンショットの左側にはプライマリ Azure Database for PostgreSQL フレキシブル サーバー インスタンスがあり、右側には読み取りレプリカがあります。
- 読み取りレプリカ コンソール (上のスクリーンショットの右側)
- 長い
SELECT
ステートメントが進行中であることがわかります。 SQL に関して注意すべき重要な側面は、データの一貫したビューです。 SQL ステートメントを実行すると、基本的にデータのビューが "固定" されます。 SQL ステートメントの実行を通じて、変更が他の場所で同時に発生している場合でも、常にデータの一貫性のあるスナップショットが表示されます。
- 長い
- プライマリ コンソール (上のスクリーンショットの左側)
UPDATE
操作が実行されました。UPDATE
自体が読み取りレプリカの動作を中断するとは限りませんが、後続の操作では動作します。 更新後、VACUUM
操作 (この場合はデモンストレーション目的で手動でトリガーされますが、自動バキューム プロセスも自動的に開始できることに注目すべきです) が実行されます。VACUUM
の役割は、古いバージョンの行を削除して領域を再利用することです。 読み取りレプリカが長いSELECT
ステートメントを実行していることを考えると、現在、VACUUM
が削除の対象としているこれらの行の一部にアクセスしています。- 行の削除を含む
VACUUM
操作によって開始されたこれらの変更は、先書きログ (WAL
) に記録されます。 Azure Database for PostgreSQL フレキシブル サーバーの読み取りレプリカでは、ネイティブ PostgreSQL 物理レプリケーションが利用されるため、これらの変更は後で読み取りレプリカに送信されます。 - この問題の核心は次のとおりです。読み取りレプリカで進行中の
SELECT
ステートメントを認識せずに、読み取りレプリカに必要な行を削除するVACUUM
操作です。 このシナリオでは、いわゆるレプリケーションの競合が発生します。
このシナリオの余波は、VACUUM
操作によって削除された行が原因で、読み取りレプリカでレプリケーションの競合が発生することです。 既定では、max_standby_streaming_delay
の既定値は 30 秒に設定されているため、読み取りレプリカはこの競合を 30 秒間解決しようとします。 この期間が過ぎると、競合が未解決のままである場合、読み取りレプリカのクエリは取り消されます。
原因
この問題の根本原因は、Azure Database for PostgreSQL フレキシブル サーバーの読み取りレプリカが継続的に復旧するシステムであるということです。 この状況は、レプリカがプライマリに追いつきつつある一方で、基本的に継続的な回復状態にあることを意味します。 読み取りレプリカ上のクエリが、復旧プロセスによって同時に更新される行の読み取りを試みる場合 (プライマリが変更を行っているため)、Azure Database for PostgreSQL フレキシブル サーバーはクエリを取り消して、中断することなく復旧を続行できるようにする可能性があります。
解決方法
- 調整
max_standby_streaming_delay
: 読み取りレプリカのmax_standby_streaming_delay
パラメーターを増やします。 設定の値を大きくすると、レプリカがクエリの取り外しを決定する前に競合を解決する時間が長くなります。 ただし、これによりレプリケーションの遅延が増加する可能性があるため、トレードオフになります。 このパラメーターは動的です。つまり、変更はサーバーの再起動を必要とせずに有効になります。 - クエリの監視と最適化: 読み取りレプリカに対して実行されるクエリの種類と頻度を確認します。 実行時間の長いクエリや複雑なクエリは、競合の影響を受けやすくなります。 それらを最適化するか、別の方法でスケジュールすることが役立つ場合があります。
- オフピーク クエリ実行: 競合の可能性を減らすために、ピーク時間外に大量のクエリまたは実行時間の長いクエリを実行することを検討してください。
- 有効化
hot_standby_feedback
: 読み取りレプリカでhot_standby_feedback
をon
に設定することを検討してください。 有効にすると、レプリカによって現在実行されているクエリについてプライマリ サーバーに通知されます。 これにより、レプリカに必要な行がプライマリによって削除されるのを防ぎ、レプリケーションの競合が発生する可能性が低くなります。 このパラメーターは動的です。つまり、変更はサーバーの再起動を必要とせずに有効になります。
注意事項
hot_standby_feedback
を有効にすると、次の潜在的な問題が発生する可能性があります。
- この設定により、プライマリに対して必要なクリーンアップ操作の一部が回避され、テーブルが肥大化する可能性があります (古い行のバージョンがバキュームされていないため、ディスク領域の使用量が増加します)。
- プライマリのディスク領域とテーブル サイズを定期的に監視することが不可欠です。 Azure Database for PostgreSQL フレキシブル サーバーの監視の詳細については、こちらを参照してください。
- 潜在的なテーブルの肥大化が問題になった場合は、手動で管理できるように準備してください。 Azure Database for PostgreSQL フレキシブル サーバーで自動バキューム チューニングを有効にして、この問題を軽減できるようにすることを検討してください。
- 調整
max_standby_archive_delay
:max_standby_archive_delay
サーバー パラメーターは、アーカイブされたWAL
データを読み取るときにサーバーが許可する最大遅延時間を指定します。 Azure Database for PostgreSQL フレキシブル サーバー インスタンスのレプリカがストリーミング モードからファイル ベースのログ配布に切り替わる場合 (まれですが)、この値を調整すると、クエリの取り消しの問題を解決するのに役立ちます。