En este documento, se describe cómo configurar la conmutación por retroceso para MySQL con la replicación inversa. La conmutación por retroceso se refiere a un plan de contingencia para revertir a tu base de datos de MySQL de origen si tienes problemas con Spanner.
La replicación inversa es útil cuando tienes problemas inesperados y necesitas volver a la base de datos de MySQL original con una interrupción mínima del servicio. La replicación inversa te permite volver a replicar los datos escritos en Spanner en tu base de datos de MySQL de origen.
El flujo de replicación inversa incluye los siguientes pasos, que realiza la plantilla de Dataflow
Spanner_to_SourceDb:
Lee los cambios de Spanner con los flujos de cambios de Spanner.
Filtra los registros con el modo de filtración
forward_migration.Transforma los datos de Spanner para que sean compatibles con el esquema de tu base de datos de origen con la herramienta de migración de Spanner. Para obtener más información, consulta Transformación personalizada.
Verifica si la base de datos de MySQL de origen ya contiene datos más recientes para la clave primaria especificada. Si ya existen datos más recientes, la canalización omite el evento de cambio para evitar la sobreescritura de datos más nuevos.
Escribe los datos en tu base de datos de origen.
Usa la plantilla de Dataflow Spanner_to_SourceDb
La plantilla de Dataflow ayuda a garantizar la coherencia a nivel de clave primaria. La plantilla crea tablas de metadatos, conocidas como tablas paralelas, en Spanner que contienen la marca de tiempo de confirmación de la última transacción de escritura en el fragmento para esa tabla en particular.
La escritura es coherente hasta la marca de tiempo de confirmación de la clave primaria.
La replicación inversa se ejecuta como un trabajo de Dataflow de transmisión continua.
El trabajo lee eventos de cambio de los flujos de cambios de Spanner, los convierte en tipos de datos compatibles con el esquema de la base de datos de origen y los escribe en tu base de datos de MySQL. Si un evento encuentra un error transitorio, el trabajo lo reintenta automáticamente a través de un directorio de cola de mensajes no entregados (DLQ) retry/ en Cloud Storage. Si un evento encuentra un error permanente (o supera los intentos de reintento), el trabajo lo enruta a un directorio de DLQ severe/ para la resolución manual. Para obtener más información sobre cómo resolver y volver a reproducir registros con errores,
consulta Supervisa y resuelve errores de replicación inversa
errors.
Antes de comenzar
Verifica la conectividad de red entre tu base de datos de MySQL de origen y tu Google Cloud proyecto, donde se ejecutan tus trabajos de Dataflow.
Incluye en la lista de entidades permitidas las direcciones IP de los trabajadores de Dataflow en tu instancia de MySQL de origen.
Verifica que las credenciales de MySQL se especifiquen correctamente en el
source shards file.Verifica que tu instancia de MySQL esté en línea y en ejecución.
Verifica que el usuario de MySQL tenga privilegios
INSERT,UPDATEyDELETEen la base de datos de MySQL.Verifica que tengas los permisos de IAM necesarios para ejecutar una plantilla de Flex de Dataflow. Para obtener más información, consulta Compila y ejecuta una plantilla de Flex.
Verifica que el puerto
12345esté abierto para la comunicación entre las VMs de trabajador de Dataflow.
Roles obligatorios
-
Para obtener los permisos que necesitas para iniciar la replicación inversa, pídele a tu administrador que te otorgue los siguientes roles de IAM en la instancia:
- Usuario de base de datos de Cloud Spanner (
roles/spanner.databaseUser) - Desarrollador de Dataflow (
roles/dataflow.developer)
- Usuario de base de datos de Cloud Spanner (
-
Para asegurarte de que la cuenta de servicio de Compute Engine tenga los permisos necesarios para iniciar la replicación inversa, pídele a tu administrador que le otorgue los siguientes roles de IAM a la cuenta de servicio de Compute Engine en la instancia:
- Usuario de base de datos de Cloud Spanner (
roles/spanner.databaseUser) - Descriptor de acceso de secretos de Secret Manager (
roles/secretmanager.secretAccessor) - Visualizador de Secret Manager (
roles/secretmanager.viewer)
- Usuario de base de datos de Cloud Spanner (
Ejecuta la replicación inversa
Para ejecutar la replicación inversa, sigue estos pasos:
Sube el archivo de sesión al bucket de Cloud Storage.
Crea una notificación de Pub/Sub para la carpeta
retrydel directorio de DLQ. Para ello, crea un tema de Pub/Sub y una suscripción a Pub/Sub para ese tema.Compila y almacena en etapa intermedia la plantilla de Dataflow. Para obtener más información, consulta Cómo compilar una plantilla.
Para iniciar la canalización de transmisión de replicación inversa, ejecuta el siguiente 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"]
Las variables obligatorias se describen en la siguiente lista:
PROJECT: Es el ID del Google Cloud proyecto.REGION: Es la Google Cloud región en la que deseas ejecutar el trabajo de Dataflow.TEMPLATE_SPEC_GCSPATH: Es la ruta de acceso de Cloud Storage al archivo de plantilla de Dataflow almacenado en etapa intermedia.CHANGE_STREAM_NAME: Es el nombre del flujo de cambios de Spanner desde el que lee el trabajo.INSTANCE_ID: Es el ID de la instancia de Spanner.DATABASE_ID: Es el ID de la base de datos de Spanner.SPANNER_PROJECT_ID: Es el ID del proyecto en el que residen tus instancias de Spanner.METADATA_INSTANCE: Es la instancia de Spanner que almacena los metadatos que usa el conector para controlar el consumo de datos de la API de flujo de cambios.METADATA_DATABASE: Es la base de datos de Spanner que almacena los metadatos que usa el conector para controlar el consumo de datos de la API de flujo de cambios.SOURCE_SHARDS_FILE_PATH: Es la ruta de acceso de Cloud Storage que contiene la información del perfil de conexión para los fragmentos de origen.
Las variables opcionales se describen en la siguiente lista:
START_TIMESTAMP: Es la marca de tiempo desde la que se comenzará a leer los cambios. La configuración predeterminada es vacía.END_TIMESTAMP: Es la marca de tiempo hasta la que se leerán los cambios. Si no se especifica, el proceso lee los cambios de forma indefinida. La configuración predeterminada es vacía.SHADOW_TABLE_PREFIX: Es el prefijo para nombrar tablas paralelas. Valor predeterminado:shadow_.SESSION_FILE_PATH: Es la ruta de acceso al archivo de sesión en Cloud Storage que contiene información de asignación de la herramienta de migración de Spanner.FILTRATION_MODE: Es el modo que determina cómo filtrar los registros según los criterios. Los modos admitidos sonnoneyforward_migration.SHARDING_CUSTOM_JAR_PATH: Es la ubicación (ruta de acceso) en Cloud Storage del archivo JAR personalizado que contiene la lógica para recuperar el ID del fragmento. La configuración predeterminada es vacía.SHARDING_CUSTOM_CLASS_NAME: Es el nombre de clase completamente calificado que tiene la implementación personalizada del ID del fragmento. Este parámetro es obligatorio si se especificaSHARDING_CUSTOM_JAR_PATH. La configuración predeterminada es vacía.SHARDING_CUSTOM_PARAMETERS: Es una cadena que contiene cualquier parámetro personalizado que se pasará a la clase de fragmentación personalizada. La configuración predeterminada es vacía.SOURCE_DB_TIMEZONE_OFFSET: Es la compensación de zona horaria desde UTC para la base de datos de origen. Por ejemplo,+10:00. Valor predeterminado:+00:00.DLQ_GCS_PUB_SUB_SUBSCRIPTION: Es la suscripción a Pub/Sub que se usa en una política de notificaciones de Cloud Storage para el directorio de reintentos de DLQ cuando se ejecuta en modoregular. Especifica el nombre en el formatoprojects/<PROJECT_ID>/subscriptions/<SUBSCRIPTION_ID>. Cuando configuras este parámetro, el sistema ignoradeadLetterQueueDirectoryydlqRetryMinutes.SKIP_DIRECTORY_NAME: Es el directorio en el que el sistema escribe los registros que omite durante la replicación inversa. Valor predeterminado:skip.MAX_SHARD_CONNECTIONS: Es la cantidad máxima de conexiones permitidas por fragmento. Valor predeterminado:10000.DEAD_LETTER_QUEUE_DIRECTORY: Es la ruta de acceso para almacenar el resultado de DLQ. El valor predeterminado es un directorio en la ubicación temporal del trabajo de Dataflow.DLQ_MAX_RETRY_COUNT: Es la cantidad máxima de veces que el sistema reintenta los errores temporales a través de DLQ. Valor predeterminado:500.RUN_MODE: Es el tipo de modo de ejecución. Las opciones admitidas sonregular,retryDLQyretryAllDLQ. UsaretryDLQpara reintentar los registros de errores del directoriosevere/junto con una canalización activa, oretryAllDLQpara procesar los directoriosretry/ysevere/cuando se detiene la canalización normal. Valor predeterminado:regular.DLQ_RETRY_MINUTES: Es la cantidad de minutos entre los reintentos de DLQ. Valor predeterminado:10.SOURCE_TYPE: Es el tipo de base de datos de origen a la que se realizará la replicación inversa. Valor predeterminado:mysql.TRANSFORMATION_JAR_PATH: Es la ubicación (ruta de acceso) en Cloud Storage del archivo JAR personalizado que contiene la lógica de transformación personalizada para procesar registros en la replicación inversa. La configuración predeterminada es vacía.TRANSFORMATION_CLASS_NAME: Es el nombre de clase completamente calificado que tiene la lógica de transformación personalizada. Este parámetro es obligatorio si se especificaTRANSFORMATION_JAR_PATH. La configuración predeterminada es vacía.TRANSFORMATION_CUSTOM_PARAMETERS: Es una cadena que contiene cualquier parámetro personalizado que se pasará a la clase de transformación personalizada. La configuración predeterminada es vacía.FILTER_EVENTS_DIRECTORY_NAME: Es el directorio en Cloud Storage en el que el sistema escribe los registros que se filtran con la lógica de transformación inversa personalizada. Valor predeterminado:filteredEvents.
Supervisa y resuelve errores de replicación inversa
Cuando se ejecuta la replicación inversa de Spanner a MySQL, si tu trabajo de Dataflow de transmisión no puede escribir un evento de cambio en tu base de datos principal de MySQL, clasifica la falla en una de dos categorías y escribe el registro en un directorio de cola de mensajes no entregados en tu bucket de Cloud Storage:
- Errores reintentables: Son fallas temporales, como la contención de bloqueo de la base de datos de MySQL
o los tiempos de espera de conexión de red. Dataflow escribe estos eventos en un directorio de cola de mensajes no entregados
retry/y los reintenta automáticamente dentro de la misma canalización hasta que se completen correctamente o superendlqMaxRetryCount. - Errores graves: Son fallas permanentes que no se pueden resolver con reintentos automáticos
, como errores de conversión de tipo de datos, errores de sintaxis o excepciones
dentro de los archivos JAR de transformación personalizados. Dataflow escribe estos eventos
en un directorio de cola de mensajes no entregados
severe/(por ejemplo,gs://MIGRATION_BUCKET/ENV/SERVICE/reverse/DB_SCHEMA/severe/) y aumenta el contador de usuarios personalizadosevere_error_count.
Debido a que los errores graves no se pueden resolver con reintentos automáticos, Dataflow quita esos eventos fallidos del flujo de replicación activo y los guarda en el directorio severe/. Si no se controlan, tu base de datos de reversión de MySQL no tendrá esos registros. Supervisa con regularidad el contador severe_error_count y el directorio severe/ durante la replicación inversa para que puedas resolver y volver a reproducir los eventos de cambio fallidos antes de iniciar una reversión.
El contador personalizado de Dataflow severe_error_count es una métrica acumulativa que registra la cantidad total de errores graves encontrados desde que se inició el trabajo de transmisión. Cuando vuelves a reproducir y resuelves los registros fallidos 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://MIGRATION_BUCKET/ENV/SERVICE/reverse/DB_SCHEMA/severe/) es la fuente de información autorizada para determinar si existen errores no controlados.
Vuelve a reproducir registros con errores
Cuando aparezcan registros fallidos 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.
Para volver a reproducir los registros de DLQ corregidos en MySQL, inicia un nuevo trabajo de Dataflow con uno de los siguientes modos de ejecución:
- 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 directoriosevere/sin detener la replicación inversa en vivo. Ejecuta este modo después de resolver las causas raíz de tus errores graves. - Modo
retryAllDLQ: Si se detiene tu canalización de transmisión normal, usa este modo para procesar los directoriosretry/ysevere/. No ejecutesretryAllDLQde forma simultánea con una canalización activa, ya que causará contención de archivos y conflictos de procesamiento.
Para iniciar un trabajo de reintento de DLQ de replicación inversa con la CLI de gcloud, ejecuta el siguiente 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"
Reemplaza lo siguiente:
PROJECT: Es el ID del Google Cloud proyecto.REGION: Es la Google Cloud región en la que deseas ejecutar el trabajo de Dataflow.TEMPLATE_SPEC_GCSPATH: Es la ruta de acceso de Cloud Storage al archivo de plantilla de Dataflow almacenado en etapa intermedia.CHANGE_STREAM_NAME: Es el nombre del flujo de cambios de Spanner desde el que lee el trabajo.INSTANCE_ID: Es el ID de la instancia de Spanner.DATABASE_ID: Es el ID de la base de datos de Spanner.SPANNER_PROJECT_ID: Es el ID del proyecto en el que residen tus instancias de Spanner.METADATA_INSTANCE: Es la instancia de Spanner que almacena los metadatos que usa el conector para controlar el consumo de datos de la API de flujo de cambios.METADATA_DATABASE: Es la base de datos de Spanner que almacena los metadatos que usa el conector para controlar el consumo de datos de la API de flujo de cambios.SOURCE_SHARDS_FILE_PATH: Es la ruta de acceso de Cloud Storage que contiene la información del perfil de conexión para los fragmentos de origen.DLQ_DIRECTORY: Es la ruta de acceso de Cloud Storage al directorio de cola de mensajes no entregados que contiene los archivos de error graves que se reintentarán.