Reprise après sinistre (DR) avancée avec emplacement de basculement logique

Cette page explique comment utiliser un emplacement de basculement logique pour configurer la réplication logique de Cloud SQL pour PostgreSQL afin qu'elle fonctionne de manière fluide avec les opérations avancées de reprise après sinistre (DR), en particulier le basculement et le basculement d'instance répliquée sur les instances avec l'édition Cloud SQL Enterprise Plus.

Les fonctionnalités avancées de reprise après sinistre (DR) de Cloud SQL offrent de solides capacités de reprise après sinistre. Lorsqu'il est combiné à la réplication logique de PostgreSQL, il est essentiel que le flux de réplication reste ininterrompu après un basculement ou un basculement d'instance répliquée.

En utilisant la reprise après sinistre (DR) avancée avec la réplication logique de PostgreSQL, vous pouvez vous assurer que vos abonnés logiques ne subissent aucune perte de données et peuvent se reconnecter automatiquement à la nouvelle instance principale après un événement de reprise après sinistre, assurant ainsi la continuité de l'activité.

Vous pouvez utiliser cette fonctionnalité sur les instances Cloud SQL qui présentent la configuration suivante :

  • PostgreSQL version 17 ou ultérieure
  • Édition Enterprise Plus de Cloud SQL
  • Accès aux services privés

    Nous vous recommandons d'utiliser le point de terminaison d'écriture du service de nom de domaine (DNS) d'accès aux services privés pour activer les reconnexions logiques automatiques des abonnés.

Avant de commencer

Configurer la reprise après sinistre avancée avec la réplication logique

La configuration de la reprise après sinistre (DR) avancée avec la réplication logique de PostgreSQL comprend les étapes générales suivantes :

  1. Configurez les variables d'environnement et la VM bastion.
  2. Créez et configurez l'instance principale.
  3. Créez et désignez une instance répliquée de reprise après sinistre.
  4. Créez et configurez une instance d'abonné logique.
  5. Créez un abonnement à la réplication logique.
  6. Effectuez une permutation ou un basculement d'instance répliquée.
  7. Validez la réplication.
  8. Nettoyez l'emplacement de réplication orphelin sur la nouvelle réplique.
  9. Facultatif : Effectuez un retour en arrière.

Configurer des variables d'environnement et une VM bastion

  1. Définissez les variables d'environnement suivantes.

    # Project
    export PROJECT="PROJECT_ID"
    
    # Instance names
    export PRIMARY_INSTANCE_NAME="PRIMARY_INSTANCE"
    export DR_REPLICA_NAME="DR_REPLICA"
    export SUBSCRIBER_INSTANCE_NAME="SUBSCRIBER_INSTANCE"
    export BASTION_VM_NAME="BASTION_VM"
    
    # Regions and zones
    export PRIMARY_REGION="PRIMARY_REGION"
    export REPLICA_REGION="REPLICA_REGION"
    export SUBSCRIBER_REGION="SUBSCRIBER_REGION"
    export VM_ZONE="VM_ZONE"
    
    # Network
    export NETWORK_NAME="NETWORK"
    
    # Credentials
    export POSTGRES_PASSWORD="PASSWORD"
    
    # Set gcloud project
    gcloud config set project PROJECT_ID
    

    Remplacez les éléments suivants :

    • PROJECT_ID : par l'ID du projet.
    • PRIMARY_INSTANCE : nom de l'instance Cloud SQL principale.
    • DR_REPLICA : nom de l'instance répliquée.
    • SUBSCRIBER_INSTANCE : nom de l'instance d'abonné.
    • BASTION_VM : nom de la VM bastion.
    • PRIMARY_REGION : région où se trouve l'instance principale.
    • REPLICA_REGION : région où se trouve la réplique. L'instance répliquée doit se trouver dans une région différente de celle de l'instance principale.
    • SUBSCRIBER_REGION : région où se trouve l'abonné.
    • VM_ZONE : zone où se trouve la VM bastion.
    • NETWORK : nom de votre réseau VPC.
    • PASSWORD : mot de passe de l'utilisateur postgres.
  2. Créez une VM bastion Compute Engine.

    Les instances Cloud SQL utilisent des adresses IP privées. Par conséquent, créez une VM hôte bastion Compute Engine dans votre réseau VPC.

    gcloud compute instances create $BASTION_VM_NAME \
      --zone=$VM_ZONE \
      --machine-type=e2-small \
      --network=projects/$PROJECT_ID/global/networks/$NETWORK_NAME \
      --image-project=debian-cloud \
      --image-family=debian-11 \
      --project=$PROJECT
    
  3. Connectez-vous à la VM bastion.

    gcloud compute ssh $BASTION_VM_NAME \
      --zone=$VM_ZONE \
      --project=$PROJECT
    
  4. Sur la VM bastion, installez le client PostgreSQL.

    sudo apt-get update
    sudo apt-get install -y postgresql-client
    exit
    

Les commandes PostgreSQL des étapes suivantes doivent être exécutées à partir de la VM bastion.

Créer et configurer l'instance principale

  1. Créez l'instance Cloud SQL principale.

    gcloud sql instances create $PRIMARY_INSTANCE_NAME \
      --database-version=POSTGRES_17 \
      --edition=ENTERPRISE_PLUS \
      --region=$PRIMARY_REGION \
      --tier=db-perf-optimized-N-2 \
      --no-assign-ip \
      --network=projects/$PROJECT/global/networks/$NETWORK_NAME \
      --project=$PROJECT
    
  2. Activez le décodage logique.

    gcloud sql instances patch $PRIMARY_INSTANCE_NAME \
      --database-flags=cloudsql.logical_decoding=on \
      --project=$PROJECT
    
  3. Définissez le mot de passe de l'utilisateur postgres sur le serveur principal.

    gcloud sql users set-password postgres \
      --instance=$PRIMARY_INSTANCE_NAME \
      --password="$POSTGRES_PASSWORD" \
      --project=$PROJECT
    
  4. Connectez-vous à l'instance principale depuis la VM bastion.

    1. Récupérez l'adresse IP privée de l'instance principale.

      gcloud sql instances describe $PRIMARY_INSTANCE_NAME \
        --format="value(ipAddresses[0].ipAddress)" \
        --project=$PROJECT
      

      Copiez et conservez l'adresse IP privée de l'instance principale.

    2. Connectez-vous en SSH à votre VM bastion.

      gcloud compute ssh $BASTION_VM_NAME --zone=$VM_ZONE --project=$PROJECT
      
    3. À partir de la VM bastion, connectez-vous à l'instance principale.

      psql -h PRIMARY_PRIVATE_IP -U postgres
      

      Remplacez PRIMARY_PRIVATE_IP par l'adresse IP privée de l'instance principale que vous avez récupérée à l'étape 4.a de cette procédure.

    4. Lorsque vous êtes invité à saisir un mot de passe, saisissez la variable $POSTGRES_PASSWORD.

      Votre VM bastion est désormais connectée à l'instance principale via PostgreSQL.

  5. Accorder des autorisations et créer une publication.

    1. Accordez le droit REPLICATION à l'utilisateur postgres.

      ALTER USER postgres WITH REPLICATION;
      
    2. Accordez les droits nécessaires sur le schéma et les tables publics.

      GRANT SELECT ON ALL TABLES IN SCHEMA public TO postgres;
      
    3. Créez la publication pour toutes les tables.

      CREATE PUBLICATION my_publication FOR ALL TABLES;
      
    4. Saisissez exit pour quitter PostgreSQL, puis exit à nouveau pour fermer la session SSH de la VM bastion.

Créer et désigner une instance répliquée de reprise après sinistre

  1. Créez une instance répliquée de reprise après sinistre.

    gcloud sql instances create $DR_REPLICA_NAME \
      --master-instance-name=$PRIMARY_INSTANCE_NAME \
      --edition=ENTERPRISE_PLUS \
      --tier=db-perf-optimized-N-2 \
      --region=$REPLICA_REGION \
      --no-assign-ip \
      --network=projects/$PROJECT/global/networks/$NETWORK_NAME \
      --project=$PROJECT
    
  2. Désignez cette instance répliquée comme instance répliquée de reprise après sinistre.

    gcloud sql instances patch $PRIMARY_INSTANCE_NAME \
      --failover-dr-replica-name=$DR_REPLICA_NAME \
      --project=$PROJECT
    
  3. Configurez l'instance dupliquée de reprise après sinistre pour la synchronisation des emplacements logiques.

    gcloud sql instances patch $DR_REPLICA_NAME \
      --database-flags="^:^cloudsql.logical_decoding=on:hot_standby_feedback=on:sync_replication_slots=on:cloudsql.logical_slot_sync_dbname=postgres" \
      --project=$PROJECT
    
  4. Configurez la réplication synchrone entre l'instance principale et l'instance répliquée de reprise après sinistre.

    Pour éviter toute perte de données potentielle sur l'abonné logique en cas d'indisponibilité soudaine de l'instance principale et de basculement de l'instance répliquée, nous vous recommandons de configurer la réplication synchrone entre l'instance principale et l'instance répliquée de reprise après sinistre.

    Si vous définissez cloudsql.synchronized_standby_replicas sur l'instance principale, l'expéditeur Write-Ahead Log (WAL) de réplication logique de l'instance principale est forcé d'attendre que l'instance dupliquée de reprise après sinistre ait reçu et vidé le WAL pour une transaction donnée avant d'envoyer cette transaction à l'abonné logique. Cela garantit que l'état du réplica de reprise après sinistre est toujours supérieur ou égal à celui de l'abonné logique.

    gcloud sql instances patch $PRIMARY_INSTANCE_NAME \
      --database-flags="^:^cloudsql.logical_decoding=on:cloudsql.synchronized_standby_replicas=$DR_REPLICA_NAME" \
      --project=$PROJECT
    

Créer et configurer une instance d'abonné logique

  1. Créez une instance d'abonné.

    gcloud sql instances create $SUBSCRIBER_INSTANCE_NAME \
      --database-version=POSTGRES_17 \
      --tier=db-perf-optimized-N-2 \
      --region=$SUBSCRIBER_REGION \
      --no-assign-ip \
      --network=projects/$PROJECT/global/networks/$NETWORK_NAME \
      --project=$PROJECT
    
  2. Activez le décodage logique sur l'abonné.

    gcloud sql instances patch $SUBSCRIBER_INSTANCE_NAME \
      --database-flags=cloudsql.logical_decoding=on \
      --project=$PROJECT
    

Créer un abonnement de réplication logique

  1. Récupérez le point de terminaison d'écriture de l'accès aux services privés de l'instance principale.

    gcloud sql instances describe $PRIMARY_INSTANCE_NAME \
      --format="value(replicationCluster.psaWriteEndpoint)" \
      --project=$PROJECT
    

    Copiez et conservez le point de terminaison d'écriture.

  2. Connectez-vous à l'instance abonnée.

    1. Mettez à jour le mot de passe de l'utilisateur postgres de l'instance abonnée.

      gcloud sql users set-password postgres \
        --instance=$SUBSCRIBER_INSTANCE_NAME \
        --password="$POSTGRES_PASSWORD" \
        --project=$PROJECT
      
    2. Récupérez l'adresse IP privée de l'instance d'abonné.

      gcloud sql instances describe $SUBSCRIBER_INSTANCE_NAME \
        --format="value(ipAddresses[0].ipAddress)" \
        --project=$PROJECT
      

      Copiez et conservez l'adresse IP privée.

    3. Connectez-vous en SSH à la VM bastion.

      gcloud compute ssh $BASTION_VM_NAME \
        --zone=$VM_ZONE \
        --project=$PROJECT
      
    4. Depuis la VM bastion, connectez-vous à l'instance d'abonné via PostgreSQL.

      psql -h SUBSCRIBER_PRIVATE_IP -U postgres
      

      Remplacez SUBSCRIBER_PRIVATE_IP par l'adresse IP privée de l'instance abonnée que vous avez copiée à l'étape 2.b de cette procédure.

    5. Lorsque vous êtes invité à saisir un mot de passe, saisissez la variable $POSTGRES_PASSWORD.

  3. Créer un abonnement

    CREATE SUBSCRIPTION my_subscription
    CONNECTION 'host=DR_CLUSTER_PSA_DNS_WRITE_ENDPOINT port=5432 dbname=postgres user=postgres password=PASSWORD'
    PUBLICATION my_publication
    WITH (failover = true);
    

    Remplacez les éléments suivants :

    • DR_CLUSTER_PSA_DNS_WRITE_ENDPOINT : point de terminaison d'écriture de l'accès aux services privés que vous avez copié à l'étape 1 de cette procédure.
    • PASSWORD : valeur de la variable ${POSTGRES_PASSWORD}.
  4. Quittez PostgreSQL et la session SSH de la VM bastion.

  5. Facultatif. Vérifiez la persistance de l'emplacement sur l'instance répliquée de reprise après sinistre.

    Cette transition vers un état persistant (temporary = false) se produit généralement rapidement, souvent en quelques secondes si l'activité principale est faible. En cas de charge d'écriture élevée sur le serveur principal, ce processus peut prendre plus de temps, généralement environ une minute. L'emplacement doit être persistant après l'exécution de ces commandes manuelles.

    1. Obtenez l'adresse IP privée de la réplique de reprise après sinistre.

      gcloud sql instances describe $DR_REPLICA_NAME \
        --format="value(ipAddresses[0].ipAddress)" \
        --project=$PROJECT
      

      Copiez et conservez l'adresse IP privée de la réplique de reprise après sinistre.

    2. Connectez-vous en SSH à la VM bastion.

      gcloud compute ssh $BASTION_VM_NAME \
        --zone=$VM_ZONE \
        --project=$PROJECT
      
    3. À partir de la VM bastion, connectez-vous à la réplique de reprise après sinistre.

      psql -h DR_REPLICA_PRIVATE_IP -U postgres
      

      Remplacez DR_REPLICA_PRIVATE_IP par l'adresse IP privée du réplica de reprise après sinistre que vous avez récupérée à l'étape 5.a de cette procédure.

    4. Lorsque vous êtes invité à saisir un mot de passe, saisissez la variable $POSTGRES_PASSWORD.

    5. Vérifiez l'état de l'emplacement.

      SELECT slot_name, slot_type, temporary, failover, synced
      FROM pg_replication_slots
      WHERE slot_type = 'logical' AND failover = true;
      

      Attendez que la colonne temporary devienne f. Cela prend généralement moins d'une minute.

    6. Quittez PostgreSQL et la session SSH de la VM bastion.

Effectuer une commutation ou un basculement d'instance répliquée

Choisissez l'opération à effectuer en fonction de votre scénario :

  • Commutation (inversion de rôle planifiée) : choisissez cette option pour la maintenance planifiée, les tests de reprise après sinistre ou pour inverser les rôles lorsque l'instance principale est en ligne et opérationnelle. Cette opération garantit une perte de données nulle pour la réplication physique.

    gcloud sql instances switchover $DR_REPLICA_NAME \
      --project=$PROJECT
    
  • Basculement de l'instance répliquée (reprise après sinistre) : choisissez cette option lorsque l'instance principale est indisponible ou ne répond pas. Cette opération promeut l'instance répliquée de reprise après sinistre en instance principale. Pour minimiser le risque de perte de données pour l'abonné logique, assurez-vous que cloudsql.synchronized_standby_replicas a été défini sur l'instance principale, comme recommandé dans Créer et désigner une réplique de reprise après sinistre.

    gcloud sql instances promote-replica $DR_REPLICA_NAME \
      --failover \
      --project=$PROJECT
    

    La promotion de $DR_REPLICA_NAME est rapide. Toutefois, l'instance principale d'origine ($PRIMARY_INSTANCE_NAME) n'est reconfigurée en tant qu'instance répliquée de la nouvelle instance principale qu'une fois qu'elle est de nouveau en ligne. Pour suivre cette opération, recherchez l'opération RECONFIGURE_OLD_PRIMARY sur $PRIMARY_INSTANCE_NAME dans le journal des opérations. Exécutez la commande suivante :

    gcloud sql operations list --instance=$PRIMARY_INSTANCE_NAME --project=$PROJECT --limit=10`
    

    La configuration de reprise après sinistre n'est entièrement restaurée qu'une fois cette phase terminée.

Après l'une ou l'autre de ces opérations, l'abonné se reconnecte automatiquement au nouveau $DR_REPLICA_NAME principal via le point de terminaison d'écriture de l'accès aux services privés.

Gestion des signalements

Les workflows de Cloud SQL gèrent automatiquement les indicateurs de base de données nécessaires sur les deux instances du cluster de reprise après sinistre pendant et après les opérations de basculement et de basculement de réplica, y compris les suivantes :

  • Les indicateurs de synchronisation des emplacements logiques (cloudsql.logical_decoding, hot_standby_feedback, sync_replication_slots, cloudsql.logical_slot_sync_dbname) sont garantis d'être corrects sur l'instance qui devient la nouvelle réplique.
  • L'indicateur cloudsql.synchronized_standby_replicas de l'instance qui devient la nouvelle instance principale est automatiquement mis à jour pour pointer vers le nom de la nouvelle instance répliquée de reprise après sinistre.

Vous n'avez pas besoin de réappliquer ni de modifier manuellement ces indicateurs après une opération de basculement ou de basculement de réplica. Cloud SQL maintient la configuration correcte pour les rôles principal et répliqué.

Valider la réplication

  1. Vérifiez l'état de l'abonné.

    1. À partir de la VM bastion, exécutez la commande suivante.

      psql -h SUBSCRIBER_PRIVATE_IP -U postgres
      

      Remplacez SUBSCRIBER_PRIVATE_IP par l'adresse IP privée de l'instance abonnée.

    2. Sur l'instance de l'abonné, exécutez la commande suivante.

      SELECT subname, pid IS NOT NULL AS is_active
      FROM pg_stat_subscription;
      

      L'état doit être streaming.

  2. Vérifiez l'état de l'emplacement de réplication de la nouvelle instance principale. Le nouveau nœud principal est l'ancienne instance répliquée de reprise après sinistre ($DR_REPLICA_NAME).

    1. Obtenez l'adresse IP privée du nouveau nœud principal.

      gcloud sql instances describe $DR_REPLICA_NAME \
        --project=$PROJECT --format="value(ipAddresses[0].ipAddress)"
      

      Copiez et conservez l'adresse IP privée de la nouvelle instance principale.

    2. Connectez-vous en SSH à la VM bastion.

      psql -h NEW_PRIMARY_PRIVATE_IP -U postgres
      

      Remplacez NEW_PRIMARY_PRIVATE_IP par l'adresse IP privée du nouveau serveur principal que vous avez copiée à l'étape précédente.

    3. Sur la nouvelle instance principale, exécutez les commandes suivantes.

      SELECT
          slot_name,
          slot_type,
          active,
          synced,
          active_pid,
          pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), confirmed_flush_lsn)) AS replication_lag
      FROM pg_replication_slots
      WHERE slot_type = 'logical';
      

      L'emplacement (par exemple, my_subscription) doit être active = t.

      SELECT
          application_name,
          state
      FROM pg_stat_replication;
      

      pg_stat_replication doit indiquer que l'abonné est connecté.

Nettoyer l'emplacement de réplication orphelin sur la nouvelle instance répliquée

Une fois les opérations de commutation et de basculement terminées, l'instance principale d'origine ($PRIMARY_INSTANCE_NAME) est désormais une instance répliquée. Cette nouvelle instance répliquée conserve toujours l'emplacement de réplication logique d'origine nommé my_subscription sur son disque. Cet emplacement my_subscription est désormais orphelin, car l'abonné est censé se connecter au nouveau primaire ($DR_REPLICA_NAME) via le point de terminaison d'écriture de l'accès aux services privés.

Cloud SQL ne supprime pas automatiquement cet emplacement orphelin de la nouvelle réplique. En effet, Cloud SQL ne peut pas déterminer si l'abonné a été configuré pour utiliser l'adresse IP de l'instance au lieu du point de terminaison d'écriture de l'accès aux services privés. Il est possible que l'abonné tente toujours de se connecter à cet ancien emplacement sur la nouvelle réplique jusqu'à ce que l'abonnement soit modifié manuellement. La suppression automatique de l'emplacement pourrait perturber ces configurations.

La présence de cet emplacement orphelin sur le nouveau réplica ($PRIMARY_INSTANCE_NAME) entraîne la génération d'erreurs dans les journaux par le processus de nœud de calcul slotsync sur cette instance. Un message d'erreur semblable au suivant peut s'afficher dans le postgres.log de la nouvelle réplique. Cette erreur se répète, car le nœud de calcul slotsync continue d'essayer.

ERROR: exiting from slot synchronization because same name slot "my_subscription" already exists on the standby

Pour éviter de telles erreurs et permettre au nœud de calcul slotsync d'établir correctement une nouvelle version synchronisée du slot my_subscription sur ce réplica, vous devez supprimer manuellement le slot orphelin. Cela permet de s'assurer que cette instance est correctement préparée si vous prévoyez de revenir à la version précédente à l'avenir.

  1. Récupérez l'adresse IP privée du nouveau réplica ($PRIMARY_INSTANCE_NAME).

    gcloud sql instances describe $PRIMARY_INSTANCE_NAME \
      --project=$PROJECT --format="value(ipAddresses[0].ipAddress)"
    

    Copiez et conservez l'adresse IP privée du nouveau réplica.

  2. Connectez-vous en SSH à la VM bastion.

    gcloud compute ssh $BASTION_VM_NAME \
      --zone=$VM_ZONE \
      --project=$PROJECT
    
  3. À partir de la VM bastion, connectez-vous à la nouvelle réplique.

    psql -h NEW_REPLICA_IP -U postgres
    

    Remplacez NEW_REPLICA_IP par l'adresse IP de la nouvelle réplique que vous avez copiée à l'étape 1 de cette procédure.

  4. Lorsque vous êtes invité à saisir un mot de passe, saisissez la variable $POSTGRES_PASSWORD.

  5. Sur la nouvelle réplique ($PRIMARY_INSTANCE_NAME), supprimez l'emplacement orphelin.

    SELECT slot_name, slot_type, temporary, failover, synced, active
    FROM pg_replication_slots
    WHERE slot_name = 'my_subscription';
    

    Vérifiez que le créneau existe avec synced = false et active = false, puis supprimez-le.

    SELECT pg_drop_replication_slot('my_subscription');
    

    L'emplacement orphelin est supprimé.

Resynchronisation automatique des créneaux

Une fois l'emplacement orphelin supprimé, le nœud de calcul slotsync sur le nouveau réplica ($PRIMARY_INSTANCE_NAME) se connecte automatiquement au nouveau nœud principal ($DR_REPLICA_NAME) lors de son prochain cycle. Il crée un emplacement my_subscription local qui est synchronisé avec l'emplacement actif de la nouvelle base de données principale.

Vous pouvez voir des messages dans le postgres.log de la nouvelle réplique indiquant la réussite, semblables à ce qui suit :

LOG: newly created slot "my_subscription" is sync-ready now

Le nouvel emplacement synchronisé a la valeur failover=true et devient éventuellement persistant (temporary=false), ce qui garantit que cette instance est prête si vous revenez en arrière ultérieurement.

Facultatif : Effectuer un retour en arrière

  1. Revenez ensuite en arrière pour redéfinir $PRIMARY_INSTANCE_NAME comme instance principale.

    gcloud sql instances switchover $PRIMARY_INSTANCE_NAME \
      --project=$PROJECT
    
  2. Effectuez la validation après le retour à la version précédente.

    1. Vérifiez l'état de l'instance abonnée.

      SELECT subname, pid IS NOT NULL AS is_active
      FROM pg_stat_subscription;
      

      L'abonnement doit toujours être actif, c'est-à-dire is_active = t.

    2. Vérifiez l'état du slot de la nouvelle instance principale ($PRIMARY_INSTANCE_NAME).

      SELECT slot_name, active FROM pg_replication_slots WHERE slot_type = 'logical';
      SELECT * FROM pg_stat_replication;
      

      L'emplacement doit être actif et l'abonné connecté.

Résoudre les problèmes

Problème Dépannage

Erreur sur la nouvelle réplique (c'est-à-dire l'ancienne instance principale) après la commutation :

"exiting from slot synchronization because same name slot already exists on the standby"

Suivez la procédure décrite dans Nettoyer l'emplacement de réplication orphelin sur la nouvelle réplique.