レプリケーションに関する問題のトラブルシューティング

AlloyDB のアーキテクチャではコンピューティングとストレージが分離されているため、それぞれを個別にスケーリングできます。プライマリ インスタンスと読み取りプール インスタンスは基盤となる同じストレージを共有しますが、レプリケーションは、リードレプリカ間でデータの整合性と鮮度を維持するための重要なプロセスです。AlloyDB クラスタでは、書き込みはプライマリ インスタンスで実行され、共有ストレージの Write-Ahead Log(WAL)に記録されます。これらの変更は、読み取りプール インスタンスのインメモリ キャッシュにレプリケートされます。このレプリケーション プロセスの 2 つの主なステップを理解しておくことは、問題のトラブルシューティングを行ううえで重要です。

  • WAL フラッシュ: データベースの変更を含む Write-Ahead Log(WAL)がプライマリからレプリカに送信されます。その後レプリカが WAL をディスクに即時に永続化します。これらのステップのいずれかで遅延が発生すると、レプリケーション ラグが発生します。この用語(レプリケーション ラグ)は曖昧に聞こえるかもしれません。正確な説明のため、レプリケーション ラグを次の 2 つの要素に分解できます。

  • フラッシュラグまたはネットワーク ラグ: WAL フラッシュ ステップでの遅延です。これは、WAL がプライマリから送信され、レプリカに永続化されるまでにかかる時間です。

  • リプレイラグ: WAL 適用ステップでの遅延です。これは、レプリカが WAL からの変更を適用するのにかかる時間です。

フラッシュラグとリプレイラグのどちらをより重視する必要があるかは、ユースケースによって異なります。

  • クロスリージョン レプリカなどでのデータ損失が懸念される場合は、フラッシュラグに注意する必要があります。WAL がレプリカでまだ永続化されていないときにプライマリがクラッシュする場合、レプリカの観点からみると変更は失われます。
  • リードレプリカのデータの鮮度が懸念される場合は、リプレイラグに注意する必要があります。リプレイラグが大きい場合は、リードレプリカのデータが古くなっています。

レプリケーション ラグを確認する

読み取りプール インスタンスのレプリケーション ラグは、 Google Cloud コンソールでモニタリングできます。詳細については、インスタンスをモニタリングするをご覧ください。また、指標しきい値のアラート ポリシーを作成するの説明に従い、読み取りプールのレプリケーション ラグをモニタリングし、指定したしきい値でアラートを受信することもできます。

レプリケーション ラグの一般的な原因

レプリケーション ラグの一般的な原因と対処方法は次のとおりです。

リソースの競合

レプリケーションの遅延は、CPU やメモリなどのシステム リソースの競合によって発生することもあります。

  • CPU とメモリの負荷: 読み取りプール インスタンスでの読み取りワークロードの負荷が高いと、レプリケーション プロセスとの間で CPU とメモリのリソースを奪い合う可能性があります。インスタンスの CPU とメモリの使用量は、 Google Cloud コンソールで確認できます。リソースの使用量が高い場合は、読み取りプール インスタンスのスケールアップまたはスケールアウトが必要になることがあります。
  • 読み取りプールノードのサイズ: プライマリ インスタンスが読み取りプールノードよりもはるかに大きい場合、レプリケーション ログの生成速度が、読み取りノードでログを処理できる速度を超える可能性があります。このような場合は、サイズの大きい読み取りノードを使用して、レプリカにより多くのリソースを提供することをおすすめします。

レプリケーションの競合

レプリケーション プロセスが待機しているリソースを読み取りクエリが保持しているために、レプリケーション プロセスがブロックされることがあります。たとえば、レプリケーション プロセスが更新する必要があるデータベース オブジェクトが、読み取りクエリによってロックされている場合、ロックが解除されるまでレプリケーションはブロックされます。これは「バッファピンの競合」と呼ばれます。

この競合を特定するには、ログ エクスプローラで postgres.log ファイル内の canceling statement due to conflict with recovery メッセージを探します。

レプリケーションの競合を軽減するための対策として、次の操作を行うことができます。

  • max_standby_streaming_delay を減らす: このパラメータは、レプリケーション プロセスをブロックしているクエリをレプリケーション プロセスがキャンセルするまでの待機時間を決定します。デフォルト値は 30 秒です。この値を小さくすると、レプリケーション ラグを減らすことができますが、キャンセルされる読み取りクエリが増加する可能性があります。このパラメータを調整して、アプリケーションに最適なバランスを見つけます。

  • 長時間実行クエリを回避する: 読み取りプールで長時間実行されるクエリにより、レプリケーションの競合が発生する可能性が高くなることがあります。低レプリケーション ラグがそれほど重要でない別の読み取りプールに長時間実行クエリを移動することを検討してください。

  • alloydb.promote_cancel_to_terminate を有効にする: このフラグはデフォルトでオンになっており、AlloyDB はキャンセル リクエストに応答しないクエリ バックエンドを強制的に終了できます。これにより、応答しないバックエンドがレプリケーションを長期間ブロックするのを防ぐことができます。

読み取りクエリの一時的なスロットリング

AlloyDB では、フラグ google_storage.log_replay_throttle_read_transactions を使用して、読み取りノードで読み取りクエリのラグベース スロットリングを有効にするかどうかを制御することもできます。このパラメータがデフォルト値の on に設定されている場合、レプリケーション ラグが 1 秒を超えると、新しいクエリの開始を一時停止し、新しいバッファを最大 1 分間読み取ることで、読み取りクエリがスロットリングされます。この機能は、リプレイに多くのリソースを割り当てて速度を上げることでレプリケーション ラグを改善しますが、読み取りレイテンシが増加する可能性が生じるというトレードオフがあります。アプリケーションがレプリケーション ラグの影響を受けない場合は、google_storage.log_replay_throttle_read_transactionsoff に設定して、読み取りクエリのレイテンシの改善を優先できます。

クエリ スロットリングの影響は、次の方法でモニタリングできます。

  • ログ: ログ エクスプローラで postgres.log ファイル内の Delayed.*due to replica lag メッセージを検索して、レプリカラグが原因でクエリが遅延している時点を特定します。

  • Cloud Monitoring: alloydb.googleapis.com/instance/postgresql/wait_count 指標を使用して、スロットリングされたクエリの数を確認します。これを行うには、この指標を wait_event_name でフィルタし、HighLagThrottle を探します。クエリがスロットリングされた合計時間を確認するには、同じフィルタで alloydb.googleapis.com/instance/postgresql/wait_time 指標を使用します。詳細については、システム分析情報の指標のリファレンスをご覧ください。

  • Query Insights: レプリケーション ラグが原因でクエリがスロットリングされている場合、Query Insights ダッシュボードの [アクティブなクエリ] ビューの [待機イベント] 列に HighLagThrottle 待機イベントが表示されます。詳細については、アクティブなクエリをモニタリングするをご覧ください。

負荷が高いワークロード

プライマリ インスタンスでの書き込みワークロードが急増すると、大量のレプリケーション ログが生成され、読み取りプール インスタンスが過負荷になり、レプリケーション ラグが発生する可能性があります。プライマリ インスタンスの書き込みトラフィックは、 Google Cloud コンソールでモニタリングできます。

大規模なトランザクション

レコードの COMMITABORT など、多数の行に影響する大規模なトランザクションでは、読み取りプール インスタンスへのレプリケーションに時間がかかることがあります。PostgreSQL 14 では、多数の排他ロックを保持する長時間実行トランザクションが原因で、リードレプリカのメモリ使用量が増加し、最終的に読み取りプール インスタンスがクラッシュする可能性があります。

この問題を軽減するには、プライマリ インスタンスで長時間実行されているトランザクションを終了します。

レプリケーションを妨げる問題のトラブルシューティング

レプリケーション ラグが発生する条件として、機能している読み取りプールが存在していることがあります。以下で説明する問題では、読み取りプールの作成が妨げられるか、またはリードレプリカがクラッシュすることで、レプリケーションが完全に妨げられる可能性があります。

読み取りプールの作成に関する問題

読み取りプールの作成に失敗すると、Cloud Logging の AlloyDB ログに Failed to create read pool メッセージが記録されることがあります。これは、クラスタがストレージの上限に達し、プライマリ インスタンスが追加の容量を割り当てられなくなった場合に発生することがあります。AlloyDB はストレージを自動的にスケーリングしますが、場合によってはストレージを消費している対象を調査して不要なデータを削除するか、サポートに連絡してストレージ割り当ての増加をリクエストする必要があります。

読み取りプール インスタンスのクラッシュ

PostgreSQL 14 では、プライマリ インスタンスで多数の排他ロックを保持する長時間実行トランザクションが原因で、リードレプリカのメモリ使用量が増加し、最終的に読み取りプール インスタンスがクラッシュする可能性があります。

この問題を軽減するには、プライマリ インスタンスで長時間実行されているトランザクションを終了します。

インスタンスのサイズ変更がレプリケーション ラグに与える影響

AlloyDB のストレージ アーキテクチャにより、読み取りプールのフラッシュラグはインスタンスのサイズ変更の影響を受けません。ただし、これはリプレイには適用されません。レプリカのリプレイ能力は、レプリカに対する負荷によって異なります。インスタンス構成を更新した場合(サイズ変更など)、ワークロードによっては、オペレーションの完了時点でレプリカのキャッシュが完全にウォームアップされていないことがあります。つまり、まだキャッシュに保存されていないレコードのリプレイや処理に時間がかかります。その場合、リプレイラグが一時的に増加する可能性があります。