Configurer le remplacement par MySQL

Ce document explique comment configurer le basculement pour MySQL à l'aide de la réplication inverse. Le basculement fait référence à un plan d'urgence permettant de revenir à votre base de données MySQL source si vous rencontrez des problèmes avec Spanner.

La réplication inverse est utile lorsque vous rencontrez des problèmes inattendus et que vous devez revenir à la base de données MySQL d'origine avec une interruption minimale du service. La réplication inverse vous permet de revenir en répliquant les données écrites dans Spanner sur votre base de données MySQL source.

Le flux de réplication inverse comprend les étapes suivantes, effectuées par le Spanner_to_SourceDb modèle Dataflow :

  1. Lire les modifications à partir de Spanner à l'aide de flux de modifications Spanner.

  2. Filtrer les enregistrements à l'aide du mode de filtrage forward_migration.

  3. Transformer les données Spanner pour qu'elles soient compatibles avec le schéma de votre base de données source à l'aide de l'outil de migration Spanner. Pour en savoir plus, consultez Transformation personnalisée.

  4. Vérifier si la base de données MySQL source contient déjà des données plus récentes pour la clé primaire spécifiée. Si des données plus récentes existent déjà, le pipeline ignore l'événement de modification pour éviter d'écraser les données plus récentes.

  5. Écrire les données dans votre base de données source.

Utiliser le modèle Dataflow Spanner_to_SourceDb

Le modèle Dataflow permet d'assurer la cohérence au niveau de la clé primaire. Le modèle crée des tables de métadonnées, appelées tables fictives, dans Spanner, qui contiennent l'horodatage de commit de la dernière transaction d'écriture sur le fragment pour cette table particulière.

L'écriture est cohérente jusqu'à l'horodatage de commit de la clé primaire.

La réplication inverse s'exécute en tant que tâche Dataflow de traitement en flux continu. La tâche lit les événements de modification à partir des flux de modifications Spanner, les convertit en types de données compatibles avec le schéma de la base de données source et les écrit dans votre base de données MySQL. Si un événement rencontre une erreur temporaire, la tâche tente automatiquement de le relancer via un répertoire de file d'attente de lettres mortes retry/ dans Cloud Storage. Si un événement rencontre une erreur permanente (ou dépasse le nombre de tentatives), la tâche l'envoie à un répertoire de file d'attente de lettres mortes severe/ pour une résolution manuelle. Pour en savoir plus sur la résolution et la relecture des enregistrements ayant échoué, consultez Surveiller et résoudre les erreurs de réplication inverse errors.

Avant de commencer

  • Vérifiez la connectivité réseau entre votre base de données MySQL source et votre Google Cloud projet, où vos tâches Dataflow s'exécutent.

  • Autorisez les adresses IP des nœuds de calcul Dataflow sur votre instance MySQL source.

  • Vérifiez que les identifiants MySQL sont correctement spécifiés dans le source shards file.

  • Vérifiez que votre instance MySQL est en ligne et en cours d'exécution.

  • Vérifiez que l'utilisateur MySQL dispose des droits INSERT, UPDATE et DELETE sur la base de données MySQL.

  • Vérifiez que vous disposez des autorisations IAM requises pour exécuter un modèle Flex Dataflow. Pour en savoir plus, consultez Créer et exécuter un modèle Flex.

  • Vérifiez que le port 12345 est ouvert pour la communication entre les VM de nœud de calcul Dataflow.

Rôles requis

  • Pour vous assurer que le compte de service Compute Engine dispose des autorisations nécessaires pour lancer la réplication inverse, demandez à votre administrateur d'accorder les rôles IAM suivants au compte de service Compute Engine sur l'instance :

Exécuter la réplication inverse

Pour exécuter la réplication inverse, procédez comme suit :

  1. Importez le fichier de session dans le bucket Cloud Storage.

  2. Créez une notification Pub/Sub pour le dossier retry du répertoire de file d'attente de lettres mortes. Pour ce faire, créez un Pub/Sub sujet et un Pub/Sub abonnement pour ce sujet.

  3. Créez et préparez le modèle Dataflow. Pour en savoir plus, consultez Créer un modèle.

  4. Pour démarrer le pipeline de traitement en flux continu de réplication inverse, exécutez la commande gcloud dataflow flex-template run suivante :

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

    Les variables obligatoires sont décrites dans la liste suivante :

    • PROJECT: ID du Google Cloud projet.
    • REGION : Google Cloud région dans laquelle vous souhaitez exécuter la tâche Dataflow.
    • TEMPLATE_SPEC_GCSPATH: chemin d'accès Cloud Storage au fichier de modèle Dataflow préparé.
    • CHANGE_STREAM_NAME: nom du flux de modifications Spanner à partir duquel la tâche lit.
    • INSTANCE_ID: ID de l'instance Spanner.
    • DATABASE_ID: ID de la base de données Spanner.
    • SPANNER_PROJECT_ID: ID du projet dans lequel résident vos instances Spanner.
    • METADATA_INSTANCE: instance Spanner qui stocke les métadonnées que le connecteur utilise pour contrôler la consommation des données de l'API de flux de modifications.
    • METADATA_DATABASE: base de données Spanner qui stocke les métadonnées que le connecteur utilise pour contrôler la consommation des données de l'API de flux de modifications.
    • SOURCE_SHARDS_FILE_PATH: chemin d'accès Cloud Storage contenant les informations de profil de connexion pour les fragments sources.

    Les variables facultatives sont décrites dans la liste suivante :

    • START_TIMESTAMP: horodatage à partir duquel commencer à lire les modifications. La valeur par défaut est vide.
    • END_TIMESTAMP: horodatage jusqu'auquel lire les modifications. Si aucune valeur n'est spécifiée, le processus lit les modifications indéfiniment. La valeur par défaut est vide.
    • SHADOW_TABLE_PREFIX: préfixe pour nommer les tables fictives. Valeur par défaut : shadow_.
    • SESSION_FILE_PATH: chemin d'accès au fichier de session dans Cloud Storage contenant les informations de mappage de l'outil de migration Spanner.
    • FILTRATION_MODE: mode qui détermine comment filtrer les enregistrements en fonction de critères. Les modes compatibles sont none et forward_migration.
    • SHARDING_CUSTOM_JAR_PATH: emplacement (chemin d'accès) dans Cloud Storage du fichier JAR personnalisé contenant la logique permettant d'extraire l'ID de fragment. La valeur par défaut est vide.
    • SHARDING_CUSTOM_CLASS_NAME: nom de classe complet qui contient l'implémentation personnalisée de l'ID de fragment. Ce paramètre est obligatoire si SHARDING_CUSTOM_JAR_PATH est spécifié. La valeur par défaut est vide.
    • SHARDING_CUSTOM_PARAMETERS: chaîne contenant les paramètres personnalisés à transmettre à la classe de sharding personnalisée. La valeur par défaut est vide.
    • SOURCE_DB_TIMEZONE_OFFSET: décalage du fuseau horaire par rapport à UTC pour la base de données source. Exemple : +10:00. Valeur par défaut : +00:00.
    • DLQ_GCS_PUB_SUB_SUBSCRIPTION: abonnement Pub/Sub utilisé dans une règle de notification Cloud Storage pour le répertoire de nouvelle tentative de la file d'attente de lettres mortes en mode regular. Spécifiez le nom au format projects/<PROJECT_ID>/subscriptions/<SUBSCRIPTION_ID>. Lorsque vous définissez ce paramètre, le système ignore deadLetterQueueDirectory et dlqRetryMinutes.
    • SKIP_DIRECTORY_NAME: répertoire dans lequel le système écrit les enregistrements qu'il ignore lors de la réplication inverse. Valeur par défaut : skip.
    • MAX_SHARD_CONNECTIONS: nombre maximal de connexions autorisées par fragment. Valeur par défaut : 10000.
    • DEAD_LETTER_QUEUE_DIRECTORY: chemin d'accès pour stocker la sortie de la file d'attente de lettres mortes. La valeur par défaut est un répertoire situé sous l'emplacement temporaire de la tâche Dataflow.
    • DLQ_MAX_RETRY_COUNT: nombre maximal de tentatives effectuées par le système pour les erreurs temporaires via la file d'attente de lettres mortes. Valeur par défaut : 500.
    • RUN_MODE : type de mode d'exécution. Les options compatibles sont regular, retryDLQ et retryAllDLQ. Utilisez retryDLQ pour réessayer les enregistrements d'erreur du répertoire severe/ avec un pipeline actif, ou retryAllDLQ pour traiter les répertoires retry/ et severe/ lorsque le pipeline normal est arrêté. Valeur par défaut : regular.
    • DLQ_RETRY_MINUTES: nombre de minutes entre les tentatives de la file d'attente de lettres mortes. Valeur par défaut : 10.
    • SOURCE_TYPE: type de base de données source à répliquer inversement. Valeur par défaut : mysql.
    • TRANSFORMATION_JAR_PATH: emplacement (chemin d'accès) dans Cloud Storage du fichier JAR personnalisé contenant la logique de transformation personnalisée pour le traitement des enregistrements lors de la réplication inverse. La valeur par défaut est vide.
    • TRANSFORMATION_CLASS_NAME: nom de classe complet qui contient la logique de transformation personnalisée. Ce paramètre est obligatoire si TRANSFORMATION_JAR_PATH est spécifié. La valeur par défaut est vide.
    • TRANSFORMATION_CUSTOM_PARAMETERS: chaîne contenant les paramètres personnalisés à transmettre à la classe de transformation personnalisée. La valeur par défaut est vide.
    • FILTER_EVENTS_DIRECTORY_NAME: répertoire dans Cloud Storage où le système écrit les enregistrements qui sont filtrés par une logique de transformation inverse personnalisée. Valeur par défaut : filteredEvents.

Surveiller et résoudre les erreurs de réplication inverse

Lorsque vous exécutez une réplication inverse de Spanner vers MySQL, si votre tâche Dataflow de traitement en flux continu ne peut pas écrire d'événement de modification dans votre base de données MySQL principale, elle classe l'échec dans l'une des deux catégories et écrit l'enregistrement dans un répertoire de file d'attente de lettres mortes dans votre bucket Cloud Storage :

  • Erreurs pouvant être relancées : échecs temporaires, tels que les conflits de verrouillage de la base de données MySQL ou les délais d'expiration de la connexion réseau. Dataflow écrit ces événements dans un répertoire de file d'attente de lettres mortes retry/ et les relance automatiquement dans le même pipeline jusqu'à ce qu'ils réussissent ou dépassent dlqMaxRetryCount.
  • Erreurs graves : échecs permanents qui ne peuvent pas être résolus par des tentatives automatiques , tels que les erreurs de conversion de type de données, les erreurs de syntaxe ou les exceptions dans les fichiers JAR de transformation personnalisée. Dataflow écrit ces événements dans un répertoire de file d'attente de lettres mortes severe/ (par exemple, gs://MIGRATION_BUCKET/ENV/SERVICE/reverse/DB_SCHEMA/severe/) et incrémente le compteur utilisateur personnalisé severe_error_count.

Étant donné que les erreurs graves ne peuvent pas être résolues par des tentatives automatiques, Dataflow supprime ces événements ayant échoué du flux de réplication actif et les enregistre dans le répertoire severe/. Si vous ne les traitez pas, votre base de données MySQL de restauration ne contiendra pas ces enregistrements. Surveillez régulièrement le compteur severe_error_count et le répertoire severe/ lors de la réplication inverse afin de pouvoir résoudre et relire les événements de modification ayant échoué avant de lancer une restauration.

Le compteur personnalisé Dataflow severe_error_count est une métrique cumulative qui enregistre le nombre total d'erreurs graves rencontrées depuis le démarrage de la tâche de traitement en flux continu. Lorsque vous relisez et résolvez les enregistrements ayant échoué à l'aide d'une tâche de nouvelle tentative de la file d'attente de lettres mortes, ce compteur de votre pipeline de traitement en flux continu d'origine ne diminue pas. Par conséquent, votre répertoire de file d'attente de lettres mortes grave Cloud Storage (gs://MIGRATION_BUCKET/ENV/SERVICE/reverse/DB_SCHEMA/severe/) est la source de référence pour déterminer si des erreurs non traitées existent.

Relire les enregistrements ayant échoué

Lorsque des enregistrements ayant échoué apparaissent dans votre répertoire de file d'attente de lettres mortes grave, inspectez les fichiers d'erreur JSON dans Cloud Storage, identifiez la cause première et résolvez le problème sous-jacent.

Pour relire les enregistrements de la file d'attente de lettres mortes corrigés dans MySQL, lancez une nouvelle tâche Dataflow à l'aide de l'un des modes d'exécution suivants :

  • Mode retryDLQ : exécutez ce mode en tant que job par lot avec votre pipeline de traitement en flux continu actif pour traiter les fichiers d'erreur dans le répertoire severe/ sans interrompre la réplication inverse en direct. Exécutez ce mode après avoir résolu les causes premières de vos erreurs graves.
  • Mode retryAllDLQ : si votre pipeline de traitement en flux continu normal est arrêté, utilisez ce mode pour traiter les répertoires retry/ et severe/. N'exécutez pas retryAllDLQ simultanément avec un pipeline actif, car cela entraînerait des conflits de fichiers et de traitement.

Pour lancer une tâche de nouvelle tentative de la file d'attente de lettres mortes de réplication inverse à l'aide de l'interface de ligne de commande gcloud CLI, exécutez la commande suivante :

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"

Remplacez les éléments suivants :

  • PROJECT: ID du Google Cloud projet.
  • REGION : Google Cloud région dans laquelle vous souhaitez exécuter la tâche Dataflow.
  • TEMPLATE_SPEC_GCSPATH: chemin d'accès Cloud Storage au fichier de modèle Dataflow préparé.
  • CHANGE_STREAM_NAME: nom du flux de modifications Spanner à partir duquel la tâche lit.
  • INSTANCE_ID : ID de l'instance Spanner.
  • DATABASE_ID : ID de la base de données Spanner.
  • SPANNER_PROJECT_ID: ID du projet dans lequel résident vos instances Spanner.
  • METADATA_INSTANCE: instance Spanner qui stocke les métadonnées que le connecteur utilise pour contrôler la consommation des données de l'API de flux de modifications.
  • METADATA_DATABASE: base de données Spanner qui stocke les métadonnées que le connecteur utilise pour contrôler la consommation des données de l'API de flux de modifications.
  • SOURCE_SHARDS_FILE_PATH: chemin d'accès Cloud Storage contenant les informations de profil de connexion pour les fragments sources.
  • DLQ_DIRECTORY: chemin d'accès Cloud Storage au répertoire de file d'attente de lettres mortes contenant les fichiers d'erreur graves à réessayer.

Étape suivante