Esta página explica como configurar o fallback para o MySQL através da replicação inversa. O fallback refere-se a um plano de contingência para reverter para a base de dados MySQL de origem se encontrar problemas com o Spanner.
A replicação inversa é útil quando encontra problemas inesperados e precisa de recorrer à base de dados MySQL original com a mínima interrupção do serviço. A replicação inversa permite-lhe fazer um fallback replicando os dados escritos no Spanner para a sua base de dados MySQL de origem. Isto garante que ambas as bases de dados são eventualmente consistentes.
O fluxo de replicação inversa envolve os seguintes passos, executados pelo
Spanner_to_SourceDb modelo do Dataflow:
Leia as alterações do Spanner através de streams de alterações do Spanner.
Certifique-se de que o modo de filtragem é
forward_migration.Transforme os dados do Spanner para serem compatíveis com o esquema da base de dados de origem através da ferramenta de migração do Spanner. Para mais informações, consulte o artigo Transformação personalizada.
Verifique se a base de dados de origem já contém dados mais recentes para a chave primária especificada.
Escreva os dados na base de dados de origem.
Use o modelo do Spanner_to_SourceDb Dataflow
O modelo de fluxo de dados garante a consistência ao nível da chave principal. O modelo cria tabelas de metadados, conhecidas como tabelas de sombra, no Spanner que contêm a data/hora de confirmação da última transação de gravação no fragmento para essa tabela específica.
A gravação é consistente até à data/hora de confirmação da chave primária.
Pode configurar a tarefa do Dataflow que realiza a replicação inversa para ser executada num dos seguintes modos:
Regular: este é o modo predefinido. A tarefa do Dataflow lê eventos de streams de alterações do Spanner, converte-os em tipos de dados compatíveis com o esquema da base de dados de origem e aplica-os à base de dados de origem. A tarefa repete automaticamente os erros. Depois de esgotar as novas tentativas, move os erros para a pasta
severedo diretório da fila de mensagens rejeitadas (DLQ) no contentor do Cloud Storage. A tarefa também move todos os erros permanentes para a pastasevere.RetryDLQ: neste modo, a tarefa do Dataflow lê eventos da pasta
severeda DLQ e tenta novamente processá-los. Execute este modo depois de corrigir todos os erros permanentes. Este modo lê apenas a DLQ e não as streams de alterações do Spanner. Se os registos processados a partir da pastasevereforem movidos para a pastaretry, a tarefa tenta processá-los novamente.
Antes de começar
Certifique-se de que existe conectividade de rede entre a base de dados MySQL de origem e o seuGoogle Cloud projeto, onde os trabalhos do Dataflow vão ser executados.
Adicione os endereços IP dos trabalhadores do Dataflow à lista de autorizações na sua instância do MySQL de destino.
Verifique se as credenciais do MySQL estão corretamente especificadas no elemento
source shards file.Verifique se a instância do MySQL está online e em execução.
Verifique se o utilizador do MySQL tem privilégios
INSERT,UPDATEeDELETEna base de dados do MySQL.Verifique se tem as autorizações de IAM necessárias para executar um modelo flexível do Dataflow. Para mais informações, consulte o artigo Crie e execute um modelo flexível.
Verifique se a porta
12345está aberta para comunicação entre as VMs de trabalho do Dataflow.
Funções necessárias
-
Para receber as autorizações de que precisa para iniciar a replicação inversa, peça ao seu administrador que lhe conceda as seguintes funções de IAM na instância:
-
Utilizador da base de dados do Cloud Spanner (
roles/spanner.databaseUser) -
Programador do Dataflow (
roles/dataflow.developer)
-
Utilizador da base de dados do Cloud Spanner (
-
Para garantir que a conta de serviço do Compute Engine tem as autorizações necessárias para iniciar a replicação inversa, peça ao seu administrador para conceder à conta de serviço do Compute Engine as seguintes funções do IAM na instância:
-
Utilizador da base de dados do Cloud Spanner (
roles/spanner.databaseUser) -
Secret Manager Secret Accessor (
roles/secretmanager.secretAccessor) -
Visitante do Secret Manager (
roles/secretmanager.viewer)
-
Utilizador da base de dados do Cloud Spanner (
Execute a replicação inversa
Para executar a replicação inversa, siga estes passos:
Carregue o ficheiro de sessão para o contentor do Cloud Storage.
Crie uma notificação do Pub/Sub para a pasta
retrydo diretório DLQ. Pode fazê-lo criando um tópico Pub/Sub e uma subscrição Pub/Sub para esse tópico.Crie e prepare o modelo do Dataflow. Para mais informações, consulte o artigo Modelo de criação.
Execute o modelo do Dataflow de replicação inversa com o seguinte comando da CLI do Google Cloud:
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 estão descritas na lista seguinte:
project: o Google Cloud ID do projeto.region: a Google Cloud região.template-file-gcs-location: o caminho para o ficheiro do Cloud Storage onde preparou o modelo do Dataflow.changeStreamName: o nome da stream de alterações do Spanner a partir da qual a tarefa lê.instanceId: o ID da instância do Spanner.databaseId: o ID da base de dados do Spanner.spannerProjectId: o ID do projeto onde residem as suas instâncias do Spanner.metadataInstance: a instância que armazena os metadados que o conetor usa para controlar o consumo de dados da API Change Stream.metadataDatabase: a base de dados que armazena os metadados que o conector usa para controlar o consumo de dados da API Change Stream.sourceShardsFilePath: o caminho para o ficheiro do Cloud Storage que contém as informações do perfil de ligação para os fragmentos de origem.
As variáveis opcionais estão descritas na seguinte lista:
startTimestamp: a data/hora a partir da qual começar a ler as alterações. A predefinição é vazio.endTimestamp: a data/hora até à qual ler as alterações. Se não for fornecida uma data/hora, o processo lê as alterações indefinidamente. O valor predefinido é vazio.shadowTablePrefix: o prefixo para atribuir nomes a tabelas de sombra. A predefinição éshadow_.sessionFilePath: o caminho para o ficheiro 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 os registos com base em critérios. Os modos suportados sãononeouforward_migration.shardingCustomJarPath: a localização (caminho) no Cloud Storage do ficheiro JAR personalizado que contém a lógica para obter o ID do fragmento. A predefinição é vazio.shardingCustomClassName: o nome da classe totalmente qualificado que tem a implementação do ID do fragmento personalizado. Este campo é obrigatório seshardingCustomJarPathfor especificado. A predefinição é vazio.shardingCustomParameters: uma string que contém quaisquer parâmetros personalizados a transmitir à classe de divisão em fragmentos personalizada. A predefinição é vazio.sourceDbTimezoneOffset: o desvio do fuso horário em relação ao UTC para a base de dados de origem. Exemplo: +10:00. Predefinição: +00:00.dlqGcsPubSubSubscription: a subscrição do Pub/Sub usada numa política de notificação do Cloud Storage para o diretório de repetição da DLQ quando executada no modoregular. Especifique o nome no formatoprojects/<PROJECT_ID>/subscriptions/<SUBSCRIPTION_ID>. Quando define este parâmetro, o sistema ignoradeadLetterQueueDirectoryedlqRetryMinutes.skipDirectoryName: o diretório onde o sistema escreve registos que ignora durante a replicação inversa. Predefinição:skip.maxShardConnections: o número máximo de associações permitidas por fragmento. Predefinição: 10 000.deadLetterQueueDirectory: o caminho para armazenar a saída da DLQ. A predefinição é um diretório na localização temporária da tarefa do Dataflow.dlqMaxRetryCount: o número máximo de vezes que o sistema tenta novamente erros temporários através da DLQ. Predefinição: 500.runMode: o tipo de modo de execução. As opções sãoregularouretryDLQ. UseretryDLQpara tentar novamente apenas os registos de DLQ graves. Predefinição:regular.dlqRetryMinutes: o número de minutos entre as novas tentativas da DLQ. Predefinição: 10.sourceType: o tipo de base de dados de origem para a qual a replicação inversa é feita. Predefinição:mysql.transformationJarPath: a localização (caminho) no Cloud Storage do ficheiro JAR personalizado que contém a lógica de transformação personalizada para o processamento de registos na replicação inversa. A predefinição é vazio.transformationClassName: o nome da classe totalmente qualificado que tem a lógica de transformação personalizada. Este campo é obrigatório setransformationJarPathfor especificado. A predefinição é vazio.transformationCustomParameters: uma string que contém quaisquer parâmetros personalizados a transmitir à classe de transformação personalizada. A predefinição é vazio.filterEventsDirectoryName: o diretório onde o sistema escreve registos que ignora durante a replicação inversa. Predefinição:skip.