MySQL からのライブデータ移行

このドキュメントでは、Terraform を使用して Dataflow と Datastream をデプロイし、ソース MySQL インスタンスから Spanner にダウンタイムを最小限に抑えてライブデータ移行を行う方法について説明します。

ライブデータ移行を実行し、すべてのデータが転送されたこと、コードと依存関係が移行され、テストが完了したことを確認したら、ソースの MySQL データベースではなく Spanner を使用するようにアプリケーションを切り替えることができます。

移行先の Spanner データベースを作成した後、ライブデータ移行を実行できます。データを移行する前に、移行先データベースに互換性のあるスキーマを作成する必要があります。

仕組み

ライブデータ移行は、次の 2 つのフェーズで構成されます。

  • バックフィル移行:

    • バックフィル移行中、Dataflow はソース MySQL データベースから既存のデータを読み取り、ターゲット Spanner データベースに移行します。ソースの MySQL インスタンスから Spanner にデータを移動するには、一括移行 Dataflow テンプレートを使用する必要があります。
    • バックフィル移行で Spanner への行の書き込みに失敗すると、その行は Cloud Storage バケットのデッドレター キュー ディレクトリに書き込まれます。バックフィル移行で、これらの行の Spanner への書き込みを再試行できます。
  • 変更データ キャプチャ(CDC)の移行:

    • このフェーズはバックフィル移行と同時に実行され、ソース MySQL インスタンスで発生した変更をリアルタイムでキャプチャします。これらの変更は、バックフィル移行の完了後に Spanner に適用されます。
    • Datastream を使用して、ソースの MySQL インスタンスで発生した変更をリアルタイムでキャプチャし、Cloud Storage バケットに書き込む必要があります。
    • バックフィル移行が完了したら、Dataflow を使用して CDC を Cloud Storage バケットから Spanner に移動する必要があります。なんらかの理由で Dataflow が Spanner に行を書き込めなかった場合、その行は別の Cloud Storage バケットのデッドレター キュー ディレクトリに書き込まれます。CDC 移行は、デッドレター キュー ディレクトリから Spanner への行の書き込みを自動的に再試行します。

ライブ データ移行を計画する

ソース MySQL インスタンス、Datastream、Dataflow、Cloud Storage バケット、ターゲット Spanner データベース間でデータが転送されるように、必要なネットワーク インフラストラクチャを構成する必要があります。安全な移行のために、プライベート ネットワーク接続を構成することをおすすめします。組織のコンプライアンス要件によっては、パブリック ネットワークまたはプライベート ネットワークの接続を構成することが必要になる場合があります。Datastream 接続の詳細については、ネットワーク接続オプションをご覧ください。

ライブデータの移行を計画するには、組織のネットワーク管理者が次のタスクを実行する必要があります。

  • デフォルトの VPC を使用するか、プロジェクトに次の要件で新しい VPC を作成します。
    • ソース MySQL インスタンスがこの VPC で使用可能である必要があります。この VPC に下り(外向き)ファイアウォール ルールを作成し、ソース MySQL インスタンスが配置されている VPC に上り(内向き)ファイアウォール ルールを作成する必要がある場合があります。
    • この VPC で Datastream、Dataflow、Cloud Storage バケット、ターゲット Spanner データベースを使用できる必要があります。
    • VPC からの接続を許可するには、移行元の MySQL インスタンスに許可リストを作成する必要があります。
  • Datastream が使用できる VPC 内の IP アドレス範囲を決定して割り振ります。
  • Dataflow がバックフィル移行の完了に使用するサブネットワークを VPC に作成します。
  • 後で CDC 移行を完了するために Dataflow が使用するサブネットを VPC に作成します。

ライブデータの移行は、次の手順で行うことができます。

  1. CDC 移行を設定します
  2. バックフィル移行を実行します
  3. バックフィル移行が完了したら CDC 移行を完了します

ライブデータ マイグレーションを行うには、大量のリソースをデプロイして管理する必要があります。Spanner には、ライブデータ移行の各フェーズに 2 つのサンプル Terraform テンプレートが用意されています。

ライブ マイグレーション テンプレートは、CDC 移行を次の 2 つのフェーズで実行します。

  • Datastream を使用して Cloud Storage バケットへの CDC 移行を設定します。Terraform 変数を使用して、テンプレートが Dataflow ジョブを作成しないようにできます。
  • Dataflow を使用して、Cloud Storage バケットから Spanner に CDC を移行します。このフェーズは、バックフィル移行 Terraform テンプレートでバックフィル移行が完了した後にのみ実行する必要があります。

バックフィル移行 Terraform テンプレートは、ソース MySQL インスタンスから Spanner へのバックフィル移行を実行します。

始める前に

  • Terraform がローカルシェルにインストールされていることを確認します。
  • ライブデータ移行を実行するサービス アカウントを作成します。サービス アカウントの作成の詳細については、サービス アカウントを作成するをご覧ください。
  • ライブ マイグレーションの実行に必要な権限がサービス アカウントに付与されるように、プロジェクトに対する次の IAM ロールをサービス アカウントに付与するよう管理者に依頼してください。

    ロールの付与については、プロジェクト、フォルダ、組織に対するアクセス権の管理をご覧ください。

    これらの事前定義ロールには、ライブ マイグレーションの実行に必要な権限が含まれています。必要とされる正確な権限については、「必要な権限」セクションを開いてご確認ください。

    必要な権限

    ライブ マイグレーションを行うには、次の権限が必要です。

    • compute.globalAddresses.create
    • compute.globalAddresses.createInternal
    • compute.globalAddresses.createInternal
    • compute.globalAddresses.delete
    • compute.globalAddresses.deleteInternal
    • compute.globalAddresses.get
    • compute.globalOperations.get
    • compute.networks.addPeering
    • compute.networks.get
    • compute.networks.listPeeringRoutes
    • compute.networks.removePeering
    • compute.networks.use
    • compute.routes.get
    • compute.routes.list
    • compute.subnetworks.get
    • compute.subnetworks.list
    • dataflow.jobs.cancel
    • dataflow.jobs.create
    • dataflow.jobs.updateContents
    • datastream.connectionProfiles.create
    • datastream.connectionProfiles.delete
    • datastream.privateConnections.create
    • datastream.privateConnections.delete
    • datastream.streams.create
    • datastream.streams.delete
    • datastream.streams.update
    • iam.roles.get
    • iam.serviceAccounts.actAs
    • pubsub.subscriptions.create
    • pubsub.subscriptions.delete
    • pubsub.topics.attachSubscription
    • pubsub.topics.create
    • pubsub.topics.delete
    • pubsub.topics.getIamPolicy
    • pubsub.topics.setIamPolicy
    • resourcemanager.projects.setIamPolicy
    • storage.buckets.create
    • storage.buckets.delete
    • storage.buckets.update
    • storage.objects.delete

    管理者は、サービス アカウントに、カスタムロールや他の事前定義ロールを付与することもできます。

CDC 移行を設定する

Spanner には、CDC を設定し、後で CDC 移行を完了する Terraform テンプレートが用意されています。Terraform 変数を使用して、テンプレートで Dataflow ジョブの作成を無効にできます。Terraform テンプレートは、次のリソースをデプロイして管理し、CDC 移行を設定します。

  • Datastream プライベート接続: 構成された VPC にプライベート Datastream プライベート接続がデプロイされます。

  • ソース Datastream 接続プロファイル: Datastream がソース MySQL インスタンスに接続できるようにする接続プロファイル。

  • Cloud Storage バケット: Datastream がデータを書き込む Cloud Storage バケット。

  • 転送先の Datastream 接続プロファイル: この接続プロファイルを使用すると、Datastream は Cloud Storage バケットに接続して書き込むことができます。

  • Datastream ストリーム: ソース MySQL インスタンスから読み取り、接続プロファイルで定義されているように Cloud Storage バケットに書き込む Datastream ストリーム。

  • Pub/Sub トピックとサブスクリプション: Cloud Storage バケットはオブジェクト通知を Pub/Sub トピックに送信し、Dataflow は Pub/Sub サブスクリプションを使用して Spanner にデータを書き込みます。

  • Cloud Storage バケット通知: Pub/Sub トピックにパブリッシュされる Cloud Storage バケット通知。

CDC Terraform 構成の準備

Terraform テンプレートを準備して Dataflow 変数の構成を含めることができますが、Dataflow ジョブの作成を無効にできます。

    common_params = {
      project = "PROJECT_ID"
      region  = "GCP_REGION"
    }
    datastream_params = {
      mysql_host = "MYSQL_HOST_IP_ADDRESS"
      mysql_username = "MYSQL_USERNAME"
      mysql_password = "MYSQL_PASSWORD"
      mysql_port     = 3306
      mysql_database = {
        database = "DATABASE_NAME"
      }
      private_connectivity = {
        vpc_name = "VPC_NAME"
        range = "RESERVED_RANGE"
      }
    }
    dataflow_params = {
      skip_dataflow = false
      enable_backfill = false
      template_params = {
        spanner_database_id = "SPANNER_DATABASE_ID"
        spanner_instance_id = "SPANNER_INSTANCE_ID"
      }
      runner_params = {
        max_workers = 10
        num_workers = 4
        on_delete   = "cancel"
        network     = "VPC_NETWORK"
        subnetwork  = "SUBNETWORK_NAME"
      }
    }
  

Terraform 変数は次のとおりです。

  • project: Google Cloud プロジェクト ID。
  • region: Google Cloud リージョン。
  • mysql_host: ソース MySQL インスタンスの IP アドレス。
  • mysql_username: ソースの mySQL インスタンスのユーザー名。
  • mysql_password: ソースの mySQL インスタンスのパスワード。
  • mysql_port: ソース MySQL インスタンスのポート番号。
  • database: インスタンス内のソース MySQL データベース名。
  • vpc_name: Datastream で使用される既存の VPC の名前。
  • range: Datastream が使用するために予約した VPC の IP 範囲。
  • skip_dataflow: この値を true に設定すると、Dataflow ジョブの作成が無効になります。
  • enable_backfill: Terraform テンプレートで Dataflow ジョブの作成を無効にするには、この値を false に設定します。
  • spanner_database_id: ターゲット Spanner データベース ID。
  • spanner_instance_id: ターゲット Spanner インスタンス ID。
  • max_workers: Dataflow が作成するワーカーの最大数を決定します。
  • min_workers: Dataflow が作成するワーカーの最大数を決定します。
  • network: Dataflow で使用される既存の VPC の名前。
  • subnetwork: Dataflow がワーカーを作成できる VPC 内の指定されたサブネットワークの名前。

CDC Terraform テンプレートを実行する

CDC 移行を実行するには、Terraform テンプレートを実行する必要があります。

  1. 次のコマンドを使用して Terraform を初期化します。

      terraform init
    

  2. 次のコマンドを使用して、Terraform ファイルを検証します。

      terraform plan --var-file=terraform_simple.tfvars
    

  3. 次のコマンドを使用して Terraform 構成を実行します。

      terraform apply --var-file=terraform_simple.tfvars
    

    Terraform 構成によって、次のような出力が生成されます。

    Outputs:
    resource_ids = {
      "datastream_source_connection_profile" = "source-mysql-thorough-wombat"
      "datastream_stream" = "mysql-stream-thorough-wombat"
      "datastream_target_connection_profile" = "target-gcs-thorough-wombat"
      "gcs_bucket" = "live-migration-thorough-wombat"
      "pubsub_subscription" = "live-migration-thorough-wombat-sub"
      "pubsub_topic" = "live-migration-thorough-wombat"
    }
    resource_urls = {
      "datastream_source_connection_profile" = "https://console.cloud.google.com/datastream/connection-profiles/locations/us-central1/instances/source-mysql-thorough-wombat?project=your-project-here"
      "datastream_stream" = "https://console.cloud.google.com/datastream/streams/locations/us-central1/instances/mysql-stream-thorough-wombat?project=your-project-here"
      "datastream_target_connection_profile" = "https://console.cloud.google.com/datastream/connection-profiles/locations/us-central1/instances/target-gcs-thorough-wombat?project=your-project-here"
      "gcs_bucket" = "https://console.cloud.google.com/storage/browser/live-migration-thorough-wombat?project=your-project-here"
      "pubsub_subscription" = "https://console.cloud.google.com/cloudpubsub/subscription/detail/live-migration-thorough-wombat-sub?project=your-project-here"
      "pubsub_topic" = "https://console.cloud.google.com/cloudpubsub/topic/detail/live-migration-thorough-wombat?project=your-project-here"
    }
    

Datastream が CDC を Cloud Storage バケットにストリーミングするようになりました。バックフィル移行を実行し、CDC 移行を後で完了する必要があります。

バックフィル移行を実行する

Spanner には、バックフィル移行を実行する Terraform テンプレートが用意されています。Terraform テンプレートは、次のリソースをデプロイして管理します。

  • Dataflow ジョブ: ソース MySQL インスタンスから読み取り、ターゲット Spanner データベースに書き込む Dataflow ジョブ。

バックフィル移行の Terraform 構成を準備する

    job_name = "JOB_NAME"
    project = "PROJECT_ID"
    region = "GCP_REGION"
    working_directory_bucket = "WORKING_DIRECTORY_BUCKET"
    working_directory_prefix = "WORKING_DIRECTORY_PREFIX"
    source_config_url = "SOURCE_CONFIG_URL"
    username = "USERNAME"
    password = "PASSWORD"
    instance_id = "SPANNER_INSTANCE_ID"
    database_id  = "SPANNER_DATABASE_ID"
    spanner_project_id = "SPANNER_PROJECT_ID"
  

Terraform 変数は次のとおりです。

  • job_name: Dataflow ジョブ名。
  • project: Dataflow ジョブを実行する必要がある Google Cloud プロジェクト ID。
  • region: Google Cloud リージョン。
  • working_directory_bucket: セッション ファイルをアップロードして出力ディレクトリを作成する Cloud Storage バケット。
  • working_directory_prefix: Dataflow 作業ディレクトリの Cloud Storage バケット接頭辞。
  • source_config_url: ソース MySQL インスタンスの IP アドレス。
  • username: ソースの mySQL インスタンスのユーザー名。
  • password: ソースの mySQL インスタンスのパスワード。
  • instance_id: ターゲット Spanner インスタンス ID。
  • database_id: ターゲット Spanner データベース ID。
  • spanner_project_id: Spanner インスタンスがあるプロジェクト ID。このプロジェクト ID は、Dataflow を実行しているプロジェクトとは異なる場合があります。

バックフィル移行 Terraform テンプレートを実行する

バックフィル移行を実行する手順は次のとおりです。

  1. 次のコマンドを使用して Terraform を初期化します。

      terraform init
    

  2. 次のコマンドを使用して、Terraform ファイルを検証します。

      terraform plan --var-file=terraform_simple.tfvars
    

  3. 次のコマンドを使用して Terraform 構成を実行します。

      terraform apply --var-file=terraform_simple.tfvars
    

    Terraform 構成により、次のような出力が生成されます。

    Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
    Outputs:
    dataflow_job_id = [
      "2024-06-05_00_41_11-4759981257849547781",
    ]
    dataflow_job_url = [
      "https://console.cloud.google.com/dataflow/jobs/gcp-region/2024-06-05_00_41_11-4759981257849547781",
    ]
    

バックフィル移行で Spanner に行を書き込めない場合、その行は Cloud Storage バケットのデッドレター キュー ディレクトリに書き込まれます。

CDC 移行を完了する前に、これらの行をデッドレター キュー ディレクトリから Spanner に書き込むことを再試行できます。

CDC の移行を完了する前に、これらの行をデッドレター キュー ディレクトリから Spanner に書き込むことを再試行するには、次のコマンドを実行します。

gcloud dataflow flex-template run JOB_NAME \
--region=GCP_REGION \
--template-file-gcs-location=gs://dataflow-templates/latest/flex/Cloud_Datastream_to_Spanner \
--additional-experiments=use_runner_v2 \
--parameters inputFilePattern=inputFilePattern,streamName="ignore", \
--datastreamSourceType=SOURCE_TYPE\
instanceId=INSTANCE_ID,databaseId=DATABASE_ID,sessionFilePath=SESSION_FILE_PATH, \
deadLetterQueueDirectory=DLQ_DIRECTORY,runMode="retryDLQ"

gcloud CLI コマンドの変数は次のとおりです。

  • job_name: Dataflow ジョブ名。
  • region: Google Cloud リージョン。
  • inputFilePattern: 入力ファイル パターンの Cloud Storage バケットのロケーション。
  • datastreamSourceType: ソースタイプ(MySQL など)。
  • instanceId: ターゲット Spanner インスタンス ID。
  • databaseId: ターゲット Spanner データベース ID。
  • sessionFilePath: セッション ファイルの Cloud Storage バケットパス。
  • deadLetterQueueDirectory: DLQ ディレクトリへの Cloud Storage バケットパス。

CDC の移行を完了する

バックフィル移行が完了したら、Dataflow を使用して CDC を Spanner に移行できます。Dataflow ジョブは、Cloud Storage バケットから変更イベントを受け取り、Spanner に書き込みます。

Cloud Storage バケットのほぼすべてのデータが Spanner に書き込まれたら、移行元の MySQL インスタンスでの書き込みを停止して、残りの変更を Spanner に書き込みます。

この結果、Spanner がソース MySQL インスタンスに追いつくまでの間、短いダウンタイムが発生します。すべての変更が Spanner に書き込まれたら、アプリケーションは Spanner をデータベースとして使用できます。

CDC の移行を完了するには、skip_dataflow Terraform パラメータの値を false に変更し、ライブ マイグレーションの Terraform テンプレートを再実行します。

次のコマンドを使用して Terraform 構成を実行します。

      terraform apply --var-file=terraform_simple.tfvars
    

次のステップ