設定改用 MySQL

本文說明如何使用反向複製功能,為 MySQL 設定備用。如果 Spanner 發生問題,您可透過回溯機制還原至來源 MySQL 資料庫。

如果遇到非預期的問題,需要復原至原始 MySQL 資料庫,同時盡可能減少服務中斷,反向複製功能就非常實用。反向複製功能可讓您在來源 MySQL 資料庫上複製寫入 Spanner 的資料,以便復原。

反向複製流程包含下列步驟,由 Spanner_to_SourceDb Dataflow 範本執行:

  1. 使用 Spanner 變更串流讀取 Spanner 中的變更。

  2. 使用 forward_migration 篩選模式篩選記錄。

  3. 使用 Spanner 遷移工具轉換 Spanner 資料,使其與來源資料庫結構定義相容。詳情請參閱「自訂轉換」。

  4. 請確認來源 MySQL 資料庫是否已包含指定主鍵的最新資料。如果已有較新的資料,管道會略過變更事件,以免覆寫較新的資料。

  5. 將資料寫入來源資料庫。

使用 Spanner_to_SourceDb Dataflow 範本

Dataflow 範本有助於確保主鍵層級的一致性。範本會在 Spanner 中建立中繼資料表 (稱為「影子資料表」),其中包含該特定資料表 shard 上最後一次寫入交易的修訂版本時間戳記。

寫入作業會與主鍵的修訂版本時間戳記保持一致。

反向複製作業會以持續串流的 Dataflow 工作形式執行。這項工作會從 Spanner 變更串流讀取異動事件,轉換為與來源資料庫結構定義相容的資料類型,然後寫入 MySQL 資料庫。如果事件發生暫時性錯誤,工作會透過 Cloud Storage 中的 retry/ 無效信件佇列 (DLQ) 目錄自動重試。如果事件發生永久性錯誤 (或超過重試次數),工作會將事件傳送至 severe/ DLQ 目錄,以供手動解決。如要進一步瞭解如何解決及重新播放失敗的記錄,請參閱「監控及解決反向複製錯誤」。

事前準備

  • 確認來源 MySQL 資料庫與Google Cloud 專案之間的網路連線,Dataflow 工作會在該專案中執行。

  • 將 Dataflow worker IP 位址加入來源 MySQL 執行個體的許可清單。

  • 確認 source shards file 中正確指定 MySQL 憑證。

  • 確認 MySQL 執行個體已連上網路並正在執行。

  • 確認 MySQL 使用者對 MySQL 資料庫具有 INSERT、UPDATE 和 DELETE 權限。

  • 確認您具備執行 Dataflow Flex 範本所需的 IAM 權限。詳情請參閱「建構及執行 Flex 範本」。

  • 確認通訊埠 12345 已開啟,可供 Dataflow worker VM 進行通訊。

必要的角色

  • 為確保 Compute Engine 服務帳戶具備啟動反向複製作業所需的權限,請要求管理員將下列 IAM 角色授予執行個體上的 Compute Engine 服務帳戶:

執行反向複製作業

如要執行反向複製,請按照下列步驟操作:

  1. 將工作階段檔案上傳至 Cloud Storage bucket。

  2. 為 DLQ 目錄的 retry 資料夾建立 Pub/Sub 通知。方法是建立 Pub/Sub 主題,以及該主題的 Pub/Sub 訂閱項目。

  3. 建構並暫存 Dataflow 範本。詳情請參閱「建構範本」。

  4. 如要啟動反向複製串流管道,請執行下列 gcloud dataflow flex-template run 指令:

      gcloud dataflow flex-template run "spanner-to-sourcedb-job" \
      --project "PROJECT" \
      --region "REGION" \
      --template-file-gcs-location "TEMPLATE_SPEC_GCSPATH" \
      --parameters "changeStreamName=CHANGE_STREAM_NAME" \
      --parameters "instanceId=INSTANCE_ID" \
      --parameters "databaseId=DATABASE_ID" \
      --parameters "spannerProjectId=SPANNER_PROJECT_ID" \
      --parameters "metadataInstance=METADATA_INSTANCE" \
      --parameters "metadataDatabase=METADATA_DATABASE" \
      --parameters "sourceShardsFilePath=SOURCE_SHARDS_FILE_PATH" \
      # All flags after this point are optional
      [--parameters "startTimestamp=START_TIMESTAMP"] \
      [--parameters "endTimestamp=END_TIMESTAMP"] \
      [--parameters "shadowTablePrefix=SHADOW_TABLE_PREFIX"] \
      [--parameters "sessionFilePath=SESSION_FILE_PATH"] \
      [--parameters "filtrationMode=FILTRATION_MODE"] \
      [--parameters "shardingCustomJarPath=SHARDING_CUSTOM_JAR_PATH"] \
      [--parameters "shardingCustomClassName=SHARDING_CUSTOM_CLASS_NAME"] \
      [--parameters "shardingCustomParameters=SHARDING_CUSTOM_PARAMETERS"] \
      [--parameters "sourceDbTimezoneOffset=SOURCE_DB_TIMEZONE_OFFSET"] \
      [--parameters "dlqGcsPubSubSubscription=DLQ_GCS_PUB_SUB_SUBSCRIPTION"] \
      [--parameters "skipDirectoryName=SKIP_DIRECTORY_NAME"] \
      [--parameters "maxShardConnections=MAX_SHARD_CONNECTIONS"] \
      [--parameters "deadLetterQueueDirectory=DEAD_LETTER_QUEUE_DIRECTORY"] \
      [--parameters "dlqMaxRetryCount=DLQ_MAX_RETRY_COUNT"] \
      [--parameters "runMode=RUN_MODE"] \
      [--parameters "dlqRetryMinutes=DLQ_RETRY_MINUTES"] \
      [--parameters "sourceType=SOURCE_TYPE"] \
      [--parameters "transformationJarPath=TRANSFORMATION_JAR_PATH"] \
      [--parameters "transformationClassName=TRANSFORMATION_CLASS_NAME"] \
      [--parameters "transformationCustomParameters=TRANSFORMATION_CUSTOM_PARAMETERS"] \
      [--parameters "filterEventsDirectoryName=FILTER_EVENTS_DIRECTORY_NAME"]
    

    以下列出必填變數:

    • PROJECT: Google Cloud 專案 ID。
    • REGION:您要執行 Dataflow 工作的 Google Cloud 區域。
    • TEMPLATE_SPEC_GCSPATH:暫存 Dataflow 範本檔案的 Cloud Storage 路徑。
    • CHANGE_STREAM_NAME:作業讀取資料的 Spanner 變更串流名稱。
    • INSTANCE_ID:Spanner 執行個體 ID。
    • DATABASE_ID:Spanner 資料庫 ID。
    • SPANNER_PROJECT_ID:Spanner 執行個體所在的專案 ID。
    • METADATA_INSTANCE:Spanner 執行個體,用於儲存連接器控制變更串流 API 資料用量時所需的中繼資料。
    • METADATA_DATABASE:Spanner 資料庫,用於儲存連接器控制變更串流 API 資料消耗量時使用的中繼資料。
    • SOURCE_SHARDS_FILE_PATH:包含來源分片連線設定檔資訊的 Cloud Storage 路徑。

    下表列出選用變數:

    • START_TIMESTAMP:開始讀取變更的時間戳記。預設為空白。
    • END_TIMESTAMP:讀取變更的時間戳記。如未指定,程序會無限期讀取變更。預設為空白。
    • SHADOW_TABLE_PREFIX:命名影子資料表的前置字串。預設值:shadow_。
    • SESSION_FILE_PATH:Cloud Storage 中工作階段檔案的路徑,內含 Spanner 遷移工具的對應資訊。
    • FILTRATION_MODE:根據條件篩選記錄的方式。支援的模式為 none 和 forward_migration。
    • SHARDING_CUSTOM_JAR_PATH:自訂 JAR 檔案在 Cloud Storage 中的位置 (路徑),該檔案包含擷取 shard ID 的邏輯。預設為空白。
    • SHARDING_CUSTOM_CLASS_NAME:具有自訂分片 ID 實作項目的完整類別名稱。如果指定 SHARDING_CUSTOM_JAR_PATH,則必須提供這項參數。預設為空白。
    • SHARDING_CUSTOM_PARAMETERS:包含要傳遞至自訂資料分割類別的任何自訂參數的字串。預設為空白。
    • SOURCE_DB_TIMEZONE_OFFSET:來源資料庫與世界標準時間的時區偏移量。例如,+10:00。預設值:+00:00。
    • DLQ_GCS_PUB_SUB_SUBSCRIPTION:在 regular 模式下執行時,用於 DLQ 重試目錄的 Cloud Storage 通知政策中的 Pub/Sub 訂閱項目。請按照 projects/<PROJECT_ID>/subscriptions/<SUBSCRIPTION_ID> 格式指定名稱。設定這個參數時,系統會忽略 deadLetterQueueDirectory 和 dlqRetryMinutes。
    • SKIP_DIRECTORY_NAME:系統在反向複製期間略過記錄時,會將記錄寫入這個目錄。預設:skip。
    • MAX_SHARD_CONNECTIONS:每個 shard 允許的連線數量上限。預設:10000。
    • DEAD_LETTER_QUEUE_DIRECTORY:用於儲存 DLQ 輸出的路徑。預設值是 Dataflow 工作暫時位置下的目錄。
    • DLQ_MAX_RETRY_COUNT:系統透過 DLQ 重試暫時性錯誤的次數上限。預設值:500。
    • RUN_MODE:執行模式類型。支援的選項為 regular、retryDLQ 和 retryAllDLQ。使用 retryDLQ,在作用中的管道旁重試 severe/ 目錄中的錯誤記錄,或在一般管道停止時,使用 retryAllDLQ 處理 retry/ 和 severe/ 目錄。預設值:regular。
    • DLQ_RETRY_MINUTES:DLQ 重試間隔時間 (以分鐘為單位)。預設:10。
    • SOURCE_TYPE:要反向複製到的來源資料庫類型。預設值:mysql。
    • TRANSFORMATION_JAR_PATH:自訂 JAR 檔案在 Cloud Storage 中的位置 (路徑),該檔案包含用於處理反向複製記錄的自訂轉換邏輯。預設為空白。
    • TRANSFORMATION_CLASS_NAME:具有自訂轉換邏輯的完整類別名稱。如果指定 TRANSFORMATION_JAR_PATH,則必須提供這項參數。預設為空白。
    • TRANSFORMATION_CUSTOM_PARAMETERS:字串,內含要傳遞至自訂轉換類別的任何自訂參數。預設為空白。
    • FILTER_EVENTS_DIRECTORY_NAME:Cloud Storage 中的目錄,系統會將自訂反向轉換邏輯篩除的記錄寫入此處。預設值:filteredEvents。

監控及解決反向複製錯誤

從 Spanner 執行反向複製作業回到 MySQL 時,如果串流 Dataflow 工作無法將變更事件寫入 MySQL 主要資料庫,系統會將失敗歸類為下列其中一種類別,並將記錄寫入 Cloud Storage 值區中的死信佇列目錄:

  • 可重試錯誤:暫時性失敗,例如 MySQL 資料庫鎖定爭用或網路連線逾時。Dataflow 會將這些事件寫入retry/死信佇列目錄,並在同一管道中自動重試,直到成功或超過dlqMaxRetryCount為止。
  • 嚴重錯誤:無法透過自動重試解決的永久性錯誤,例如資料類型轉換錯誤、語法錯誤,或自訂轉換 JAR 中的例外狀況。Dataflow 會將這些事件寫入 severe/ 無效信件佇列目錄 (例如 gs://MIGRATION_BUCKET/ENV/SERVICE/reverse/DB_SCHEMA/severe/),並遞增自訂使用者計數器 severe_error_count。

由於嚴重錯誤無法透過自動重試解決,Dataflow 會從有效的複製串流中移除這些失敗的事件,並將其儲存在 severe/ 目錄中。如果不處理,復原的 MySQL 資料庫就會缺少這些記錄。在反向複製期間,請定期監控 severe_error_count 計數器和 severe/ 目錄,以便在啟動回溯前解決並重新播放失敗的變更事件。

Dataflow 自訂計數器 severe_error_count 是累計指標,會記錄串流工作啟動以來發生的嚴重錯誤總數。使用 DLQ 重試工作重播及解決失敗記錄時,原始串流管道上的這個計數器不會遞減。因此,Cloud Storage 嚴重 DLQ 目錄 (gs://MIGRATION_BUCKET/ENV/SERVICE/reverse/DB_SCHEMA/severe/) 是判斷是否存在未處理錯誤的權威資訊來源。

重播失敗的記錄

如果嚴重 DLQ 目錄中出現失敗記錄,請檢查 Cloud Storage 中的 JSON 錯誤檔案,找出根本原因並解決潛在問題。

如要將修正後的 DLQ 記錄重播至 MySQL,請使用下列其中一種執行模式啟動新的 Dataflow 工作:

  • retryDLQ 模式:與現有的串流管道一起以批次工作形式執行此模式,處理 severe/ 目錄中的錯誤檔案,不會中斷即時反向複製作業。解決嚴重錯誤的根本原因後,請執行這個模式。
  • retryAllDLQ 模式:如果一般串流管道已停止,請使用這個模式處理 retry/ 和 severe/ 目錄。請勿在管道執行期間同時執行 retryAllDLQ,否則會導致檔案爭用和處理衝突。

如要使用 gcloud CLI 啟動反向複製 DLQ 重試工作,請執行下列指令:

gcloud dataflow flex-template run "spanner-to-sourcedb-retry-job" \
    --project "PROJECT" \
    --region "REGION" \
    --template-file-gcs-location "TEMPLATE_SPEC_GCSPATH" \
    --parameters "changeStreamName=CHANGE_STREAM_NAME" \
    --parameters "instanceId=INSTANCE_ID" \
    --parameters "databaseId=DATABASE_ID" \
    --parameters "spannerProjectId=SPANNER_PROJECT_ID" \
    --parameters "metadataInstance=METADATA_INSTANCE" \
    --parameters "metadataDatabase=METADATA_DATABASE" \
    --parameters "sourceShardsFilePath=SOURCE_SHARDS_FILE_PATH" \
    --parameters "deadLetterQueueDirectory=DLQ_DIRECTORY" \
    --parameters "runMode=retryDLQ"

更改下列內容:

  • PROJECT: Google Cloud 專案 ID。
  • REGION:您要執行 Dataflow 工作的 Google Cloud 區域。
  • TEMPLATE_SPEC_GCSPATH:暫存 Dataflow 範本檔案的 Cloud Storage 路徑。
  • CHANGE_STREAM_NAME:工作讀取的 Spanner 變更串流名稱。
  • INSTANCE_ID:Spanner 執行個體 ID。
  • DATABASE_ID:Spanner 資料庫 ID。
  • SPANNER_PROJECT_ID:Spanner 執行個體所在的專案 ID。
  • METADATA_INSTANCE:Spanner 執行個體,用於儲存連接器控制變更串流 API 資料用量時所需的中繼資料。
  • METADATA_DATABASE:Spanner 資料庫,用於儲存連接器控制變更串流 API 資料消耗量時使用的中繼資料。
  • SOURCE_SHARDS_FILE_PATH:Cloud Storage 路徑,其中包含來源 shard 的連線設定檔資訊。
  • DLQ_DIRECTORY:Cloud Storage 路徑,指向含有嚴重錯誤檔案的無效信件佇列目錄,以便重試。

後續步驟