Migra tus datos de MySQL

En este documento, se explica cómo realizar una migración de datos en vivo de una instancia de MySQL de origen a Spanner con un tiempo de inactividad mínimo usando Terraform para implementar Dataflow y Datastream.

Una vez que realices la migración de datos en vivo y tengas la certeza de que se transfirieron todos tus datos, hayas migrado tu código y dependencias, y completado las pruebas, puedes cambiar tu aplicación para que use Spanner en lugar de tu base de datos de MySQL de origen.

Puedes realizar una migración de datos en vivo después de crear la base de datos de Spanner de destino. Debes crear un esquema compatible en tu base de datos de destino antes de migrar los datos.

Cómo funciona

La migración de datos en vivo consta de las siguientes dos fases:

  • Migración de reabastecimiento:

    • Durante la migración de reabastecimiento, Dataflow lee los datos existentes de tu base de datos de MySQL de origen y los migra a la base de datos de Spanner de destino. Debes usar una plantilla de Dataflow de migración masiva para mover los datos de tu instancia de MySQL de origen a Spanner.
    • Cuando la migración de relleno falla al escribir una fila en Spanner, escribe esa fila en un directorio de cola de mensajes no entregados (DLQ) en un bucket de Cloud Storage. Puedes hacer que la migración de reabastecimiento vuelva a intentar escribir estas filas en Spanner.
  • Migración de la captura de datos modificados (CDC):

    • Esta fase se ejecuta de forma simultánea con la migración de reabastecimiento, lo que captura los cambios que se producen en la instancia de MySQL de origen en tiempo real. Luego, estos cambios se aplican a Spanner después de que se completa la migración de reabastecimiento.
    • Debes usar Datastream para capturar los cambios que se producen en tu instancia de MySQL de origen en tiempo real y escribirlos en un bucket de Cloud Storage.
    • Una vez que se complete la migración de reabastecimiento, deberás usar Dataflow para mover la CDC del bucket de Cloud Storage a Spanner. Si Dataflow no puede escribir una fila en Spanner por cualquier motivo, la escribe en un directorio de DLQ en un bucket de Cloud Storage diferente. La migración de CDC vuelve a intentar escribir automáticamente las filas del directorio de DLQ en Spanner.

Planifica la migración de datos en vivo

Debes configurar la infraestructura de red necesaria para que los datos fluyan entre tu instancia de MySQL de origen, Datastream, Dataflow, los buckets de Cloud Storage y la base de datos de Spanner de destino. Te recomendamos que configures la conectividad de red privada para una migración segura. Según los requisitos de cumplimiento de tu organización, es posible que debas configurar la conectividad de red pública o privada. Para obtener más información sobre la conectividad de Datastream, consulta Opciones de conectividad de red.

Para planificar la migración de datos en vivo, es posible que necesites que el administrador de red de tu organización realice las siguientes tareas:

  • Usa la VPC predeterminada o crea una nueva en tu proyecto con los siguientes requisitos:
    • La instancia de MySQL de origen debe estar disponible en esta VPC. Es posible que debas crear una regla de firewall de salida en esta VPC y una regla de firewall de entrada en la VPC en la que se encuentra la instancia de MySQL de origen.
    • Datastream, Dataflow, los buckets de Cloud Storage y la base de datos de destino de Spanner deben estar disponibles en esta VPC.
    • Debes crear una lista de entidades permitidas en tu instancia de MySQL de origen para permitir conexiones desde la VPC.
  • Determina y asigna un rango de direcciones IP en la VPC que Datastream pueda usar.
  • Crea una subred en la VPC para que Dataflow la use para completar la migración de reabastecimiento.
  • Crea una subred en la VPC para que Dataflow la use para completar la migración de CDC más adelante.

Para realizar una migración de datos en vivo, sigue estos pasos:

  1. Configura la migración de CDC.
  2. Realiza la migración de reabastecimiento.
  3. Realiza la migración de CDC después de que finalice la migración de reabastecimiento.
  4. Supervisa y resuelve errores de CDC.
  5. Finaliza la migración de la CDC.

Para realizar la migración de datos en vivo, se debe implementar y administrar una cantidad significativa de recursos. Spanner proporciona dos plantillas de Terraform de muestra para cada fase de la migración de datos en vivo.

La plantilla de migración en vivo realiza la migración de CDC en dos fases:

  • Configura la migración de CDC a un bucket de Cloud Storage con Datastream. Puedes usar una variable de Terraform para evitar que la plantilla cree los trabajos de Dataflow.
  • Migra los datos de CDC a Spanner desde el bucket de Cloud Storage con Dataflow. Debes realizar esta fase solo después de que la plantilla de Terraform de migración de carga inicial haya finalizado la migración de carga inicial.

La plantilla de Terraform de migración de reabastecimiento realiza la migración de reabastecimiento desde tu instancia de MySQL de origen a Spanner.

Antes de comenzar

  • Asegúrate de que Terraform esté instalado en tu shell local.
  • Crea una cuenta de servicio para ejecutar la migración de datos en vivo. Para obtener más información sobre cómo crear una cuenta de servicio, consulta Crea cuentas de servicio.
  • Para garantizar que la cuenta de servicio tenga los permisos necesarios para realizar la migración en vivo, pídele a tu administrador que le otorgue los siguientes roles de IAM a la cuenta de servicio en tu proyecto:

    Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.

    Estos roles predefinidos contienen los permisos necesarios para realizar la migración en vivo. Para ver los permisos exactos que son necesarios, expande la sección Permisos requeridos:

    Permisos necesarios

    Se requieren los siguientes permisos para realizar la migración en vivo:

    • 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

    Es posible que tu administrador también pueda otorgar estos permisos a la cuenta de servicio con roles personalizados o con otros roles predefinidos.

Configura la migración de CDC

Spanner ofrece una plantilla de Terraform para configurar la CDC y, luego, completar la migración de CDC. Puedes usar una variable de Terraform para inhabilitar la plantilla y que no cree los trabajos de Dataflow. La plantilla de Terraform implementa y administra los siguientes recursos para configurar la migración de CDC:

  • Conexión privada de Datastream: Se implementa una conexión privada de Datastream en tu VPC configurada.

  • Perfil de conexión de Datastream de origen: Es un perfil de conexión que permite que Datastream se conecte a tu instancia de MySQL de origen.

  • Bucket de Cloud Storage: Es un bucket de Cloud Storage en el que Datastream escribe los datos.

  • Perfil de conexión de Datastream de destino: Este perfil de conexión permite que Datastream se conecte y escriba en el bucket de Cloud Storage.

  • Transmisión de Datastream: Es una transmisión de Datastream que lee desde tu instancia de MySQL de origen y escribe en el bucket de Cloud Storage, como se define en los perfiles de conexión.

  • Tema y suscripción de Pub/Sub: El bucket de Cloud Storage envía notificaciones de objetos al tema de Pub/Sub y Dataflow consume la suscripción de Pub/Sub para escribir datos en Spanner.

  • Notificaciones de buckets de Cloud Storage: Es una notificación de bucket de Cloud Storage que se publica en el tema de Pub/Sub.

Prepara la configuración de Terraform del CDC

Puedes preparar la plantilla de Terraform para incluir parámetros de configuración de variables de Dataflow, pero inhabilitar la creación de trabajos de 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"
  }
}

Reemplaza lo siguiente:

  • PROJECT_ID: Es el ID del proyecto de Google Cloud .
  • GCP_REGION: la Google Cloud región en la que deseas ejecutar el trabajo de Dataflow.
  • MYSQL_HOST_IP_ADDRESS: Es la dirección IP de tu instancia de MySQL de origen.
  • MYSQL_USERNAME: el nombre de usuario de tu instancia de MySQL de origen.
  • MYSQL_PASSWORD: Es la contraseña de tu instancia de MySQL de origen.
  • DATABASE_NAME: Es el nombre de tu base de datos de MySQL de origen en la instancia.
  • VPC_NAME: Es el nombre de una VPC existente que usa Datastream.
  • RESERVED_RANGE: Es el rango de direcciones IP en la VPC que reservaste para Datastream.
  • SPANNER_DATABASE_ID: Es el ID de la base de datos de Spanner de destino.
  • SPANNER_INSTANCE_ID: Es el ID de la instancia de Spanner de destino.
  • VPC_NETWORK: Es el nombre de una VPC existente que usa Dataflow.
  • SUBNETWORK_NAME: Es el nombre de la subred designada en la VPC en la que Dataflow crea trabajadores.

Ejecuta la plantilla de Terraform de CDC

Para realizar la migración de CDC, debes ejecutar la plantilla de Terraform:

  1. Inicializa Terraform con el siguiente comando:

      terraform init
    

  2. Valida los archivos de Terraform con el siguiente comando:

      terraform plan --var-file=terraform_simple.tfvars
    

  3. Ejecuta la configuración de Terraform con el siguiente comando:

      terraform apply --var-file=terraform_simple.tfvars
    

    La configuración de Terraform produce un resultado similar al siguiente:

    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 ahora transmite la CDC a un bucket de Cloud Storage. Debes realizar la migración de reabastecimiento y finalizar la migración de CDC más adelante.

Realiza la migración de reabastecimiento

Spanner ofrece una plantilla de Terraform para realizar la migración de relleno. La plantilla de Terraform implementa y administra el siguiente recurso:

  • Trabajo de Dataflow: Es el trabajo de Dataflow que lee desde la instancia de MySQL de origen y escribe en la base de datos de Spanner de destino.

Cómo preparar la configuración de Terraform para la migración de relleno

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"

Reemplaza lo siguiente:

  • JOB_NAME: Es el nombre del trabajo de Dataflow.
  • PROJECT_ID: Es el ID del proyecto Google Cloud en el que se ejecuta el trabajo de Dataflow.
  • GCP_REGION: Es la región de Google Cloud en la que deseas ejecutar el trabajo de Dataflow.
  • WORKING_DIRECTORY_BUCKET: Es el bucket de Cloud Storage para subir el archivo de sesión y crear el directorio de salida.
  • WORKING_DIRECTORY_PREFIX: Es el prefijo del bucket de Cloud Storage para el directorio de trabajo de Dataflow.
  • SOURCE_CONFIG_URL: Es la dirección IP de tu instancia de MySQL de origen.
  • USERNAME: Es el nombre de usuario de tu instancia de MySQL de origen.
  • PASSWORD: la contraseña de tu instancia de MySQL de origen.
  • SPANNER_INSTANCE_ID: Es el ID de la instancia de Spanner de destino.
  • SPANNER_DATABASE_ID: Es el ID de la base de datos de Spanner de destino.
  • SPANNER_PROJECT_ID: Es el ID del proyecto en el que reside tu instancia de Spanner. Este ID del proyecto puede ser diferente del proyecto en el que ejecutas Dataflow.

Ejecuta la plantilla de Terraform de migración de reabastecimiento

Para realizar la migración de reabastecimiento, haz lo siguiente:

  1. Inicializa Terraform con el siguiente comando:

      terraform init
    

  2. Valida los archivos de Terraform con el siguiente comando:

      terraform plan --var-file=terraform_simple.tfvars
    

  3. Ejecuta la configuración de Terraform con el siguiente comando:

      terraform apply --var-file=terraform_simple.tfvars
    

    La configuración de Terraform produce un resultado similar al siguiente:

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

Cuando la migración de carga inicial no puede escribir una fila en Spanner, la escribe en un directorio de cola de mensajes no entregados en un bucket de Cloud Storage.

Puedes volver a intentar escribir estas filas desde el directorio de la cola de mensajes no entregados en Spanner antes de finalizar la migración de CDC.

Para volver a intentar escribir estas filas desde el directorio de la cola de mensajes no entregados en Spanner antes de finalizar la migración de CDC, ejecuta el siguiente 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"

Reemplaza lo siguiente:

  • JOB_NAME: Es el nombre del trabajo de Dataflow.
  • PROJECT_ID: Es el ID del proyecto Google Cloud en el que se ejecuta el trabajo de Dataflow.
  • GCP_REGION: la Google Cloud región en la que deseas ejecutar el trabajo de Dataflow.
  • INPUT_FILE_PATTERN: Es la ubicación del bucket de Cloud Storage del patrón de archivo de entrada.
  • SOURCE_TYPE: Es el tipo de base de datos de origen (por ejemplo, mysql).
  • INSTANCE_ID: Es el ID de la instancia de Spanner de destino.
  • DATABASE_ID: Es el ID de la base de datos de Spanner de destino.
  • SESSION_FILE_PATH: Es la ruta de acceso de Cloud Storage al archivo de sesión que generó la herramienta de migración de Spanner.
  • DLQ_DIRECTORY: Es la ruta de acceso de Cloud Storage al directorio raíz de la cola de mensajes no entregados que contiene los archivos de error que se volverán a intentar (por ejemplo, gs://MIGRATION_BUCKET/ENV/SERVICE/cdc/DB_SCHEMA/).

Realiza la migración de CDC

Una vez que se complete la migración de reabastecimiento, puedes usar Dataflow para migrar la CDC a Spanner. El trabajo de Dataflow toma los eventos de cambio del bucket de Cloud Storage y los escribe en Spanner.

Para realizar la migración de CDC, cambia el valor del parámetro skip_dataflow de Terraform a false y vuelve a ejecutar la plantilla de Terraform de migración en vivo.

Ejecuta la configuración de Terraform con el siguiente comando:

      terraform apply --var-file=terraform_simple.tfvars
    

Supervisa y resuelve errores de CDC

Durante la replicación de la captura de datos modificados (CDC) en vivo de MySQL a Spanner, si tu trabajo de transmisión de Dataflow no puede escribir un evento de cambio en Spanner, clasifica la falla en una de las dos categorías de error y escribe el registro en un directorio de DLQ en el bucket de Cloud Storage deadLetterQueueDirectory:

  • Errores que se pueden reintentar: Son fallas temporales, que incluyen, entre otras, las siguientes:

    • Errores de plazo excedido de Spanner
    • Incumplimientos de restricciones de claves externas y tablas intercaladas Esto puede ocurrir cuando una fila secundaria llega antes que su fila superior debido a errores de red o procesamiento paralelo.

    Dataflow escribe estos eventos en un directorio de DLQ de retry/ y los vuelve a intentar dentro de la misma canalización hasta que se completen correctamente o superen el límite máximo de reintentos.

  • Errores graves: Son fallas permanentes que no se pueden resolver con reintentos automáticos, que incluyen, entre otros, los siguientes:

    • Errores de conversión de tipos de datos
    • Incumplimientos de índices únicos
    • Excepciones dentro de los JAR de transformación personalizados

    Dataflow escribe estos eventos en un directorio de DLQ de severe/ y aumenta el contador de usuarios personalizado de Total permanent errors.

Debido a que los errores graves no se pueden resolver con reintentos automáticos, Dataflow quita esos eventos con errores del flujo de replicación activo y los guarda en el directorio severe/. Si no se controla, la base de datos de Spanner de destino no tendrá esos registros. Supervisa con regularidad el contador Total permanent errors y el directorio severe/ durante la migración en vivo para que puedas resolver y volver a reproducir los eventos de cambio con errores antes de iniciar la migración de sistemas de la aplicación.

Ten en cuenta que el contador personalizado de Dataflow Total permanent errors es una métrica acumulativa que registra la cantidad total de errores graves que se encontraron desde que se inició el trabajo de transmisión. Cuando reproduces y resuelves registros con errores con un trabajo de reintento de DLQ, este contador en tu canalización de transmisión original no disminuye. Por lo tanto, tu directorio de DLQ grave de Cloud Storage (gs://.../severe/) es la fuente autorizada de información para determinar si existen errores no controlados.

Vuelve a reproducir los registros con errores

Cuando aparezcan registros con errores en tu directorio de DLQ grave, inspecciona los archivos de error JSON en Cloud Storage, identifica la causa raíz y resuelve el problema subyacente en Spanner (como insertar de forma manual los registros superiores faltantes o actualizar las asignaciones de anulación de esquemas).

Para volver a reproducir los registros corregidos de la DLQ en Spanner, inicia un nuevo trabajo de Dataflow con uno de los siguientes modos de ejecución de reintentos de DLQ:

  • Modo retryDLQ: Ejecuta este modo como un trabajo por lotes junto con tu canalización de transmisión activa para procesar archivos de error en el directorio severe/ sin detener la replicación de CDC en vivo.
  • Modo retryAllDLQ: Si se detiene tu canalización de transmisión normal, usa este modo para procesar los directorios retry/ y severe/. No ejecutes retryAllDLQ de forma simultánea con una canalización activa, ya que esto provocará conflictos de procesamiento y contención de archivos.

Para iniciar un trabajo de reintento de DLQ con la CLI de gcloud, ejecuta el siguiente 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"

Reemplaza lo siguiente:

  • RETRY_JOB_NAME: Es el nombre del trabajo de reintento de la DLQ de Dataflow.
  • PROJECT_ID: Es el ID del proyecto de Google Cloud en el que se ejecuta el trabajo de Dataflow.
  • GCP_REGION: Es la región de Google Cloud en la que deseas ejecutar el trabajo de Dataflow.
  • SOURCE_TYPE: Es el tipo de base de datos de origen (por ejemplo, mysql).
  • INSTANCE_ID: Es el ID de la instancia de Spanner de destino.
  • DATABASE_ID: Es el ID de la base de datos de Spanner de destino.
  • SESSION_FILE_PATH: Es la ruta de acceso de Cloud Storage al archivo de sesión que generó la herramienta de migración de Spanner.
  • DLQ_DIRECTORY: Es la ruta de acceso de Cloud Storage al directorio raíz de la cola de mensajes no entregados que contiene los archivos de error que se volverán a intentar (por ejemplo, gs://MIGRATION_BUCKET/ENV/SERVICE/cdc/DB_SCHEMA/).

Finaliza la migración de CDC

Después de que se escriban casi todos los datos del bucket de Cloud Storage en Spanner, detén las escrituras en la instancia de MySQL de origen para permitir que los cambios restantes se escriban en Spanner.

Esto provoca un breve tiempo de inactividad mientras Spanner se pone al día con la instancia de MySQL de origen. Una vez que se escriban todos los cambios en Spanner, tu aplicación podrá comenzar a usar Spanner como su base de datos.

Para obtener instrucciones detalladas paso a paso para pausar las escrituras de la aplicación, vaciar los datos en tránsito y realizar el corte de la aplicación, consulta Cómo realizar el corte desde MySQL.

¿Qué sigue?