複製延遲時間

本頁說明如何排解及修正 Cloud SQL 讀取複本的複製延遲問題。

總覽

Cloud SQL 唯讀備用資源會使用 PostgreSQL 串流複寫功能。變更會寫入主要執行個體中的預寫記錄 (WAL)。WAL sender 會將 WAL 傳送至副本中的 WAL receiver,並在該處套用 WAL。

複製延遲可能會在以下情況下發生:

  • 主要執行個體無法將變更內容快速傳送至副本。
  • 副本無法快速接收變更。
  • 副本無法快速套用變更。
上述前兩個原因可透過 network_lag 指標監控。第三個則是透過 replica_lag 指標觀察。replica_lag 值越高,表示複本無法快速套用複製變更。您可以透過 replica_byte_lag 指標查看總延遲時間,該指標會顯示標籤,以便進一步說明詳細資訊。請參閱下方的「監控複製延遲」一節,瞭解這些指標。

最佳化查詢和結構定義

本節將提供一些常見的查詢和結構定義最佳化方式,協助您提升複製效能。

唯讀備用資源中的長時間執行查詢

備用資源中長時間執行的查詢可能會阻斷 Cloud SQL 的複製作業。您可能會為線上交易處理 (OLTP) 和線上分析處理 (OLAP) 建立個別的複本,並只將長時間執行的查詢傳送至 OLAP 複本。

建議您調整複本的 max_standby_archive_delaymax_standby_streaming_delay 標記。

如果您懷疑是 VACUUM 造成問題,且無法接受查詢取消功能,請考慮在複本中設定 hot_standby_feedback 標記。

詳情請參閱 PostgreSQL 說明文件

因 DDL 而產生的專屬鎖定

資料定義語言 (DDL) 指令 (例如 ALTER TABLECREATE INDEX) 可能會因專屬鎖定而導致備援主機的複製延遲。為避免發生鎖定爭用情形,建議您在複本的查詢負載較低時,安排 DDL 執行作業。

詳情請參閱 PostgreSQL 說明文件

備用資源超載

如果讀取副本收到的查詢過多,複製作業可能會遭到封鎖。建議您將讀取作業分散到多個備用資源,以減輕每個備用資源的負載。

為避免查詢量激增,建議您在應用程式邏輯中或代理層 (如有) 中,限制複本讀取查詢。

如果主要執行個體的活動量突然激增,請考慮分散更新作業。

單體式主要資料庫

建議您將主要資料庫進行垂直 (或水平) 分割,以免一或多個延遲的資料表拖慢其他所有資料表。

監控複製延遲時間

您可以使用 replica_lagnetwork_lag 指標監控複製延遲情形,並找出延遲的原因是主要資料庫、網路或備用資料庫。

指標說明
複製延遲時間
(cloudsql.googleapis.com/database/replication/replica_lag)

備用資源的狀態落後於主要執行個體的秒數。這是目前時間與原始時間戳記之間的差異,當初主要資料庫會在該時間戳記時刻,將目前套用在副本上的交易提交。特別是,如果副本尚未將寫入作業套用至資料庫,即使副本已收到寫入作業,系統仍可能將寫入作業計為延遲。

這項指標是使用副本中的 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:Write minus sent lag 會顯示網路中已傳送但尚未寫入複本的 WAL 位元組。
  • flush_location:Flush minus write lag 會顯示在備用資源中寫入但尚未在備用資源中刷新的 WAL 位元組。
  • replay_location:以位元組為單位,顯示總延遲時間。重播時間減去清除延遲時間,表示重播延遲。
網路延遲
(cloudsql.googleapis.com/database/replication/network_lag)

從主要資料庫的提交作業到備援資料庫的 WAL 接收器所需的時間 (以秒為單位)。

如果 network_lag 為零或可忽略,但 replica_lag 很高,表示 WAL 接收器無法快速套用複製變更。

確認複製設定

如要確認複製功能是否正常運作,請針對複本執行下列陳述式:

  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)

後續步驟: