Migrar seus dados do MySQL

Neste documento, explicamos como realizar uma migração de dados em tempo real de uma instância de origem do MySQL para o Spanner com um tempo de inatividade mínimo usando o Terraform para implantar o Dataflow e o Datastream.

Depois de realizar a migração de dados em tempo real e ter certeza de que todos os dados foram transferidos, você terá migrado o código e as dependências e concluído os testes. Em seguida, será possível alternar o aplicativo para usar o Spanner em vez do banco de dados MySQL de origem.

É possível realizar uma migração de dados em tempo real depois de criar o banco de dados de destino do Spanner. É necessário criar um esquema compatível no banco de dados de destino antes de migrar os dados.

Como funciona

A migração de dados ativos consiste nas duas fases a seguir:

  • Migração de preenchimento:

    • Durante a migração de preenchimento, o Dataflow lê os dados existentes do banco de dados MySQL de origem e os migra para o banco de dados Spanner de destino. É preciso usar um modelo de migração em massa do Dataflow para mover os dados da instância de origem do MySQL para o Spanner.
    • Quando a migração de preenchimento não consegue gravar uma linha no Spanner, ela grava essa linha em um diretório de fila de mensagens inativas (DLQ, na sigla em inglês) em um bucket do Cloud Storage. É possível fazer com que a migração de preenchimento tente novamente gravar essas linhas no Spanner.
  • Migração da captura de dados alterados (CDC):

    • Essa fase é executada simultaneamente com a migração de preenchimento, capturando as mudanças que ocorrem na instância de origem do MySQL em tempo real. Essas alterações são aplicadas ao Spanner após a conclusão da migração de preenchimento.
    • Use o Datastream para capturar as mudanças que ocorrem na sua instância de origem do MySQL em tempo real e gravá-las em um bucket do Cloud Storage.
    • Depois que a migração de backfill for concluída, use o Dataflow para mover a CDC do bucket do Cloud Storage para o Spanner. Se o Dataflow não conseguir gravar uma linha no Spanner por qualquer motivo, ele vai gravar essa linha em um diretório de DLQ em um bucket diferente do Cloud Storage. A migração do CDC tenta gravar automaticamente as linhas do diretório DLQ no Spanner.

Planejar a migração de dados em tempo real

É necessário configurar a infraestrutura de rede necessária para que os dados fluam entre a instância de origem do MySQL, o Datastream, o Dataflow, os buckets do Cloud Storage e o banco de dados de destino do Spanner. Recomendamos configurar a conectividade de rede privada para uma migração segura. Dependendo dos requisitos de compliance da sua organização, talvez seja necessário configurar a conectividade de rede pública ou privada. Para mais informações sobre a conectividade do Datastream, consulte Opções de conectividade de rede.

Para planejar a migração de dados em tempo real, talvez seja necessário que o administrador de rede da sua organização realize as seguintes tarefas:

  • Use a VPC padrão ou crie uma nova VPC no projeto com os seguintes requisitos:
    • A instância de origem do MySQL precisa estar disponível nessa VPC. Talvez seja necessário criar uma regra de firewall de saída nessa VPC e uma regra de firewall de entrada na VPC em que a instância de origem do MySQL está localizada.
    • O Datastream, o Dataflow, os buckets do Cloud Storage e o banco de dados de destino do Spanner precisam estar disponíveis nessa VPC.
    • Crie uma lista de permissões na instância de origem do MySQL para permitir conexões da VPC.
  • Determine e aloque um intervalo de endereços IP na VPC que o Datastream pode usar.
  • Crie uma sub-rede na VPC para o Dataflow usar e concluir a migração de backfill.
  • Crie uma sub-rede na VPC para o Dataflow usar e concluir a migração de CDC mais tarde.

Para fazer uma migração de dados em tempo real, siga estas etapas:

  1. Configurar a migração de CDC.
  2. Realize a migração de preenchimento.
  3. Faça a migração de CDC depois que a migração de backfill for concluída.
  4. Monitore e resolva erros de CDC.
  5. Conclua a migração da CDC.

Para fazer a migração de dados ativos, é necessário implantar e gerenciar um número significativo de recursos. O Spanner oferece dois modelos de exemplo do Terraform para cada fase da migração de dados ativos.

O modelo de migração em tempo real realiza a migração de CDC em duas fases:

  • Configurar a migração de CDC para um bucket do Cloud Storage usando o Datastream. É possível usar uma variável do Terraform para impedir que o modelo crie os jobs do Dataflow.
  • Migre a CDC para o Spanner do bucket do Cloud Storage usando o Dataflow. Realize essa fase somente depois que o modelo do Terraform de migração de backfill for concluído.

O modelo do Terraform de migração de preenchimento realiza a migração de preenchimento da instância de origem do MySQL para o Spanner.

Antes de começar

  • Verifique se o Terraform está instalado no shell local.
  • Crie uma conta de serviço para executar a migração de dados ativos. Para mais informações sobre como criar uma conta de serviço, consulte Criar contas de serviço.
  • Para garantir que a conta de serviço tenha as permissões necessárias para realizar a migração em tempo real, peça ao administrador para conceder os seguintes papéis do IAM à conta de serviço no seu projeto:

    Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

    Esses papéis predefinidos contêm as permissões necessárias para realizar a migração em tempo real. Para acessar as permissões exatas necessárias, expanda a seção Permissões necessárias:

    Permissões necessárias

    As seguintes permissões são necessárias para realizar a migração em tempo real:

    • 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

    O administrador também pode conceder essas permissões à conta de serviço com papéis personalizados ou outros papéis predefinidos.

Configurar a migração de CDC

O Spanner oferece um modelo do Terraform que configura a CDC e, depois, conclui a migração da CDC. É possível usar uma variável do Terraform para impedir que o modelo crie os jobs do Dataflow. O modelo do Terraform implanta e gerencia os seguintes recursos para configurar a migração de CDC:

  • Conexão particular do Datastream: uma conexão particular do Datastream é implantada na VPC configurada.

  • Perfil de conexão de origem do Datastream: um perfil de conexão que permite que o Datastream se conecte à sua instância de origem do MySQL.

  • Bucket do Cloud Storage: um bucket do Cloud Storage em que o Datastream grava os dados.

  • Perfil de conexão de destino do Datastream: esse perfil de conexão permite que o Datastream se conecte e grave no bucket do Cloud Storage.

  • Stream do Datastream: um stream do Datastream que lê da sua instância de origem do MySQL e grava no bucket do Cloud Storage conforme definido nos perfis de conexão.

  • Tópico e assinatura do Pub/Sub: o bucket do Cloud Storage envia notificações de objeto para o tópico do Pub/Sub, e o Dataflow consome a assinatura do Pub/Sub para gravar dados no Spanner.

  • Notificações de bucket do Cloud Storage: uma notificação de bucket do Cloud Storage que publica no tópico do Pub/Sub.

Como preparar a configuração do Terraform para CDC

É possível preparar o modelo do Terraform para incluir configurações de variáveis do Dataflow, mas desativar a criação de jobs do 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"
  }
}

Substitua:

  • PROJECT_ID: o ID do projeto do Google Cloud .
  • GCP_REGION: a Google Cloud região em que você quer executar o job do Dataflow.
  • MYSQL_HOST_IP_ADDRESS: o endereço IP da instância de origem do MySQL.
  • MYSQL_USERNAME: o nome de usuário da sua instância de origem do MySQL.
  • MYSQL_PASSWORD: a senha da instância de origem do MySQL.
  • DATABASE_NAME: o nome do banco de dados MySQL de origem na instância.
  • VPC_NAME: o nome de uma VPC usada pelo Datastream.
  • RESERVED_RANGE: o intervalo de endereços IP na VPC que você reservou para o Datastream.
  • SPANNER_DATABASE_ID: o ID do banco de dados de destino do Spanner.
  • SPANNER_INSTANCE_ID: o ID da instância de destino do Spanner.
  • VPC_NETWORK: o nome de uma VPC usada pelo Dataflow.
  • SUBNETWORK_NAME: o nome da sub-rede designada na VPC em que o Dataflow cria workers.

Executar o modelo do Terraform de CDC

Para realizar a migração de CDC, execute o modelo do Terraform:

  1. Inicialize o Terraform usando o seguinte comando:

      terraform init
    

  2. Valide os arquivos do Terraform usando o seguinte comando:

      terraform plan --var-file=terraform_simple.tfvars
    

  3. Execute a configuração do Terraform usando o comando a seguir:

      terraform apply --var-file=terraform_simple.tfvars
    

    A configuração do Terraform produz uma saída semelhante a esta:

    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"
    }
    

O Datastream agora está transmitindo o CDC para um bucket do Cloud Storage. Você precisa realizar a migração de preenchimento e concluir a migração de CDC depois.

Realizar a migração de preenchimento

O Spanner oferece um modelo do Terraform para realizar a migração de preenchimento. O modelo do Terraform implanta e gerencia o seguinte recurso:

  • Job do Dataflow: o job do Dataflow que lê da instância de origem do MySQL e grava no banco de dados de destino do Spanner.

Como preparar a configuração do Terraform para a migração de preenchimento

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"

Substitua:

  • JOB_NAME: o nome do job do Dataflow.
  • PROJECT_ID: o ID do projeto do Google Cloud em que o job do Dataflow é executado.
  • GCP_REGION: a Google Cloud região em que você quer executar o job do Dataflow.
  • WORKING_DIRECTORY_BUCKET: o bucket do Cloud Storage para fazer upload do arquivo de sessão e criar o diretório de saída.
  • WORKING_DIRECTORY_PREFIX: o prefixo do bucket do Cloud Storage para o diretório de trabalho do Dataflow.
  • SOURCE_CONFIG_URL: o endereço IP da instância de origem do MySQL.
  • USERNAME: o nome de usuário da sua instância de origem do MySQL.
  • PASSWORD: a senha da instância de origem do MySQL.
  • SPANNER_INSTANCE_ID: o ID da instância de destino do Spanner.
  • SPANNER_DATABASE_ID: o ID do banco de dados de destino do Spanner.
  • SPANNER_PROJECT_ID: o ID do projeto em que a instância do Spanner reside. Esse ID do projeto pode ser diferente do projeto em que você executa o Dataflow.

Executar o modelo do Terraform de migração de preenchimento

Para realizar a migração de preenchimento, faça o seguinte:

  1. Inicialize o Terraform usando o seguinte comando:

      terraform init
    

  2. Valide os arquivos do Terraform usando o seguinte comando:

      terraform plan --var-file=terraform_simple.tfvars
    

  3. Execute a configuração do Terraform usando o seguinte comando:

      terraform apply --var-file=terraform_simple.tfvars
    

    A configuração do Terraform produz uma saída semelhante a esta:

    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",
    ]
    

Quando a migração de preenchimento não consegue gravar uma linha no Spanner, ela grava essa linha em um diretório de fila de mensagens inativas em um bucket do Cloud Storage.

É possível tentar gravar essas linhas do diretório da fila de mensagens inativas no Spanner antes de concluir a migração de CDC.

Para tentar gravar novamente essas linhas do diretório da fila de mensagens não entregues no Spanner antes de concluir a migração da CDC, execute o seguinte comando:

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

Substitua:

  • JOB_NAME: o nome do job do Dataflow.
  • PROJECT_ID: o ID do projeto Google Cloud em que o job do Dataflow é executado.
  • GCP_REGION: a Google Cloud região em que você quer executar o job do Dataflow.
  • INPUT_FILE_PATTERN: o local do bucket do Cloud Storage do padrão de arquivo de entrada.
  • SOURCE_TYPE: o tipo de banco de dados de origem (por exemplo, mysql).
  • INSTANCE_ID: o ID da instância de destino do Spanner.
  • DATABASE_ID: o ID do banco de dados de destino do Spanner.
  • SESSION_FILE_PATH: o caminho do Cloud Storage para o arquivo de sessão gerado pela ferramenta de migração do Spanner.
  • DLQ_DIRECTORY: o caminho do Cloud Storage para o diretório raiz da fila de mensagens não entregues que contém os arquivos de erro para nova tentativa (por exemplo, gs://MIGRATION_BUCKET/ENV/SERVICE/cdc/DB_SCHEMA/).

Realizar a migração da CDC

Depois que a migração de preenchimento for concluída, use o Dataflow para migrar a CDC para o Spanner. O job do Dataflow recebe os eventos de alteração do bucket do Cloud Storage e os grava no Spanner.

Para realizar a migração de CDC, mude o valor do parâmetro skip_dataflow do Terraform para false e execute novamente o modelo do Terraform de migração em tempo real.

Execute a configuração do Terraform usando o seguinte comando:

      terraform apply --var-file=terraform_simple.tfvars
    

Monitorar e resolver erros de CDC

Durante a replicação da captura de dados alterados (CDC) em tempo real do MySQL para o Spanner, se o job de streaming do Dataflow não puder gravar um evento de alteração no Spanner, ele classificará a falha em uma das duas categorias de erro e gravará o registro em um diretório DLQ no bucket do Cloud Storage deadLetterQueueDirectory:

  • Erros que podem ser repetidos: falhas temporárias, que incluem, entre outras, as seguintes:

    • Erros de prazo excedido do Spanner
    • Violações de restrição de chave externa e tabela intercalada. Isso pode ocorrer quando uma linha filha chega antes da linha pai devido a erros de rede ou processamento paralelo.

    O Dataflow grava esses eventos em um diretório de DLQ retry/ e tenta novamente no mesmo pipeline até que sejam concluídos ou excedam o limite máximo de novas tentativas.

  • Erros graves: falhas permanentes que não podem ser resolvidas por novas tentativas automatizadas, incluindo, entre outros:

    • Erros de conversão de tipo de dados
    • Violações de índice único
    • Exceções em JARs de transformação personalizada

    O Dataflow grava esses eventos em um diretório DLQ severe/ e incrementa o contador de usuários personalizado Total permanent errors.

Como erros graves não podem ser resolvidos por novas tentativas automáticas, o Dataflow remove esses eventos com falha do fluxo de replicação ativo e os salva no diretório severe/. Se não forem processados, o banco de dados de destino do Spanner não terá esses registros. Monitore regularmente o contador Total permanent errors e o diretório severe/ durante a migração em tempo real para resolver e repetir eventos de mudança com falha antes de iniciar a transição do aplicativo.

O contador personalizado do Dataflow Total permanent errors é uma métrica cumulativa que registra o número total de erros graves encontrados desde o início do job de streaming. Quando você repete e resolve registros com falha usando um job de repetição de DLQ, esse contador no pipeline de streaming original não diminui. Portanto, o diretório de DLQ grave do Cloud Storage (gs://.../severe/) é a fonte de verdade oficial para saber se existem erros não processados.

Repetir registros com falha

Quando os registros com falha aparecem no diretório de DLQ grave, inspecione os arquivos JSON de erro no Cloud Storage, identifique a causa raiz e resolva o problema subjacente no Spanner (como inserir manualmente registros principais ausentes ou atualizar mapeamentos de substituição de esquema).

Para repetir os registros de DLQ corrigidos no Spanner, inicie um novo job do Dataflow usando um dos seguintes modos de execução de repetição de DLQ:

  • Modo retryDLQ: execute esse modo como um job em lote junto com o pipeline de streaming ativo para processar arquivos de erro no diretório severe/ sem interromper a replicação de CDC em tempo real.
  • Modo retryAllDLQ: se o pipeline de streaming regular for interrompido, use esse modo para processar os diretórios retry/ e severe/. Não execute retryAllDLQ simultaneamente com um pipeline ativo, porque isso vai causar disputa de arquivos e conflitos de processamento.

Para iniciar um job de nova tentativa de DLQ usando a CLI gcloud, execute o seguinte comando:

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

Substitua:

  • RETRY_JOB_NAME: o nome do job de nova tentativa da DLQ do Dataflow.
  • PROJECT_ID: o ID do projeto do Google Cloud em que o job do Dataflow é executado.
  • GCP_REGION: a Google Cloud região em que você quer executar o job do Dataflow.
  • SOURCE_TYPE: o tipo de banco de dados de origem (por exemplo, mysql).
  • INSTANCE_ID: o ID da instância de destino do Spanner.
  • DATABASE_ID: o ID do banco de dados de destino do Spanner.
  • SESSION_FILE_PATH: o caminho do Cloud Storage para o arquivo de sessão gerado pela ferramenta de migração do Spanner.
  • DLQ_DIRECTORY: o caminho do Cloud Storage para o diretório raiz da fila de mensagens não entregues que contém os arquivos de erro para nova tentativa (por exemplo, gs://MIGRATION_BUCKET/ENV/SERVICE/cdc/DB_SCHEMA/).

Concluir a migração da CDC

Depois que quase todos os dados do bucket do Cloud Storage forem gravados no Spanner, interrompa as gravações na instância de origem do MySQL para permitir que as mudanças restantes sejam gravadas no Spanner.

Isso causa um curto período de inatividade enquanto o Spanner se atualiza com a instância de origem do MySQL. Depois que todas as alterações forem gravadas no Spanner, seu aplicativo poderá começar a usar o Spanner como banco de dados.

Para instruções detalhadas sobre como pausar gravações de aplicativos, drenar dados em trânsito e realizar a substituição de aplicativos, consulte Realizar substituição do MySQL.

A seguir