Eseguire la migrazione dei dati MySQL

Questo documento spiega come eseguire una migrazione dei dati in tempo reale da un'istanza MySQL di origine a Spanner con tempi di inattività minimi utilizzando Terraform per eseguire il deployment di Dataflow e Datastream.

Dopo aver eseguito la migrazione dei dati in tempo reale e aver verificato che tutti i dati siano stati trasferiti, che sia stata eseguita la migrazione del codice e delle dipendenze e che i test siano stati completati, puoi passare all'utilizzo di Spanner anziché del database MySQL di origine.

Puoi eseguire una migrazione dei dati in tempo reale dopo aver creato il database Spanner di destinazione. Prima di eseguire la migrazione dei dati, devi creare uno schema compatibile nel database di destinazione.

Come funziona

La migrazione dei dati in tempo reale è composta dalle seguenti due fasi:

  • Migrazione backfill:

    • Durante la migrazione di backfill, Dataflow legge i dati esistenti dal database MySQL di origine ed esegue la migrazione dei dati al database Spanner di destinazione. Devi utilizzare un modello Dataflow di migrazione collettiva per spostare i dati dall'istanza MySQL di origine a Spanner.
    • Quando la migrazione di backfill non riesce a scrivere una riga in Spanner, scrive la riga in una directory di coda dei messaggi non recapitabili (DLQ) in un bucket Cloud Storage. Puoi fare in modo che la migrazione di backfill riprovi a scrivere queste righe in Spanner.
  • Migrazione con Change Data Capture (CDC):

    • Questa fase viene eseguita contemporaneamente alla migrazione di backfill, acquisendo in tempo reale le modifiche che si verificano nell'istanza MySQL di origine. Queste modifiche vengono quindi applicate a Spanner al termine della migrazione di backfill.
    • Devi utilizzare Datastream per acquisire le modifiche che si verificano nell'istanza MySQL di origine in tempo reale e scriverle in un bucket Cloud Storage.
    • Al termine della migrazione di backfill, devi utilizzare Dataflow per spostare il CDC dal bucket Cloud Storage a Spanner. Se Dataflow non riesce a scrivere una riga in Spanner per qualsiasi motivo, scrive la riga in una directory DLQ in un bucket Cloud Storage diverso. La migrazione CDC ritenta automaticamente la scrittura delle righe dalla directory DLQ a Spanner.

Pianificare la migrazione dei dati live

Devi configurare l'infrastruttura di rete necessaria per il flusso di dati tra l'istanza MySQL di origine, Datastream, Dataflow, i bucket Cloud Storage e il database Spanner di destinazione. Ti consigliamo di configurare la connettività di rete privata per una migrazione sicura. A seconda dei requisiti di conformità della tua organizzazione, potresti dover configurare la connettività di rete pubblica o privata. Per saperne di più sulla connettività di Datastream, consulta Opzioni di connettività di rete.

Per pianificare la migrazione dei dati live, potresti aver bisogno dell'amministratore di rete della tua organizzazione per eseguire le seguenti attività:

  • Utilizza il VPC predefinito o creane uno nuovo nel tuo progetto con i seguenti requisiti:
    • L'istanza MySQL di origine deve essere disponibile su questo VPC. Potresti dover creare una regola firewall in uscita su questo VPC e una regola firewall in entrata sul VPC in cui si trova l'istanza MySQL di origine.
    • Datastream, Dataflow, i bucket Cloud Storage e il database Spanner di destinazione devono essere disponibili su questo VPC.
    • Devi creare una lista consentita nell'istanza MySQL di origine per consentire le connessioni dal VPC.
  • Determina e alloca un intervallo di indirizzi IP nel VPC che Datastream può utilizzare.
  • Crea una subnet nel VPC che Dataflow utilizzerà per completare la migrazione di backfill.
  • Crea una subnet nel VPC da utilizzare per completare la migrazione CDC in un secondo momento.

Per eseguire una migrazione dei dati in tempo reale, segui questi passaggi:

  1. Configura la migrazione CDC.
  2. Esegui la migrazione backfill.
  3. Esegui la migrazione CDC al termine della migrazione backfill.
  4. Monitora e risolvi gli errori CDC.
  5. Completa la migrazione di CDC.

L'esecuzione della migrazione dei dati in tempo reale richiede il deployment e la gestione di un numero significativo di risorse. Spanner fornisce due modelli Terraform di esempio per ogni fase della migrazione dei dati in tempo reale.

Il modello di migrazione live esegue la migrazione CDC in due fasi:

  • Configura la migrazione CDC a un bucket Cloud Storage utilizzando Datastream. Puoi utilizzare una variabile Terraform per impedire al template di creare i job Dataflow.
  • Esegui la migrazione del CDC a Spanner dal bucket Cloud Storage utilizzando Dataflow. Devi eseguire questa fase solo dopo che il modello Terraform di migrazione backfill ha completato la migrazione backfill.

Il modello Terraform di migrazione di backfill esegue la migrazione di backfill dall'istanza MySQL di origine a Spanner.

Prima di iniziare

  • Assicurati che Terraform sia installato nella shell locale.
  • Crea un account di servizio per eseguire la migrazione dei dati live. Per ulteriori informazioni sulla creazione di un account di servizio, consulta Crea service account.
  • Per assicurarti che il account di servizio disponga delle autorizzazioni necessarie per eseguire la migrazione live, chiedi all'amministratore di concedere i seguenti ruoli IAM al account di servizio nel tuo progetto:

    Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.

    Questi ruoli predefiniti contengono le autorizzazioni necessarie per eseguire la migrazione live. Per vedere quali sono esattamente le autorizzazioni richieste, espandi la sezione Autorizzazioni obbligatorie:

    Autorizzazioni obbligatorie

    Per eseguire la migrazione live sono necessarie le seguenti autorizzazioni:

    • 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

    L'amministratore potrebbe anche essere in grado di concedere al account di servizio queste autorizzazioni tramite ruoli personalizzati o altri ruoli predefiniti.

Configurare la migrazione CDC

Spanner offre un template Terraform per configurare il CDC e, in un secondo momento, completare la migrazione CDC. Puoi utilizzare una variabile Terraform per disattivare la creazione dei job Dataflow da parte del modello. Il modello Terraform esegue il deployment e gestisce le seguenti risorse per configurare la migrazione CDC:

  • Connessione privata Datastream: viene eseguito il deployment di una connessione privata Datastream privata sul VPC configurato.

  • Profilo di connessione Datastream di origine: un profilo di connessione che consente a Datastream di connettersi all'istanza MySQL di origine.

  • Bucket Cloud Storage: un bucket Cloud Storage in cui Datastream scrive i dati.

  • Profilo di connessione Datastream di destinazione: questo profilo di connessione consente a Datastream di connettersi e scrivere nel bucket Cloud Storage.

  • Stream Datastream: uno stream Datastream che legge dall'istanza MySQL di origine e scrive nel bucket Cloud Storage, come definito nei profili di connessione.

  • Argomento e sottoscrizione Pub/Sub: il bucket Cloud Storage invia notifiche degli oggetti all'argomento Pub/Sub e Dataflow utilizza la sottoscrizione Pub/Sub per scrivere i dati in Spanner.

  • Notifiche dei bucket Cloud Storage: una notifica del bucket Cloud Storage che pubblica nell'argomento Pub/Sub.

Preparazione della configurazione Terraform di CDC

Puoi preparare il modello Terraform per includere le configurazioni delle variabili Dataflow, ma disattivare la creazione di job 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"
  }
}

Sostituisci quanto segue:

  • PROJECT_ID: l'ID progetto Google Cloud .
  • GCP_REGION: la Google Cloud regione in cui vuoi eseguire il job Dataflow.
  • MYSQL_HOST_IP_ADDRESS: l'indirizzo IP dell'istanza MySQL di origine.
  • MYSQL_USERNAME: il nome utente dell'istanza MySQL di origine.
  • MYSQL_PASSWORD: la password dell'istanza MySQL di origine.
  • DATABASE_NAME: il nome del database MySQL di origine nell'istanza.
  • VPC_NAME: il nome di una VPC esistente utilizzata da Datastream.
  • RESERVED_RANGE: l'intervallo di indirizzi IP sul VPC che hai prenotato per Datastream.
  • SPANNER_DATABASE_ID: l'ID del database Spanner di destinazione.
  • SPANNER_INSTANCE_ID: l'ID dell'istanza Spanner di destinazione.
  • VPC_NETWORK: il nome di un VPC esistente utilizzato da Dataflow.
  • SUBNETWORK_NAME: il nome della subnet designata nel VPC in cui Dataflow crea i worker.

Esegui il template Terraform CDC

Per eseguire la migrazione CDC, devi eseguire il template Terraform:

  1. Inizializza Terraform utilizzando il seguente comando:

      terraform init
    

  2. Convalida i file Terraform utilizzando il seguente comando:

      terraform plan --var-file=terraform_simple.tfvars
    

  3. Esegui la configurazione di Terraform utilizzando questo comando:

      terraform apply --var-file=terraform_simple.tfvars
    

    La configurazione Terraform produce un output simile al seguente:

    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 ora trasmette in streaming la CDC a un bucket Cloud Storage. Devi eseguire la migrazione backfill e completare la migrazione CDC in un secondo momento.

Esegui la migrazione backfill

Spanner offre un modello Terraform per eseguire la migrazione di backfill. Il modello Terraform esegue il deployment e gestisce la seguente risorsa:

  • Job Dataflow: il job Dataflow che legge dall'istanza MySQL di origine e scrive nel database Spanner di destinazione.

Preparazione della configurazione Terraform per la migrazione backfill

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"

Sostituisci quanto segue:

  • JOB_NAME: il nome del job Dataflow.
  • PROJECT_ID: l'ID progetto Google Cloud in cui viene eseguito il job Dataflow.
  • GCP_REGION: la Google Cloud regione in cui vuoi eseguire il job Dataflow.
  • WORKING_DIRECTORY_BUCKET: il bucket Cloud Storage per il caricamento del file di sessione e la creazione della directory di output.
  • WORKING_DIRECTORY_PREFIX: il prefisso del bucket Cloud Storage per la directory di lavoro di Dataflow.
  • SOURCE_CONFIG_URL: l'indirizzo IP dell'istanza MySQL di origine.
  • USERNAME: il nome utente dell'istanza MySQL di origine.
  • PASSWORD: la password dell'istanza MySQL di origine.
  • SPANNER_INSTANCE_ID: l'ID dell'istanza Spanner di destinazione.
  • SPANNER_DATABASE_ID: l'ID del database Spanner di destinazione.
  • SPANNER_PROJECT_ID: l'ID progetto in cui si trova l'istanza Spanner. Questo ID progetto può essere diverso dal progetto in cui esegui Dataflow.

Esegui il template Terraform per la migrazione backfill

Per eseguire la migrazione del backfill:

  1. Inizializza Terraform utilizzando questo comando:

      terraform init
    

  2. Convalida i file Terraform utilizzando il seguente comando:

      terraform plan --var-file=terraform_simple.tfvars
    

  3. Esegui la configurazione di Terraform utilizzando questo comando:

      terraform apply --var-file=terraform_simple.tfvars
    

    La configurazione Terraform produce un output simile al seguente:

    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 la migrazione del backfill non può scrivere una riga in Spanner, la scrive in una directory della coda dei messaggi non recapitabili in un bucket Cloud Storage.

Puoi riprovare a scrivere queste righe dalla directory della coda di messaggi non recapitabili in Spanner prima di completare la migrazione CDC.

Per riprovare a scrivere queste righe dalla directory della coda di messaggi non recapitabili in Spanner prima di completare la migrazione CDC, esegui questo 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"

Sostituisci quanto segue:

  • JOB_NAME: il nome del job Dataflow.
  • PROJECT_ID: l'ID progetto Google Cloud in cui viene eseguito il job Dataflow.
  • GCP_REGION: la Google Cloud regione in cui vuoi eseguire il job Dataflow.
  • INPUT_FILE_PATTERN: la posizione del bucket Cloud Storage del pattern del file di input.
  • SOURCE_TYPE: il tipo di database di origine (ad esempio, mysql).
  • INSTANCE_ID: l'ID dell'istanza Spanner di destinazione.
  • DATABASE_ID: l'ID del database Spanner di destinazione.
  • SESSION_FILE_PATH: il percorso Cloud Storage del file di sessione generato dallo strumento di migrazione di Spanner.
  • DLQ_DIRECTORY: il percorso Cloud Storage della directory principale della coda dei messaggi non recapitabili contenente i file di errore da riprovare (ad esempio, gs://MIGRATION_BUCKET/ENV/SERVICE/cdc/DB_SCHEMA/).

Esegui la migrazione CDC

Al termine della migrazione di backfill, puoi utilizzare Dataflow per eseguire la migrazione del CDC a Spanner. Il job Dataflow prende gli eventi di modifica dal bucket Cloud Storage e li scrive in Spanner.

Per eseguire la migrazione CDC, modifica il valore del parametro Terraform skip_dataflow in false ed esegui nuovamente il modello Terraform di migrazione live.

Esegui la configurazione di Terraform utilizzando questo comando:

      terraform apply --var-file=terraform_simple.tfvars
    

Monitora e risolvi gli errori CDC

Durante la replica live di Change Data Capture (CDC) da MySQL a Spanner, se il job Dataflow di streaming non riesce a scrivere un evento di modifica in Spanner, classifica l'errore in una delle due categorie di errori e scrive il record in una directory DLQ nel bucket Cloud Storage deadLetterQueueDirectory:

  • Errori riproducibili: errori temporanei, che includono, a titolo esemplificativo:

    • Errori di scadenza di Spanner superata
    • Violazioni dei vincoli delle chiavi esterne e delle tabelle con interleaving. Ciò può verificarsi quando una riga secondaria arriva prima della riga principale a causa di errori di rete o dell'elaborazione parallela.

    Dataflow scrive questi eventi in una directory DLQ retry/ e riprova a elaborarli all'interno della stessa pipeline finché non vengono eseguiti correttamente o non superano il limite massimo di tentativi.

  • Errori gravi: errori permanenti che non possono essere risolti tramite nuovi tentativi automatici, tra cui, a titolo esemplificativo:

    • Errori di conversione del tipo di dati
    • Violazioni dell'indice univoco
    • Eccezioni all'interno dei JAR di trasformazione personalizzati

    Dataflow scrive questi eventi in una directory DLQ severe/ e incrementa il contatore utente personalizzato Total permanent errors.

Poiché gli errori gravi non possono essere risolti con i nuovi tentativi automatici, Dataflow rimuove gli eventi non riusciti dallo stream di replica attivo e li salva nella directory severe/. Se non vengono gestiti, questi record non saranno presenti nel database Spanner di destinazione. Monitora regolarmente il contatore Total permanent errors e la directory severe/ durante la migrazione live per risolvere e riprodurre gli eventi di modifica non riusciti prima di avviare il cutover dell'applicazione.

Tieni presente che il contatore personalizzato Dataflow Total permanent errors è una metrica cumulativa che registra il numero totale di errori gravi riscontrati dall'avvio del job di flussi di dati. Quando riproduci e risolvi i record con errori utilizzando un job di ripetizione DLQ, questo contatore nella pipeline di streaming originale non diminuisce. Pertanto, la directory DLQ di Cloud Storage per gli errori gravi (gs://.../severe/) è l'unica fonte di attendibilità per verificare se esistono errori non gestiti.

Riproduci i record non riusciti

Quando i record non riusciti vengono visualizzati nella directory DLQ grave, esamina i file di errore JSON in Cloud Storage, identifica la causa principale e risolvi il problema di fondo in Spanner (ad esempio inserendo manualmente i record principali mancanti o aggiornando le mappature di override dello schema).

Per riprodurre i record DLQ corretti in Spanner, avvia un nuovo job Dataflow utilizzando una delle seguenti modalità di esecuzione dei nuovi tentativi DLQ:

  • Modalità retryDLQ: esegui questa modalità come job batch insieme alla pipeline di streaming attiva per elaborare i file di errore nella directory severe/ senza interrompere la replica CDC in tempo reale.
  • Modalità retryAllDLQ: se la normale pipeline di streaming è interrotta, utilizza questa modalità per elaborare sia la directory retry/ sia la directory severe/. Non eseguire retryAllDLQ contemporaneamente a una pipeline attiva, poiché ciò causerà conflitti di elaborazione e di file.

Per avviare un job di ripetizione DLQ utilizzando gcloud CLI, esegui il seguente 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"

Sostituisci quanto segue:

  • RETRY_JOB_NAME: il nome del job di ripetizione della DLQ di Dataflow.
  • PROJECT_ID: l'ID progetto Google Cloud in cui viene eseguito il job Dataflow.
  • GCP_REGION: la Google Cloud regione in cui vuoi eseguire il job Dataflow.
  • SOURCE_TYPE: il tipo di database di origine (ad esempio, mysql).
  • INSTANCE_ID: l'ID dell'istanza Spanner di destinazione.
  • DATABASE_ID: l'ID del database Spanner di destinazione.
  • SESSION_FILE_PATH: il percorso Cloud Storage del file di sessione generato dallo strumento di migrazione di Spanner.
  • DLQ_DIRECTORY: il percorso Cloud Storage della directory root della coda di messaggi non recapitabili contenente i file di errore da riprovare (ad esempio gs://MIGRATION_BUCKET/ENV/SERVICE/cdc/DB_SCHEMA/).

Completa la migrazione CDC

Dopo che quasi tutti i dati del bucket Cloud Storage sono stati scritti in Spanner, interrompi le scritture nell'istanza MySQL di origine per consentire la scrittura delle modifiche rimanenti in Spanner.

Ciò causa un breve tempo di inattività mentre Spanner si aggiorna all'istanza MySQL di origine. Dopo che tutte le modifiche sono state scritte in Spanner, l'applicazione può iniziare a utilizzare Spanner come database.

Per istruzioni passo passo dettagliate su come mettere in pausa le scritture dell'applicazione, svuotare i dati in transito ed eseguire il cutover dell'applicazione, consulta Esegui il cutover da MySQL.

Passaggi successivi