Esta página explica como configurar o failback para o MySQL usando a replicação reversa. O failback se refere a um plano de contingência para reverter ao banco de dados MySQL de origem se você encontrar problemas com o Spanner.
A replicação reversa é útil quando você encontra problemas inesperados e precisa fazer o failback para o banco de dados MySQL original com o mínimo de interrupção no serviço. A replicação reversa permite fazer o failback replicando os dados gravados no Spanner para o banco de dados MySQL de origem. Isso garante que os dois bancos de dados sejam consistentes.
O fluxo de replicação reversa envolve as etapas a seguir, executadas pelo
Spanner_to_SourceDb modelo do Dataflow:
Leia as mudanças do Spanner usando fluxo de alterações do Spanner.
Verifique se o modo de filtragem é
forward_migration.Transforme os dados do Spanner para que sejam compatíveis com o esquema do banco de dados de origem usando a ferramenta de migração do Spanner. Para mais informações, consulte Transformação personalizada.
Verifique se o banco de dados de origem já contém dados mais recentes para a chave primária especificada.
Grave os dados no banco de dados de origem.
Usar o modelo do Dataflow Spanner_to_SourceDb
O modelo do Dataflow garante a consistência no nível da chave primária. O modelo cria tabelas de metadados, conhecidas como tabelas de sombra, em Spanner que contêm o carimbo de data/hora de confirmação da última transação de gravação no fragmento da tabela.
A gravação é consistente até o carimbo de data/hora de confirmação da chave primária.
É possível configurar o job do Dataflow que executa a replicação reversa para ser executado em um dos seguintes modos:
Normal: esse é o modo padrão. O job do Dataflow lê eventos dos fluxo de alterações do Spanner, os converte em tipos de dados compatíveis com o esquema do banco de dados de origem e os aplica ao banco de dados de origem. O job repete erros automaticamente. Depois de esgotar as repetições, ele move os erros para a pasta
severedo diretório da fila de mensagens inativas (DLQ, na sigla em inglês) no bucket do Cloud Storage. O job também move todos os erros permanentes para a pastasevere.RetryDLQ: nesse modo, o job do Dataflow lê eventos da pasta
severeda DLQ e os repete. Execute esse modo depois de corrigir todos os erros permanentes. Esse modo lê apenas da DLQ e não dos fluxo de alterações do Spanner. Se os registros processados da pastasevereforem movidos para a pastaretry, o job os repetirá.
Antes de começar
Garanta a conectividade de rede entre o banco de dados MySQL de origem e o Google Cloud projeto em que os jobs do Dataflow serão executados.
Permita a lista de endereços IP dos workers do Dataflow na instância de destino do MySQL.
Verifique se as credenciais do MySQL estão especificadas corretamente no
source shards file.Verifique se a instância do MySQL está on-line e em execução.
Verifique se o usuário do MySQL tem privilégios
INSERT,UPDATEeDELETEno banco de dados MySQL.Verifique se você tem as permissões do IAM necessárias para executar um modelo flexível do Dataflow. Para mais informações, consulte Criar e executar um modelo flexível.
Verifique se a porta
12345está aberta para comunicação entre as VMs do worker do Dataflow.
Funções exigidas
-
Para receber as permissões necessárias para iniciar a replicação reversa, peça ao administrador para conceder a você os seguintes papéis do IAM na instância:
- Usuário do banco de dados do Cloud Spanner (
roles/spanner.databaseUser) - Desenvolvedor do Dataflow (
roles/dataflow.developer)
- Usuário do banco de dados do Cloud Spanner (
-
Para garantir que a conta de serviço do Compute Engine tenha as permissões necessárias para iniciar a replicação reversa, peça ao administrador para conceder os seguintes papéis do IAM à conta de serviço do Compute Engine na instância:
- Usuário do banco de dados do Cloud Spanner (
roles/spanner.databaseUser) - Acessador de secrets do Secret Manager (
roles/secretmanager.secretAccessor) - Visualizador do Secret Manager (
roles/secretmanager.viewer)
- Usuário do banco de dados do Cloud Spanner (
Executar a replicação reversa
Para executar a replicação reversa, siga estas etapas:
Faça upload do arquivo de sessão para o bucket do Cloud Storage.
Crie uma notificação do Pub/Sub para a pasta
retrydo diretório da DLQ. Para fazer isso, crie um tópico e uma assinatura do Pub/Sub para esse tópico.Crie e prepare o modelo do Dataflow. Para mais informações, consulte Como criar um modelo.
Execute o modelo do Dataflow de replicação reversa usando o seguinte comando da Google Cloud CLI:
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"]
As variáveis obrigatórias são descritas na lista a seguir:
project: o ID do projeto. Google Cloudregion: a Google Cloud região.template-file-gcs-location: o caminho para o arquivo do Cloud Storage em que você preparou o modelo do Dataflow.changeStreamName: o nome do stream de mudanças do Spanner que o job lê.instanceId: o ID da instância do Spanner.databaseId: o ID do banco de dados do Spanner.spannerProjectId: o ID do projeto em que as instâncias do Spanner residem.metadataInstance: a instância que armazena os metadados que o conector usa para controlar o consumo de dados da API de stream de mudanças.metadataDatabase: o banco de dados que armazena os metadados que o conector usa para controlar o consumo de dados da API de stream de mudanças.sourceShardsFilePath: o caminho para o arquivo do Cloud Storage que contém as informações do perfil de conexão dos fragmentos de origem.
As variáveis opcionais são descritas na lista a seguir:
startTimestamp: o carimbo de data/hora a partir do qual começar a ler as mudanças. O padrão é vazio.endTimestamp: o carimbo de data/hora até o qual ler as mudanças. Se você não fornecer um carimbo de data/hora, o processo vai ler as mudanças indefinidamente. O padrão é vazio.shadowTablePrefix: o prefixo para nomear tabelas de sombra. O padrão éshadow_.sessionFilePath: o caminho para o arquivo de sessão no Cloud Storage que contém informações de mapeamento da ferramenta de migração do Spanner.filtrationMode: o modo que determina como filtrar registros com base em critérios. Os modos compatíveis sãononeouforward_migration.shardingCustomJarPath: o local (caminho) no Cloud Storage do arquivo JAR personalizado que contém a lógica para buscar o ID do fragmento. O padrão é vazio.shardingCustomClassName: o nome de classe totalmente qualificado que tem a implementação personalizada do ID do fragmento. Esse campo é obrigatório seshardingCustomJarPathfor especificado. O padrão é vazio.shardingCustomParameters: uma string contendo os parâmetros personalizados que serão transmitidos para a classe de fragmentação personalizada. O padrão é vazio.sourceDbTimezoneOffset: o deslocamento do fuso horário do banco de dados de origem em relação ao UTC. Exemplo: +10:00. Padrão: +00:00.dlqGcsPubSubSubscription: a assinatura do Pub/Sub usada em uma política de notificação do Cloud Storage para o diretório de repetição de DLQ quando executado no modoregular. Especifique o nome no formatoprojects/<PROJECT_ID>/subscriptions/<SUBSCRIPTION_ID>. Quando você define esse parâmetro, o sistema ignoradeadLetterQueueDirectoryedlqRetryMinutes.skipDirectoryName: o diretório em que o sistema grava os registros que ele ignora durante a replicação reversa. Padrão:skip.maxShardConnections: o número máximo de conexões permitidas por fragmento. Padrão: 10000.deadLetterQueueDirectory: o caminho para armazenar a saída da DLQ. O padrão é um diretório no local temporário do job do Dataflow.dlqMaxRetryCount: o número máximo de vezes que o sistema repete erros temporários pela DLQ. Padrão: 500.runMode: o tipo de modo de execução. As opções sãoregularouretryDLQ. UseretryDLQpara repetir apenas os registros de DLQ graves. Padrão:regular.dlqRetryMinutes: o número de minutos entre as repetições da DLQ. Padrão: 10.sourceType: o tipo de banco de dados de origem para replicação reversa. Padrão:mysql.transformationJarPath: o local (caminho) no Cloud Storage do arquivo JAR personalizado que contém a lógica de transformação personalizada para processar registros na replicação reversa. O padrão é vazio.transformationClassName: o nome de classe totalmente qualificado que tem a lógica de transformação personalizada. Esse campo é obrigatório setransformationJarPathfor especificado. O padrão é vazio.transformationCustomParameters: uma string contendo os parâmetros personalizados que serão transmitidos para a classe de transformação personalizada. O padrão é vazio.filterEventsDirectoryName: o diretório em que o sistema grava os registros que ele ignora durante a replicação reversa. Padrão:skip.