为 MySQL 配置回退

本页介绍了如何使用反向复制为 MySQL 设置回退。回退是指制定应急计划,以便在遇到 Spanner 相关问题时还原到源 MySQL 数据库。

在遇到意外问题并需要以尽可能少地中断服务的方式回退到原始 MySQL 数据库时,反向复制非常有用。借助反向复制,您可以将写入 Spanner 的数据复制到源 MySQL 数据库,从而实现回退。这可确保两个数据库最终保持一致。

反向复制流程涉及以下步骤(这些步骤由 Spanner_to_SourceDb Dataflow 模板执行):

  1. 使用 Spanner 变更数据流从 Spanner 读取更改。

  2. 确保过滤模式为 forward_migration

  3. 使用 Spanner 迁移工具转换 Spanner 数据,使其与源数据库架构兼容。如需了解详情,请参阅自定义转换

  4. 验证源数据库是否已包含指定主键的最新数据。

  5. 将数据写入源数据库。

使用 Spanner_to_SourceDb Dataflow 模板

Dataflow 模板可确保主键级别的一致性。该模板会在 Spanner 中创建元数据表(称为影子表),其中包含相应表的分片上最后一次写入事务的提交时间戳。

写入操作在主键的提交时间戳之前是一致的。

您可以将执行反向复制的 Dataflow 作业配置为以以下模式之一运行:

  • 常规:这是默认模式。Dataflow 作业从 Spanner 变更数据流中读取事件,将其转换为与源数据库架构兼容的数据类型,然后将其应用于源数据库。作业会自动重试错误。在重试次数用尽后,它会将错误移至 Cloud Storage 存储桶中死信队列 (DLQ) 目录的 severe 文件夹。该作业还会将所有永久性错误移至 severe 文件夹。

  • RetryDLQ:在此模式下,Dataflow 作业会从 DLQ 的 severe 文件夹中读取事件并重试这些事件。在修复所有永久性错误后运行此模式。此模式仅从 DLQ 读取数据,而不从 Spanner 变更数据流读取数据。如果从 severe 文件夹处理的记录被移至 retry 文件夹,作业会重试这些记录。

准备工作

  • 确保源 MySQL 数据库与Google Cloud 项目(Dataflow 作业将在其中运行)之间存在网络连接。

  • 在目标 MySQL 实例上将 Dataflow 工作器 IP 地址列入许可名单。

  • 检查 source shards file 中是否正确指定了 MySQL 凭证。

  • 检查 MySQL 实例是否已上线并正在运行。

  • 验证 MySQL 用户是否对 MySQL 数据库拥有 INSERTUPDATEDELETE 权限。

  • 验证您是否拥有运行 Dataflow Flex 模板所需的 IAM 权限。如需了解详情,请参阅构建和运行灵活模板

  • 验证端口 12345 是否已打开,以便在 Dataflow 工作器虚拟机之间进行通信。

所需的角色

  • 为确保 Compute Engine 服务账号具有启动反向复制所需的权限,请让您的管理员为 Compute Engine 服务账号授予实例的以下 IAM 角色:

运行反向复制

如需运行反向复制,请按以下步骤操作:

  1. 会话文件上传到 Cloud Storage 存储桶。

  2. 为 DLQ 目录的 retry 文件夹创建 Pub/Sub 通知。为此,您可以创建一个 Pub/Sub 主题,并为该主题创建一个 Pub/Sub 订阅

  3. 构建并暂存 Dataflow 模板。如需了解详情,请参阅构建模板

  4. 使用以下 Google Cloud CLI 命令运行反向复制 Dataflow 模板:

      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" \
      --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: Google Cloud 区域。
    • template-file-gcs-location:您暂存 Dataflow 模板的 Cloud Storage 文件路径。
    • changeStreamName:作业从中读取数据的 Spanner 变更数据流的名称。
    • instanceId:Spanner 实例 ID。
    • databaseId:Spanner 数据库 ID。
    • spannerProjectId:Spanner 实例所在的项目 ID。
    • metadataInstance:存储元数据的实例,连接器使用该元数据来控制变更数据流 API 数据的使用。
    • metadataDatabase:存储连接器用于控制变更数据流 API 数据使用情况的元数据的数据库。
    • sourceShardsFilePath:包含源分片连接配置文件信息的 Cloud Storage 文件的路径。

    以下列表介绍了可选变量:

    • startTimestamp:开始读取变更的时间戳。 默认值为空。
    • endTimestamp:读取更改的时间戳上限。如果您未提供时间戳,该进程将无限期地读取更改。默认值为空。
    • shadowTablePrefix:用于命名影子表的前缀。默认值为 shadow_
    • sessionFilePath:Cloud Storage 中会话文件的路径,其中包含 Spanner 迁移工具的映射信息。
    • filtrationMode:用于确定如何根据条件过滤记录的模式。支持的模式为 noneforward_migration
    • shardingCustomJarPath:Cloud Storage 中包含用于提取分片 ID 的逻辑的自定义 JAR 文件的位置(路径)。 默认值为空。
    • shardingCustomClassName:具有自定义分片 ID 实现的完全限定类名。如果指定了 shardingCustomJarPath,则此字段为必填字段。默认值为空。
    • shardingCustomParameters:一个字符串,包含要传递给自定义分片类的任何自定义参数。默认值为空。
    • sourceDbTimezoneOffset:源数据库相对于世界协调时间 (UTC) 的时区偏移量。示例:+10:00。默认值:+00:00。
    • dlqGcsPubSubSubscription:在 regular 模式下运行时,Cloud Storage 通知政策中用于 DLQ 重试目录的 Pub/Sub 订阅。以 projects/<PROJECT_ID>/subscriptions/<SUBSCRIPTION_ID> 格式指定名称。设置此参数后,系统会忽略 deadLetterQueueDirectorydlqRetryMinutes
    • skipDirectoryName:系统在反向复制期间跳过的记录的写入目录。默认值:skip
    • maxShardConnections:每个分片允许的最大连接数。 默认值:10000。
    • deadLetterQueueDirectory:用于存储 DLQ 输出的路径。默认值为 Dataflow 作业的临时位置下的目录。
    • dlqMaxRetryCount:系统通过 DLQ 重试临时错误的次数上限。默认值:500。
    • runMode:运行模式类型。选项为 regularretryDLQ。使用 retryDLQ 仅重试严重 DLQ 记录。默认值:regular
    • dlqRetryMinutes:DLQ 重试之间的分钟数。默认值:10。
    • sourceType:要反向复制到的源数据库的类型。默认值:mysql
    • transformationJarPath:Cloud Storage 中自定义 JAR 文件的位置(路径),其中包含用于处理反向复制中的记录的自定义转换逻辑。默认值为空。
    • transformationClassName:包含自定义转换逻辑的完全限定类名称。如果指定了 transformationJarPath,则此字段为必填字段。默认值为空。
    • transformationCustomParameters:一个字符串,包含要传递给自定义转换类的任何自定义参数。默认值为空。
    • filterEventsDirectoryName:系统在反向复制期间跳过的记录的写入目录。默认值:skip

后续步骤