複製延遲時間

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

總覽

Cloud SQL 唯讀備用資源會使用 MySQL 列式複製功能,並採用全域交易 ID (GTID)。變更會寫入主要執行個體的二進位記錄檔,並傳送至副本,副本會接收變更,然後套用至資料庫。

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

  • 主要執行個體無法快速將變更傳送至副本。
  • 副本無法及時接收變更。
  • 副本無法及時套用變更。
如果主要執行個體無法快速傳送變更,或副本無法快速接收變更,請使用 network_lag 指標監控前兩種情況。

總延遲時間會以 replica_lag 指標表示。replica_lagnetwork_lag 之間的差異,可能表示備用資源無法及時套用複製變更的第三個原因。下方的「監控複寫延遲」一節將說明這些指標。

加快備用資源設定速度

我們提供兩種方法,讓 MySQL 副本更快套用變更。使用者可以透過下列選項設定副本:

  • 平行複製
  • 高效能排空

平行複製

平行複製功能可讓備用資源使用多個平行運作的執行緒,在備用資源上套用變更,有助於解決複製延遲問題。如要瞭解如何使用平行複製功能,請參閱「 設定平行複製功能」。

高效能排空

根據預設,MySQL 適用的 Cloud SQL 會在每筆交易完成後,將重做記錄排清至磁碟。高效能清除作業會將重做記錄檔清除至磁碟的頻率降至每秒一次,進而提升寫入效能。

將唯讀副本的 innodb_flush_log_at_trx_commit 旗標設為 2。您也必須將 sync_binlog 標記設為較高的值,innodb_flush_log_at_trx_commit 標記才會生效。

如要進一步瞭解此標記,請參閱「使用標記的訣竅」。

在唯讀備用資源上設定 innodb_flush_log_at_trx_commit 旗標後,如果 Cloud SQL 偵測到可能發生當機,就會自動重建備用資源。

最佳化查詢和結構定義

本節提供一些常見的查詢和結構定義最佳化建議,可提升複寫效能。

唯讀副本中的查詢隔離等級

REPEATABLE READSERIALIZABLE交易隔離層級會取得可能封鎖複製變更的鎖定。建議您降低副本中查詢的隔離等級。READ COMMITTED交易隔離等級的成效可能較佳。

主要資料庫中長時間執行的交易

如果單一交易更新大量資料列,可能導致需要套用至主要執行個體,然後傳送至副本的變更數量突然暴增。這適用於一次影響多個資料列的單一陳述式更新或刪除作業。變更會在提交後傳送至副本。 如果備用資源的查詢負載也很高,在備用資源中突然套用大量變更,可能會增加備用資源發生鎖定爭用的可能性,導致複製延遲。

建議將大型交易拆分成多筆小型交易。

缺少主鍵

Cloud SQL 唯讀備用資源使用列式複製,如果複製的 MySQL 資料表沒有主索引鍵,效能就會不佳。建議所有複製的資料表都設有主鍵。

如果是 MySQL 8 以上版本,建議將 sql_require_primary_key 旗標設為 ON,要求資料庫中的資料表必須有主鍵。

因 DDL 而鎖定

資料定義語言 (DDL) 指令 (例如 ALTER TABLECREATE INDEX) 可能會因獨占鎖定而導致副本出現複製延遲。為避免鎖定爭用,請考慮在副本的查詢負載較低時,排定 DDL 執行作業。

過載的副本

如果唯讀副本收到太多查詢,複製作業可能會遭到封鎖。 請考慮將讀取作業分散到多個備用資源,以減輕每個資源的負擔。

為避免查詢量暴增,請考慮在應用程式邏輯或 Proxy 層 (如有使用) 中,調節副本讀取查詢。

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

單體式主要資料庫

考慮垂直 (或水平) 分片主要資料庫,避免一或多個延遲資料表拖累所有其他資料表。

監控複製延遲

您可以使用 replica_lagnetwork_lag 指標監控複製延遲,並判斷延遲原因是否在於主要資料庫、網路或副本。

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

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

這個指標會回報在副本上執行 SHOW SLAVE STATUS 時的 Seconds_Behind_Master 值。詳情請參閱 MySQL 參考手冊中的「檢查複製狀態」。

Last I/O thread error number
(cloudsql.googleapis.com/database/mysql/replication/last_io_errno)

指出導致 I/O 執行緒失敗的最後一個錯誤。如果這個值不是零,表示複寫作業已中斷。這種情況並不常見,但仍有可能發生。請參閱 MySQL 說明文件,瞭解錯誤代碼的意義。舉例來說,在副本收到主要執行個體中的 binlog 檔案前,這些檔案可能就已遭刪除。如果複製作業中斷,Cloud SQL 通常會自動重建副本。這項last_io_errno指標可能會說明原因。

Last SQL thread error number
(cloudsql.googleapis.com/database/mysql/replication/last_sql_errno)

指出導致 SQL 執行緒失敗的最後一個錯誤。如果這個值不是零,表示複寫作業已中斷。這種情況並不常見,但仍有可能發生。請參閱 MySQL 說明文件,瞭解錯誤代碼的意義。如果複製作業中斷,Cloud SQL 通常會自動重建副本。這項last_sql_errno指標可說明原因。

網路延遲
(cloudsql.googleapis.com/database/replication/network_lag)

從主要資料庫寫入 binlog 到達副本的 IO 執行緒所需的時間長度 (以秒為單位)。

如果 network_lag 為零或可忽略,但 replica_lag 很高,表示 SQL 執行緒無法快速套用複製變更。

確認複製設定

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

mysql> SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
               Slave_IO_State: Queueing master event to the relay log
                  Master_Host: xx.xxx.xxx.xxx
                  Master_User: cloudsqlreplica
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.199927
          Read_Master_Log_Pos: 83711956
               Relay_Log_File: relay-log.000025
                Relay_Log_Pos: 24214376
        Relay_Master_Log_File: mysql-bin.199898
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 24214163
              Relay_Log_Space: 3128686571
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: Yes
           Master_SSL_CA_File: master_server_ca.pem
           Master_SSL_CA_Path: /mysql/datadir
              Master_SSL_Cert: replica_cert.pem
            Master_SSL_Cipher:
               Master_SSL_Key: replica_pkey.pem
        Seconds_Behind_Master: 2627
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 321071839
                  Master_UUID: 437d04e9-8456-11e8-b13d-42010a80027b
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: System lock
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set: 437d04e9-8456-11e8-b13d-42010a80027b:52111095710-52120776390
            Executed_Gtid_Set: 437d04e9-8456-11e8-b13d-42010a80027b:1-52113039508
                Auto_Position: 1
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)

如果正在進行複製作業,第一欄 Slave_IO_State 會顯示 Waiting for master to send event 或類似訊息。此外,Last_IO_Error 欄位為空白。

如果未發生複製作業,Slave_IO_State 欄會顯示狀態 Connecting to masterLast_IO_Error 欄則會顯示狀態 error connecting to master cloudsqlreplica@x.x.x.x:3306

根據 MySQL 說明文件,與複製延遲相關的其他有趣欄位包括:

欄位說明
Master_Log_File
I/O 執行緒目前讀取的來源二進位記錄檔名稱。
Read_Master_Log_Pos
I/O 執行緒已讀取的目前來源二進位記錄檔位置。
Relay_Log_File
SQL 執行緒目前正在讀取及執行的中繼記錄檔名稱。
Relay_Log_Pos
SQL 執行緒已讀取並執行的目前中繼記錄檔位置。
Relay_Master_Log_File
來源二進位記錄檔的名稱,其中包含 SQL 執行緒執行的最新事件。

在先前的範例中,Relay_Master_Log_File 的值為 mysql-bin.199898Master_Log_File 的值為 mysql-bin.199927,數字後置字元 199898 小於 199927。也就是說,即使副本已收到較新的 mysql-bin.199927 記錄檔,仍會套用較舊的 mysql-bin.199898

在此情況下,SQL 執行緒在副本中會延遲。

您也可以連線至主要資料庫並執行下列指令:

  SHOW MASTER STATUS;

這項指令會顯示主要資料庫中正在寫入的 binlog 檔案。

如果主要資料庫的二進位記錄檔比副本中的 Master_Log_File 新,表示 I/O 執行緒延遲。副本仍在讀取主要資料庫中較舊的二進位記錄檔。

如果 I/O 執行緒延遲,network_lag 指標也會偏高。如果 SQL 執行緒延遲,但 I/O 執行緒沒有,則 network_lag 指標不會太高,但 replica_lag 指標會很高。

先前的指令可讓您在發生延遲時觀察延遲詳細資料,但 network_lagreplica_lag 指標可讓您查看過去發生的延遲。

重新建立落後的副本

如果複製作業延遲的時間超出可接受範圍,請重新建立延遲的副本。

使用 Cloud SQL 時,您可以設定唯讀備用資源,在複製作業延遲超過可接受的時間長度,且延遲時間持續至少五分鐘時,重新建立自身。

如果您將可接受的複寫延遲時間定義為少於 360 秒 (六分鐘),且複寫延遲時間持續超過 361 秒超過五分鐘,則五分鐘後,主要執行個體會建立自身的全新快照,並使用這個快照重新建立唯讀副本。

重新建立延遲的唯讀副本有下列優點:

  • 您可以控管複製延遲的可接受範圍。
  • 您可以減少解決複製延遲問題的時間,節省數小時甚至數天的時間。

其他功能詳細資料適用於:

  • 支援下列版本:
    • MySQL 5.7
    • MySQL 8.0
    • MySQL 8.4
  • 必須以秒為單位定義可接受的複製延遲或延遲範圍。
  • 可接受的最低值為 300 秒或五分鐘。
  • 可接受的最大值為 31,536,000 秒或一年。
    • 如果您為執行個體啟用「重新建立延遲的備用資源」,但未設定可接受的最大複製延遲時間,Cloud SQL 會使用預設值 (一年)。
  • 支援的執行個體類型:
    • 唯讀備用資源
    • 跨區域唯讀備用資源
    • 層疊式備用資源
  • replicationLagMaxSeconds 欄位設定的值適用於每個副本例項。如果主要執行個體有多個副本執行個體,則可以為每個副本設定不同的值。
  • 重建副本時,使用者可能會遇到停機時間,因為系統需要完成下列作業:
    • 複製作業已停止。
    • 已刪除副本。
    • 建立主要執行個體的快照。
    • 系統會根據這個最新快照重新建立副本。新的副本會使用與先前副本相同的名稱和 IP 位址。因此 MySQL 必須停止並重新啟動。
    • 新的副本會開始複製資料。
  • replicationLagMaxSeconds 是執行個體層級的欄位。每個執行個體都有自己的值。
  • 如果同一個主要執行個體有多個唯讀備用資源,您可以為每個備用資源的 replicationLagMaxSeconds 欄位設定唯一值。

    為不同副本定義不同的時間門檻,有助於避免所有副本同時停止運作。

啟用重新建立落後副本

重新建立落後副本功能預設為停用。如要在建立執行個體時啟用這項功能,請使用下列其中一種方法:

gcloud

使用 gcloud sql instances create 指令,搭配
--replication-lag-max-seconds-for-recreate 旗標建立新的唯讀副本執行個體:

gcloud beta sql instances create REPLICA_INSTANCE_NAME \
  --master-instance-name=PRIMARY_INSTANCE_NAME \
  --database-version=DATABASE_VERSION \
  --tier=TIER \
  --edition=EDITION \
  --region=REGION \
  --root-password=PASSWORD \
  --replication-lag-max-seconds-for-recreate=REPLICATION_LAG_MAX_SECONDS

其中:

  • REPLICA_INSTANCE_NAME 是副本執行個體的名稱。
  • PRIMARY_INSTANCE_NAME 是主要執行個體的名稱。
  • DATABASE_VERSION 是執行個體的資料庫版本。例如:MYSQL_8_0_31
  • TIER 是您要用於副本執行個體的機器類型。例如,db-perf-optimized-N-4。詳情請參閱「自訂執行個體設定」。
  • EDITION 是要用於副本執行個體的版本。例如,ENTERPRISE_PLUS。詳情請參閱「建立執行個體」。
  • REGION 是您要用於副本執行個體的區域。例如:us-central1
  • PASSWORD 是執行個體的根密碼。
  • REPLICATION_LAG_MAX_SECONDS 是可接受的複寫延遲時間上限,以秒為單位。例如,600。可接受的最低值為 300 秒或五分鐘。可接受的最大值為 31,536,000 秒或一年。

REST API

replicationLagMaxSeconds 欄位位於 DatabaseInstance 資源中。在要求主體中新增這個欄位:

{
  "settings": {
  "replicationLagMaxSeconds" :REPLICATION_LAG_MAX_SECONDS,
  }
  ...
}

其中:

  • REPLICATION_LAG_MAX_SECONDS 是可接受的複寫延遲時間上限,以秒為單位。例如:600

更新複製延遲的重新建立時間範圍

如要查看執行個體的設定,請使用「查看執行個體摘要資訊」一文所述的任何方法。

有了這項資訊,您就能選擇是否要更新複製延遲時間範圍,也就是在重建副本前可接受的延遲時間。

gcloud

使用 gcloud sql instances patch 指令,根據複寫延遲更新重新建立執行個體的時間範圍:

gcloud beta sql instances patch INSTANCE_NAME \
  --replication-lag-max-seconds-for-recreate=REPLICATION_LAG_MAX_SECONDS

其中:

  • INSTANCE_NAME 是執行個體的名稱。
  • REPLICATION_LAG_MAX_SECONDS 是可接受的複寫延遲時間上限,以秒為單位。例如,700。如要還原為預設值 (一年),請輸入 31536000。可接受的最低值為 300 秒或五分鐘。可接受的最大值為 31,536,000 秒或一年。

REST API

您可以使用 instances.patchinstance.insert 更新政策。

如要查看如何使用 REST API 更新設定的範例,請參閱「編輯執行個體」。

限制

重新建立延遲副本時,請注意下列限制:

  • replicationLagMaxSeconds 的值只能以秒為單位設定。
  • 在重建作業前,於讀取副本上建立的索引不會保留。如果索引存在,請在重建副本後建立次要索引。
  • 為避免唯讀副本經常停機,每個執行個體每天最多只能重新建立一次。
  • 這項功能不支援外部伺服器的副本。
  • 如果您在連鎖備用資源上啟用延遲備用資源的重建功能,Cloud SQL 會先重建葉節點備用資源,以維持複製作業的一致性。
  • 重建跨區域備用資源會產生額外費用
  • 您無法在 Google Cloud 控制台中啟用重新建立落後備用資源。

後續情況: