En esta página, se describe cómo usar la ranura de conmutación por error lógica para configurar la replicación lógica de Cloud SQL para PostgreSQL para que funcione sin problemas con las operaciones de recuperación ante desastres (DR) avanzada, específicamente el cambio y la conmutación por error de réplicas en instancias con la edición Cloud SQL Enterprise Plus.
Las funciones de recuperación ante desastres (DR) avanzada de Cloud SQL habilitan capacidades sólidas de recuperación ante desastres. Cuando se combina con la replicación lógica de PostgreSQL, es fundamental que el flujo de replicación permanezca ininterrumpido después de un cambio o una conmutación por error de réplica.
Con la recuperación ante desastres (DR) avanzada con la replicación lógica de PostgreSQL, puedes asegurarte de que tus suscriptores lógicos no experimenten pérdida de datos y puedan volver a conectarse automáticamente a la nueva instancia principal después de un evento de recuperación ante desastres, lo que garantiza la continuidad empresarial.
Puedes usar esta funcionalidad en las instancias de Cloud SQL que tengan la siguiente configuración:
- PostgreSQL versión 17 o posterior
- Cloud SQL edición Enterprise Plus
Acceso privado a servicios
Te recomendamos que uses el extremo de escritura del servicio de nombres de dominio (DNS) de acceso privado a servicios para habilitar las reconexiones lógicas automáticas de los suscriptores.
Antes de comenzar
-
Debes usar la versión 502.0.0 o una posterior. Para verificar la versión del SDK de Google Cloud, ejecuta
gcloud --version. Para actualizar el SDK de Google Cloud, ejecutagcloud components update. Crea un proyecto de Google Cloud o selecciona uno existente.
Otorga los roles y permisos de Identity and Access Management (IAM) necesarios.
Para crear un proyecto: Creador de proyectos (
roles/resourcemanager.projectCreator)Para crear y administrar instancias de Cloud SQL: Administrador de Cloud SQL (
roles/cloudsql.admin)Para crear y administrar VMs de Compute Engine: Administrador de instancias de Compute (v1) (
roles/compute.instanceAdmin.v1) y Visualizador de Compute (roles/compute.networkViewer)Para crear redes de VPC: Administrador de redes (
roles/compute.networkAdmin)
Para obtener más información, consulta Roles y permisos.
Para obtener información sobre cómo otorgar roles y permisos de IAM, consulta Administra el acceso a proyectos, carpetas y organizaciones.
Configura la recuperación ante desastres (DR) avanzada con la replicación lógica
El proceso para configurar la recuperación ante desastres (DR) avanzada con la replicación lógica de PostgreSQL tiene los siguientes pasos de alto nivel:
- Configura las variables de entorno y la VM de bastión.
- Crea y configura la instancia principal.
- Crea y designa una réplica de DR.
- Crea y configura una instancia de suscriptor lógica.
- Crea una suscripción de replicación lógica.
- Realiza un cambio o una conmutación por error de réplica.
- Valida la replicación.
- Limpia la ranura de replicación huérfana en la réplica nueva.
- Opcional: Realiza el cambio de vuelta.
Configura las variables de entorno y la VM de bastión
Configura las siguientes variables de entorno:
# 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_IDReemplaza lo siguiente:
- PROJECT_ID: el ID de tu proyecto.
- PRIMARY_INSTANCE: Es el nombre de la instancia principal de Cloud SQL.
- DR_REPLICA: Es el nombre de la réplica.
- SUBSCRIBER_INSTANCE: Es el nombre de la instancia de suscriptor.
- BASTION_VM: Es el nombre de la VM de bastión.
- PRIMARY_REGION: Es la región en la que se encuentra la instancia principal.
- REPLICA_REGION: Es la región en la que se encuentra la réplica. La réplica debe estar en una región diferente a la de la instancia principal.
- SUBSCRIBER_REGION: Es la región en la que se encuentra el suscriptor.
- VM_ZONE: Es la zona en la que se encuentra la VM de bastión.
- NETWORK: Es el nombre de tu red de VPC.
- PASSWORD: la contraseña del usuario
postgres.
Crear una VM de bastión de Compute Engine
Las instancias de Cloud SQL usan IP privadas. Por lo tanto, crea una VM de host de bastión de Compute Engine en tu red de 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=$PROJECTConéctate a la VM de bastión.
gcloud compute ssh $BASTION_VM_NAME \ --zone=$VM_ZONE \ --project=$PROJECTEn la VM de bastión, instala el cliente de PostgreSQL.
sudo apt-get update sudo apt-get install -y postgresql-client exit
Los comandos de PostgreSQL de los pasos siguientes se deben ejecutar desde la VM de bastión.
Crea y configura la instancia principal
Crea la instancia principal de Cloud SQL.
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=$PROJECTHabilita la decodificación lógica.
gcloud sql instances patch $PRIMARY_INSTANCE_NAME \ --database-flags=cloudsql.logical_decoding=on \ --project=$PROJECTEstablece la contraseña para el usuario
postgresen la instancia principal.gcloud sql users set-password postgres \ --instance=$PRIMARY_INSTANCE_NAME \ --password="$POSTGRES_PASSWORD" \ --project=$PROJECTConéctate a la instancia principal desde la VM de bastión.
Recupera la dirección IP privada de la instancia principal.
gcloud sql instances describe $PRIMARY_INSTANCE_NAME \ --format="value(ipAddresses[0].ipAddress)" \ --project=$PROJECTCopia y conserva la dirección IP privada de la instancia principal.
Establece una conexión SSH a tu VM de bastión.
gcloud compute ssh $BASTION_VM_NAME --zone=$VM_ZONE --project=$PROJECTDesde la VM de bastión, conéctate a la instancia principal.
psql -h PRIMARY_PRIVATE_IP -U postgresReemplaza PRIMARY_PRIVATE_IP por la IP privada de la instancia principal que recuperaste en el paso 4.a de este procedimiento.
Cuando se te solicite la contraseña, ingresa la variable
$POSTGRES_PASSWORD.Tu VM de bastión ahora está conectada a la instancia principal a través de PostgreSQL.
Otorgar permisos y crear la publicación
Otorga el privilegio
REPLICATIONal usuariopostgres.ALTER USER postgres WITH REPLICATION;Otorga los privilegios necesarios en el esquema y las tablas públicos.
GRANT SELECT ON ALL TABLES IN SCHEMA public TO postgres;Crea la publicación para todas las tablas.
CREATE PUBLICATION my_publication FOR ALL TABLES;Escribe
exitpara salir de PostgreSQL y, luego,exitde nuevo para cerrar la sesión de SSH de la VM de bastión.
Crea y designa una réplica de recuperación ante desastres (réplica de DR)
Crea una réplica de DR.
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=$PROJECTDesigna esta réplica como la réplica de DR.
gcloud sql instances patch $PRIMARY_INSTANCE_NAME \ --failover-dr-replica-name=$DR_REPLICA_NAME \ --project=$PROJECTConfigura la réplica de DR para la sincronización de ranuras lógicas.
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=$PROJECTConfigura la replicación síncrona entre la instancia principal y la réplica de DR.
Para evitar la posible pérdida de datos en el suscriptor lógico en caso de una interrupción repentina de la instancia principal y la conmutación por error de la réplica posterior, te recomendamos que configures la replicación síncrona entre la instancia principal y la réplica de DR.
Configurar
cloudsql.synchronized_standby_replicasen la instancia principal obliga al remitente del registro de escritura anticipada (WAL) de replicación lógica de la instancia principal a esperar hasta que la réplica de DR haya recibido y vaciado el WAL para una transacción determinada antes de enviar esa transacción al suscriptor lógico. Esto garantiza que el estado de la réplica de DR siempre esté por delante o sea igual al estado del suscriptor lógico.gcloud sql instances patch $PRIMARY_INSTANCE_NAME \ --database-flags="^:^cloudsql.logical_decoding=on:cloudsql.synchronized_standby_replicas=$DR_REPLICA_NAME" \ --project=$PROJECT
Crea y configura una instancia de suscriptor lógica
Crea una instancia de suscriptor.
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=$PROJECTHabilita la decodificación lógica en el suscriptor.
gcloud sql instances patch $SUBSCRIBER_INSTANCE_NAME \ --database-flags=cloudsql.logical_decoding=on \ --project=$PROJECT
Crea una suscripción de replicación lógica
Recupera el extremo de escritura de acceso privado a servicios de la instancia principal.
gcloud sql instances describe $PRIMARY_INSTANCE_NAME \ --format="value(replicationCluster.psaWriteEndpoint)" \ --project=$PROJECTCopia y conserva el extremo de escritura.
Conéctate a la instancia del suscriptor.
Actualiza la contraseña del usuario
postgresde la instancia de suscriptor.gcloud sql users set-password postgres \ --instance=$SUBSCRIBER_INSTANCE_NAME \ --password="$POSTGRES_PASSWORD" \ --project=$PROJECTRecupera la dirección IP privada de la instancia de suscriptor.
gcloud sql instances describe $SUBSCRIBER_INSTANCE_NAME \ --format="value(ipAddresses[0].ipAddress)" \ --project=$PROJECTCopia y guarda la dirección IP privada.
Conéctate a la VM de bastión a través de SSH.
gcloud compute ssh $BASTION_VM_NAME \ --zone=$VM_ZONE \ --project=$PROJECTDesde la VM de bastión, conéctate a la instancia de suscriptor a través de PostgreSQL.
psql -h SUBSCRIBER_PRIVATE_IP -U postgresReemplaza SUBSCRIBER_PRIVATE_IP por la IP privada de la instancia de suscriptor que copiaste en el paso 2.b de este procedimiento.
Cuando se te solicite la contraseña, ingresa la variable
$POSTGRES_PASSWORD.
Cree una suscripción.
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);Reemplaza lo siguiente:
- DR_CLUSTER_PSA_DNS_WRITE_ENDPOINT: Es el extremo de escritura de acceso a servicios privados que copiaste en el paso 1 de este procedimiento.
- PASSWORD: Es el valor de la variable
${POSTGRES_PASSWORD}.
Sal de PostgreSQL y de la sesión SSH de la VM de bastión.
Es opcional. Verifica la persistencia de la ranura en la réplica de DR.
Esta transición a persistente (
temporary = false) suele ocurrir con rapidez, a menudo en cuestión de segundos si la instancia principal tiene poca actividad. En condiciones de carga de escritura intensa en la instancia principal, este proceso puede tardar más, por lo general, alrededor de un minuto. La ranura debería ser persistente después de completar estos comandos manuales.Obtén la dirección IP privada de la réplica de DR.
gcloud sql instances describe $DR_REPLICA_NAME \ --format="value(ipAddresses[0].ipAddress)" \ --project=$PROJECTCopia y conserva la dirección IP privada de la réplica de DR.
Conéctate a la VM de bastión a través de SSH.
gcloud compute ssh $BASTION_VM_NAME \ --zone=$VM_ZONE \ --project=$PROJECTDesde la VM de bastión, conéctate a la réplica de DR.
psql -h DR_REPLICA_PRIVATE_IP -U postgresReemplaza DR_REPLICA_PRIVATE_IP por la dirección IP privada de la réplica de DR que recuperaste en el paso 5.a de este procedimiento.
Cuando se te solicite la contraseña, ingresa la variable
$POSTGRES_PASSWORD.Verifica el estado de la ranura.
SELECT slot_name, slot_type, temporary, failover, synced FROM pg_replication_slots WHERE slot_type = 'logical' AND failover = true;Espera a que la columna
temporaryse convierta enf. Este proceso suele tardar menos de un minuto.Sal de PostgreSQL y de la sesión SSH de la VM de bastión.
Realiza un cambio o una conmutación por error de réplica
Elige la operación que quieras realizar según tu situación:
Cambio (reversión de rol planificada): Elige esta opción para el mantenimiento planificado, las pruebas de recuperación ante desastres o para cambiar de rol cuando la instancia principal esté en línea y en buen estado. Esta operación garantiza que no se produzca pérdida de datos en la replicación física.
gcloud sql instances switchover $DR_REPLICA_NAME \ --project=$PROJECTConmutación por error de réplica (recuperación ante desastres): Elige esta opción cuando la instancia principal no esté disponible o no responda. Esta operación asciende la réplica de DR a principal. Para minimizar el riesgo de pérdida de datos para el suscriptor lógico, asegúrate de que se haya configurado
cloudsql.synchronized_standby_replicasen la instancia principal, como se recomienda en Crea y designa una réplica de recuperación ante desastres (réplica de DR).gcloud sql instances promote-replica $DR_REPLICA_NAME \ --failover \ --project=$PROJECTLa promoción de
$DR_REPLICA_NAMEse produce rápidamente. Sin embargo, la instancia principal original ($PRIMARY_INSTANCE_NAME) solo se reconfigura como una réplica de la instancia principal nueva una vez que vuelve a estar en línea. Para hacer un seguimiento de esto, busca la operaciónRECONFIGURE_OLD_PRIMARYque se completará en$PRIMARY_INSTANCE_NAMEen el registro de operaciones. Ejecuta el comando siguiente:gcloud sql operations list --instance=$PRIMARY_INSTANCE_NAME --project=$PROJECT --limit=10`La configuración de recuperación ante desastres se restablece por completo solo después de que se completa esta fase.
Después de cualquiera de las operaciones, el suscriptor se vuelve a conectar de forma automática a la nueva
$DR_REPLICA_NAME principal a través del extremo de escritura de acceso privado a servicios.
Administración de marcas
Los flujos de trabajo de Cloud SQL administran automáticamente las marcas de base de datos necesarias en ambas instancias dentro del clúster de recuperación ante desastres durante y después de las operaciones de cambio y conmutación por error de la réplica, incluidas las siguientes:
- Se garantiza que las marcas de sincronización de ranuras lógicas (
cloudsql.logical_decoding,hot_standby_feedback,sync_replication_slotsycloudsql.logical_slot_sync_dbname) sean correctas en la instancia que se convierte en la réplica nueva. - La marca
cloudsql.synchronized_standby_replicasen la instancia que se convierte en la nueva principal se actualiza automáticamente para apuntar al nombre de la nueva réplica de DR.
No es necesario que vuelvas a aplicar o cambiar estas marcas de forma manual después de una operación de cambio o conmutación por error de réplica. Cloud SQL mantiene la configuración correcta para los roles principal y de réplica.
Valida la replicación
Verifica el estado del suscriptor.
Desde la VM de bastión, ejecuta el siguiente comando.
psql -h SUBSCRIBER_PRIVATE_IP -U postgresReemplaza SUBSCRIBER_PRIVATE_IP por la dirección IP privada de la instancia del suscriptor.
En la instancia del suscriptor, ejecuta el siguiente comando.
SELECT subname, pid IS NOT NULL AS is_active FROM pg_stat_subscription;El estado debe ser
streaming.
Verifica el estado de la ranura de replicación de la instancia principal nueva. La nueva instancia principal es la réplica de DR anterior (
$DR_REPLICA_NAME).Obtén la dirección IP privada de la nueva instancia principal.
gcloud sql instances describe $DR_REPLICA_NAME \ --project=$PROJECT --format="value(ipAddresses[0].ipAddress)"Copia y conserva la dirección IP privada de la nueva instancia principal.
Conéctate a la VM de bastión a través de SSH.
psql -h NEW_PRIMARY_PRIVATE_IP -U postgresReemplaza NEW_PRIMARY_PRIVATE_IP por la dirección IP privada de la nueva instancia principal que copiaste en el paso anterior.
En la nueva instancia principal, ejecuta los siguientes comandos.
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';El espacio (por ejemplo,
my_subscription) debe seractive = t.SELECT application_name, state FROM pg_stat_replication;pg_stat_replicationdebería mostrar que el suscriptor está conectado.
Limpia la ranura de replicación huérfana en la réplica nueva
Después de que se completen las operaciones de cambio y conmutación por error, la instancia principal original ($PRIMARY_INSTANCE_NAME) ahora es una réplica. Esta nueva instancia de réplica
conserva la ranura de replicación lógica original llamada
my_subscription en su disco. Esta ranura my_subscription ahora está huérfana porque
se espera que el suscriptor se conecte a la nueva instancia principal ($DR_REPLICA_NAME)
a través del extremo de escritura de acceso privado a servicios.
Cloud SQL no quita automáticamente esta ranura huérfana de la réplica nueva. Esto se debe a que Cloud SQL no puede determinar si el suscriptor se configuró para usar la dirección IP de la instancia en lugar del extremo de escritura de acceso privado a servicios. Es posible que el suscriptor aún intente conectarse a esta ranura anterior en la réplica nueva hasta que la suscripción se modifique de forma manual. Si se descarta automáticamente la ranura, se podrían romper esas configuraciones.
La presencia de esta ranura huérfana en la réplica nueva ($PRIMARY_INSTANCE_NAME)
hace que el proceso de trabajador slotsync en esta instancia genere errores en los
registros. Es posible que veas un mensaje de error como el siguiente en el postgres.log de
la réplica nueva. Este error se repite a medida que el trabajador de slotsync sigue intentando.
ERROR: exiting from slot synchronization because same name slot "my_subscription" already exists on the standby
Para evitar estos errores y permitir que el trabajador de slotsync establezca correctamente una
nueva versión sincronizada de la ranura de my_subscription en esta réplica, debes
borrar manualmente la ranura huérfana. Esto garantiza que esta instancia esté preparada de forma adecuada si tienes la intención de volver a cambiar en el futuro.
Recupera la dirección IP privada de la réplica nueva (
$PRIMARY_INSTANCE_NAME).gcloud sql instances describe $PRIMARY_INSTANCE_NAME \ --project=$PROJECT --format="value(ipAddresses[0].ipAddress)"Copia y conserva la dirección IP privada de la réplica nueva.
Conéctate a la VM de bastión a través de SSH.
gcloud compute ssh $BASTION_VM_NAME \ --zone=$VM_ZONE \ --project=$PROJECTDesde la VM de bastión, conéctate a la réplica nueva.
psql -h NEW_REPLICA_IP -U postgresReemplaza NEW_REPLICA_IP por la dirección IP de la réplica nueva que copiaste en el paso 1 de este procedimiento.
Cuando se te solicite la contraseña, ingresa la variable
$POSTGRES_PASSWORD.En la réplica nueva (
$PRIMARY_INSTANCE_NAME), descarta la ranura huérfana.SELECT slot_name, slot_type, temporary, failover, synced, active FROM pg_replication_slots WHERE slot_name = 'my_subscription';Confirma que la ranura exista con
synced = falseyactive = false, y, luego, bórrala.SELECT pg_drop_replication_slot('my_subscription');Se quita el espacio huérfano.
Resincronización automática de ranuras
Una vez que se descarta la ranura huérfana, el trabajador slotsync de la réplica nueva
($PRIMARY_INSTANCE_NAME) se conecta automáticamente a la instancia principal nueva
($DR_REPLICA_NAME) en su siguiente ciclo. Crea una nueva ranura my_subscription local
que se sincroniza con la ranura activa de la nueva instancia principal.
Puedes ver mensajes en el postgres.log de la réplica nueva que indican que se realizó correctamente,
como los siguientes:
LOG: newly created slot "my_subscription" is sync-ready now
La nueva ranura sincronizada tiene failover=true y, con el tiempo, se vuelve persistente
(temporary=false), lo que garantiza que, si vuelves a cambiar más adelante, esta instancia esté lista.
Opcional: Realiza la reversión
Ahora, vuelve a cambiar y convierte a
$PRIMARY_INSTANCE_NAMEen la instancia principal de nuevo.gcloud sql instances switchover $PRIMARY_INSTANCE_NAME \ --project=$PROJECTRealiza la verificación después de la reversión.
Verifica el estado de la instancia de suscriptor.
SELECT subname, pid IS NOT NULL AS is_active FROM pg_stat_subscription;La suscripción debería seguir activa, es decir,
is_active = t.Verifica el estado de la ranura de la nueva instancia principal (
$PRIMARY_INSTANCE_NAME).SELECT slot_name, active FROM pg_replication_slots WHERE slot_type = 'logical'; SELECT * FROM pg_stat_replication;El espacio debe estar activo y el suscriptor conectado.
Solucionar problemas
| Problema | Soluciona problemas |
|---|---|
Error en la réplica nueva (es decir, la instancia principal anterior) después del cambio:
|
Sigue los pasos que se indican en Limpia la ranura de replicación huérfana en la réplica nueva. |