Questo documento descrive come configurare il fallback per MySQL utilizzando la replica inversa. Il fallback si riferisce a un piano di emergenza per ripristinare il database MySQL di origine in caso di problemi con Spanner.
La replica inversa è utile quando si verificano problemi imprevisti ed è necessario eseguire il fallback al database MySQL originale con un'interruzione minima del servizio. La replica inversa consente di eseguire il fallback replicando i dati scritti in Spanner nel database MySQL di origine.
Il flusso di replica inversa prevede i seguenti passaggi, eseguiti dal
Spanner_to_SourceDb modello Dataflow:
Leggi le modifiche da Spanner utilizzando i flussi di modifiche di Spanner.
Filtra i record utilizzando la modalità di filtro
forward_migration.Trasforma i dati di Spanner in modo che siano compatibili con lo schema del database di origine utilizzando lo strumento di migrazione di Spanner. Per saperne di più, consulta Trasformazione personalizzata.
Verifica se il database MySQL di origine contiene già dati più recenti per la chiave primaria specificata. Se esistono già dati più recenti, la pipeline salta l'evento di modifica per evitare di sovrascrivere i dati più recenti.
Scrivi i dati nel database di origine.
Utilizza il modello Dataflow Spanner_to_SourceDb
Il modello Dataflow contribuisce a garantire la coerenza a livello di chiave primaria. Il modello crea tabelle di metadati, note come tabelle shadow, in Spanner che contengono il timestamp di commit dell'ultima transazione di scrittura sullo shard per quella tabella specifica.
La scrittura è coerente fino al timestamp di commit della chiave primaria.
La replica inversa viene eseguita come un job Dataflow di streaming continuo.
Il job legge gli eventi di modifica dai flussi di modifiche in tempo reale di Spanner, li converte in tipi di dati compatibili con lo schema del database di origine e li scrive nel database MySQL. Se un evento rileva un errore temporaneo, il job lo ritenta automaticamente tramite una directory della coda di messaggi non recapitabili (DLQ) retry/ in Cloud Storage. Se un evento rileva un errore permanente (o supera i tentativi di ripetizione), il job lo indirizza a una directory DLQ severe/ per la risoluzione manuale. Per saperne di più sulla risoluzione e sulla riproduzione dei record non riusciti,
consulta Monitorare e risolvere gli errori di replica inversa.
Prima di iniziare
Verifica la connettività di rete tra il database MySQL di origine e il tuo Google Cloud progetto in cui vengono eseguiti i job Dataflow.
Aggiungi gli indirizzi IP dei worker Dataflow alla lista consentita nell'istanza MySQL di origine.
Verifica che le credenziali MySQL siano specificate correttamente nel
source shards file.Verifica che l'istanza MySQL sia online e in esecuzione.
Verifica che l'utente MySQL disponga dei privilegi
INSERT,UPDATEeDELETEsul database MySQL.Verifica di disporre delle autorizzazioni IAM necessarie per eseguire un modello flessibile Dataflow. Per saperne di più, consulta Creare ed eseguire un template flessibile.
Verifica che la porta
12345sia aperta per la comunicazione tra le VM worker Dataflow.
Ruoli obbligatori
-
Per ottenere le autorizzazioni necessarie per avviare la replica inversa, chiedi all'amministratore di concederti i seguenti ruoli IAM sull'istanza:
- Utente del database Cloud Spanner (
roles/spanner.databaseUser) - Sviluppatore Dataflow (
roles/dataflow.developer)
- Utente del database Cloud Spanner (
-
Per assicurarti che il account di servizio Compute Engine disponga delle autorizzazioni necessarie per avviare la replica inversa, chiedi all'amministratore di concedere i seguenti ruoli IAM al account di servizio Compute Engine sull'istanza:
- Utente del database Cloud Spanner (
roles/spanner.databaseUser) - Accessore ai secret di Secret Manager (
roles/secretmanager.secretAccessor) - Visualizzatore di Secret Manager (
roles/secretmanager.viewer)
- Utente del database Cloud Spanner (
Esegui la replica inversa
Per eseguire la replica inversa:
Carica il file di sessione nel bucket Cloud Storage.
Crea una notifica Pub/Sub per la cartella
retrydella directory DLQ. Puoi farlo creando un Pub/Sub argomento e una Pub/Sub sottoscrizione per quell'argomento.Crea e archivia il modello Dataflow. Per saperne di più, consulta Creazione di un modello.
Per avviare la pipeline di streaming di replica inversa, esegui il seguente comando
gcloud dataflow flex-template run: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" \ # All flags after this point are optional [--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"]
Le variabili obbligatorie sono descritte nel seguente elenco:
PROJECT: l' Google Cloud ID progetto.REGION: la Google Cloud regione in cui vuoi eseguire il job Dataflow.TEMPLATE_SPEC_GCSPATH: il percorso di Cloud Storage del file del modello Dataflow archiviato.CHANGE_STREAM_NAME: il nome del flusso di modifiche in tempo reale di Spanner da cui legge il job.INSTANCE_ID: l'ID istanza Spanner.DATABASE_ID: l'ID database Spanner.SPANNER_PROJECT_ID: l'ID progetto in cui risiedono le istanze Spanner.METADATA_INSTANCE: l'istanza Spanner che archivia i metadati utilizzati dal connettore per controllare il consumo dei dati dell'API modifiche in tempo reale.METADATA_DATABASE: il database Spanner che archivia i metadati utilizzati dal connettore per controllare il consumo dei dati dell'API modifiche in tempo reale.SOURCE_SHARDS_FILE_PATH: il percorso di Cloud Storage che contiene le informazioni del profilo di connessione per gli shard di origine.
Le variabili facoltative sono descritte nel seguente elenco:
START_TIMESTAMP: il timestamp da cui iniziare a leggere le modifiche. Il valore predefinito è vuoto.END_TIMESTAMP: il timestamp fino al quale leggere le modifiche. Se non specificato, il processo legge le modifiche a tempo indeterminato. Il valore predefinito è vuoto.SHADOW_TABLE_PREFIX: il prefisso per la denominazione delle tabelle shadow. Valore predefinito:shadow_.SESSION_FILE_PATH: il percorso del file di sessione in Cloud Storage che contiene le informazioni di mapping dello strumento di migrazione di Spanner.FILTRATION_MODE: la modalità che determina come filtrare i record in base ai criteri. Le modalità supportate sonononeeforward_migration.SHARDING_CUSTOM_JAR_PATH: la posizione (percorso) in Cloud Storage del file JAR personalizzato che contiene la logica per recuperare l'ID shard. Il valore predefinito è vuoto.SHARDING_CUSTOM_CLASS_NAME: il nome completo della classe che ha l'implementazione dell'ID shard personalizzato. Questo parametro è obbligatorio se viene specificatoSHARDING_CUSTOM_JAR_PATH. Il valore predefinito è vuoto.SHARDING_CUSTOM_PARAMETERS: una stringa contenente eventuali parametri personalizzati da passare alla classe di sharding personalizzata. Il valore predefinito è vuoto.SOURCE_DB_TIMEZONE_OFFSET: l'offset del fuso orario rispetto all'UTC per il database di origine. Ad esempio,+10:00. Valore predefinito:+00:00.DLQ_GCS_PUB_SUB_SUBSCRIPTION: la sottoscrizione Pub/Sub utilizzata in una policy di notifica di Cloud Storage per la directory di tentativi della DLQ quando viene eseguita in modalitàregular. Specifica il nome nel formatoprojects/<PROJECT_ID>/subscriptions/<SUBSCRIPTION_ID>. Quando imposti questo parametro, il sistema ignoradeadLetterQueueDirectoryedlqRetryMinutes.SKIP_DIRECTORY_NAME: la directory in cui il sistema scrive i record che salta durante la replica inversa. Valore predefinito:skip.MAX_SHARD_CONNECTIONS: il numero massimo di connessioni consentite per shard. Valore predefinito:10000.DEAD_LETTER_QUEUE_DIRECTORY: il percorso per l'archiviazione dell'output della DLQ. Il valore predefinito è una directory nella posizione temporanea del job Dataflow.DLQ_MAX_RETRY_COUNT: il numero massimo di volte in cui il sistema ritenta gli errori temporanei tramite la DLQ. Valore predefinito:500.RUN_MODE: il tipo di modalità di esecuzione. Le opzioni supportate sonoregular,retryDLQeretryAllDLQ. UtilizzaretryDLQper ritentare i record di errore dalla directorysevere/insieme a una pipeline attiva oppureretryAllDLQper elaborare le directoryretry/esevere/quando la pipeline normale è arrestata. Valore predefinito:regular.DLQ_RETRY_MINUTES: il numero di minuti tra i tentativi della DLQ. Valore predefinito:10.SOURCE_TYPE: il tipo di database di origine in cui eseguire la replica inversa. Valore predefinito:mysql.TRANSFORMATION_JAR_PATH: la posizione (percorso) in Cloud Storage del file JAR personalizzato che contiene la logica di trasformazione personalizzata per l'elaborazione dei record nella replica inversa. Il valore predefinito è vuoto.TRANSFORMATION_CLASS_NAME: il nome completo della classe che ha la logica di trasformazione personalizzata. Questo parametro è obbligatorio se viene specificatoTRANSFORMATION_JAR_PATH. Il valore predefinito è vuoto.TRANSFORMATION_CUSTOM_PARAMETERS: una stringa contenente eventuali parametri personalizzati da passare alla classe di trasformazione personalizzata. Il valore predefinito è vuoto.FILTER_EVENTS_DIRECTORY_NAME: la directory in Cloud Storage in cui il sistema scrive i record filtrati dalla logica di trasformazione inversa personalizzata. Valore predefinito:filteredEvents.
Monitorare e risolvere gli errori di replica inversa
Quando esegui la replica inversa da Spanner a MySQL, se il job Dataflow di streaming non riesce a scrivere un evento di modifica nel database primario MySQL, classifica l'errore in una delle due categorie e scrive il record in una directory della coda di messaggi non recapitabili nel bucket Cloud Storage:
- Errori ripetibili: errori temporanei, come la contesa di blocco del database MySQL
o i timeout di connessione di rete. Dataflow scrive questi eventi in una directory della coda di messaggi non recapitabili
retry/e li ritenta automaticamente all'interno della stessa pipeline finché non vanno a buon fine o superanodlqMaxRetryCount. - Errori gravi: errori permanenti che non possono essere risolti mediante tentativi automatici
, come errori di conversione del tipo di dati, errori di sintassi o eccezioni
all'interno dei file JAR di trasformazione personalizzata. Dataflow scrive questi eventi
in una directory della coda di messaggi non recapitabili
severe/(ad esempio,gs://MIGRATION_BUCKET/ENV/SERVICE/reverse/DB_SCHEMA/severe/) e incrementa il contatore utente personalizzatosevere_error_count.
Poiché gli errori gravi non possono essere risolti mediante tentativi automatici, Dataflow rimuove questi eventi non riusciti dal flusso di replica attivo e li salva nella directory severe/. Se non vengono gestiti, nel database MySQL di rollback mancheranno questi record. Monitora regolarmente il contatore severe_error_count e la directory severe/ durante la replica inversa in modo da poter risolvere e riprodurre gli eventi di modifica non riusciti prima di avviare un rollback.
Il contatore personalizzato Dataflow severe_error_count è una metrica cumulativa che registra il numero totale di errori gravi rilevati dall'avvio del job di streaming. Quando riproduci e risolvi i record non riusciti utilizzando un job di tentativi della DLQ, questo contatore nella pipeline di streaming originale non diminuisce. Pertanto, la directory DLQ grave di Cloud Storage (gs://MIGRATION_BUCKET/ENV/SERVICE/reverse/DB_SCHEMA/severe/) è l'origine autorevole per verificare se esistono errori non gestiti.
Riproduci i record non riusciti
Quando i record non riusciti vengono visualizzati nella directory DLQ grave, ispeziona i file di errore JSON in Cloud Storage, identifica la causa principale e risolvi il problema sottostante.
Per riprodurre i record DLQ corretti in MySQL, avvia un nuovo job Dataflow utilizzando una delle seguenti modalità di esecuzione:
- Modalità
retryDLQ: esegui questa modalità come job batch insieme alla pipeline di streaming attiva per elaborare i file di errore nella directorysevere/senza interrompere la replica inversa live. Esegui questa modalità dopo aver risolto le cause principali degli errori gravi. - Modalità
retryAllDLQ: se la pipeline di streaming normale è arrestata, utilizza questa modalità per elaborare le directoryretry/esevere/. Non eseguireretryAllDLQcontemporaneamente a una pipeline attiva, in quanto ciò causerebbe conflitti di file e di elaborazione.
Per avviare un job di tentativi della DLQ di replica inversa utilizzando gcloud CLI, esegui il seguente comando:
gcloud dataflow flex-template run "spanner-to-sourcedb-retry-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 "deadLetterQueueDirectory=DLQ_DIRECTORY" \
--parameters "runMode=retryDLQ"
Sostituisci quanto segue:
PROJECT: l' Google Cloud ID progetto.REGION: la Google Cloud regione in cui vuoi eseguire il job Dataflow.TEMPLATE_SPEC_GCSPATH: il percorso di Cloud Storage del file del modello Dataflow archiviato.CHANGE_STREAM_NAME: il nome del flusso di modifiche in tempo reale di Spanner da cui legge il job.INSTANCE_ID: l'ID istanza Spanner.DATABASE_ID: l'ID database Spanner.SPANNER_PROJECT_ID: l'ID progetto in cui risiedono le istanze Spanner.METADATA_INSTANCE: l'istanza Spanner che archivia i metadati utilizzati dal connettore per controllare il consumo dei dati dell'API modifiche in tempo reale.METADATA_DATABASE: il database Spanner che archivia i metadati utilizzati dal connettore per controllare il consumo dei dati dell'API modifiche in tempo reale.SOURCE_SHARDS_FILE_PATH: il percorso di Cloud Storage che contiene le informazioni del profilo di connessione per gli shard di origine.DLQ_DIRECTORY: il percorso di Cloud Storage della directory della coda di messaggi non recapitabili contenente i file di errore gravi da ritentare.