レプリケーション ラグ

このページでは、Cloud SQL リードレプリカのレプリケーション ラグのトラブルシューティングと修正方法について説明します。

概要

Cloud SQL リードレプリカは、PostgreSQL ストリーミング レプリケーションを使用します。変更は、プライマリ インスタンスの先行書き込みログ(WAL)に書き込まれます。WAL sender がレプリカの WAL receiver に WAL を送信し、そこで適用されます。

レプリケーション ラグは、次のようないくつかのシナリオで発生する可能性があります。

  • プライマリ インスタンスが、レプリカに変更を十分な速さで送信できない。
  • レプリカが変更を十分な速さで受信できない。
  • レプリカが変更を十分な速さで適用できない。
上記の最初の 2 つの理由は、network_lag 指標でモニタリングできます。3 つめは replica_lag 指標を介してモニタリングされます。replica_lag が高い場合、レプリカがレプリケーションの変更を十分な速さで適用できないことを意味します。合計ラグは、replica_byte_lag 指標を介してモニタリングできます。この指標には詳細を示すラベルがあります。これらの指標については、以下のレプリケーション ラグのモニタリングのセクションで説明します。

クエリとスキーマを最適化する

このセクションでは、レプリケーションのパフォーマンスを改善するためによく実行するクエリとスキーマの最適化について説明します。

リードレプリカでの長時間実行クエリ

レプリカで長時間実行されるクエリが原因で、Cloud SQL のレプリケーションがブロックされる場合があります。オンライン トランザクション処理(OLTP)とオンライン分析処理(OLAP)に別々のレプリカを使用し、長時間実行クエリのみを OLAP レプリカに送信できます。

レプリカの max_standby_archive_delay フラグと max_standby_streaming_delay フラグの調整を検討してください。

VACUUM が原因の可能性があり、クエリのキャンセルが許容されない場合は、レプリカに hot_standby_feedback フラグを設定することを検討してください。

詳細については、PostgreSQL のホット スタンバイのドキュメントをご覧ください。

DDL による排他ロック

データ定義言語(DDL)コマンド(ALTER TABLECREATE INDEX など)では、排他的ロックによってレプリカでレプリケーション ラグが発生することがあります。ロックの競合を回避するには、レプリカでクエリの負荷が低いときに DDL の実行をスケジュールすることを検討してください。

詳細については、PostgreSQL のホット スタンバイのドキュメントをご覧ください。

レプリカの過負荷

リードレプリカが受信するクエリが多すぎると、レプリケーションがブロックされることがあります。読み取りを複数のレプリカに分割して、各レプリカの負荷を減らすことを検討してください。

クエリの急増を回避するには、アプリケーション ロジックまたはプロキシレイヤ(1 つ使用している場合)でレプリカの読み取りクエリを抑制することを検討してください。

プライマリ インスタンスでアクティビティが急増した場合は、更新を分散させることを検討してください。

モノリシックなプライマリ データベース

プライマリ データベースを垂直方向(または水平方向)に分割して、1 つ以上のラグテーブルが他のすべてのテーブルを抑制しないようにすることを検討してください。

レプリケーション ラグをモニタリングする

replica_lag 指標と network_lag 指標を使用してレプリケーション ラグをモニタリングし、ラグの原因がプライマリ データベース、ネットワーク、レプリカのどれにあるのかを識別できます。

指標説明
レプリケーション ラグ
cloudsql.googleapis.com/database/replication/replica_lag

レプリカの状態がプライマリ インスタンスの状態よりも遅れている秒数。これは、現在の時刻と、現在レプリカに適用されているトランザクションをプライマリ データベースが commit した時点のタイムスタンプとの差です。特に、レプリカが書き込みを受信していても、レプリカがデータベースへの書き込みをまだ適用していない場合、書き込みは遅延として記録される可能性があります。

この指標は、レプリカの now() - pg_last_xact_replay_timestamp() を使用して計算されます。これはおおよその値です。レプリケーションが破損していると、レプリカはプライマリ データベースの状態がわからないため、この指標は合計ラグを示しません。

ラグバイト
cloudsql.googleapis.com/database/postgres/replication/replica_byte_lag

プライマリ データベースの状態からのレプリカの状態の遅れ(バイト数)。replica_byte_lag は 4 つの時系列をエクスポートし、replica_lag_type ラベルは次のいずれかを示します。

  • sent_location: WAL が生成されたものの、レプリカにまだ送信されていないバイト数を示します。
  • write_location: 書き込みから送信ラグを差し引いた値が、送信されレプリカでまだ書き込まれていないネットワーク内の WAL バイトを示します。
  • lush_location: フラッシュから書き込みラグを差し引いた値が、レプリカに書き込まれレプリカでまだフラッシュされていない WAL バイトを示します。
  • replay_location: 合計ラグをバイト単位で示します。リプレイからフラッシュラグを差し引いたものがリプレイ遅延を示します。
ネットワーク ラグ
cloudsql.googleapis.com/database/replication/network_lag

プライマリ データベースの commit からレプリカの WAL receiver に到達するまでにかかる時間(秒)。

network_lag がゼロまたはごくわずかであっても、replica_lag が高い場合は、WAL receiver がレプリケーションの変更を迅速に適用できないことを示します。

レプリケーションを検証する

レプリケーションが機能していることを確認するには、レプリカに対して次のステートメントを実行します。

select status, last_msg_receipt_time from pg_stat_wal_receiver;

レプリケーションが行われている場合は、ステータス streaming と最近の last_msg_receipt_time が表示されます。

postgres=> select status, last_msg_receipt_time from pg_stat_wal_receiver;
  status   |     last_msg_receipt_time
-----------+-------------------------------
 streaming | 2020-01-21 20:19:51.461535+00
(1 row)

レプリケーションが行われていない場合、空の結果が返されます。

postgres=> select status, last_msg_receipt_time from pg_stat_wal_receiver;
 status | last_msg_receipt_time
--------+-----------------------
(0 rows)