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 de modo que funcione sin problemas con las operaciones de recuperación ante desastres (DR) avanzada, específicamente la conmutación y la conmutación por error de réplicas en instancias con la edición Cloud SQL Enterprise Plus.
Las funciones avanzadas de recuperación ante desastres (DR) de Cloud SQL permiten 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 una conmutación o una conmutación por error de la réplica.
Si usas 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 instancias de Cloud SQL que tengan la siguiente configuración:
- PostgreSQL versión 17 o posterior
- Edición Enterprise Plus de Cloud SQL
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 Google Cloud proyecto 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 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 generales:
- 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 una reversión.
Configura variables de entorno y una 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 host.
- NETWORK: Es el nombre de tu red de VPC.
- PASSWORD: la contraseña del usuario
postgres.
Crea una VM de bastión de Compute Engine.
Las instancias de Cloud SQL usan una IP privada. 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 en los pasos posteriores 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 el servidor 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 guarda la dirección IP privada de la instancia principal.
Conéctate a tu VM de host 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 principal.
psql -h PRIMARY_PRIVATE_IP -U postgresReemplaza PRIMARY_PRIVATE_IP por la IP privada de la instancia principal que recuperaste en el paso 4a de este procedimiento.
Cuando se te solicite la contraseña, ingresa la variable
$POSTGRES_PASSWORD.Tu VM de host ahora está conectada a la instancia principal a través de PostgreSQL.
Otorga permisos y crea 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,exitotra vez 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 posterior conmutación por error de la réplica, te recomendamos que configures la replicación síncrona entre la instancia principal y la réplica de DR.
Establecer
cloudsql.synchronized_standby_replicasen la instancia principal obliga al emisor del registro de escritura anticipada (WAL) de la 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 guarda el endpoint de escritura.
Conéctate a la instancia del suscriptor.
Actualiza la contraseña del usuario
postgresde la instancia del suscriptor.gcloud sql users set-password postgres \ --instance=$SUBSCRIBER_INSTANCE_NAME \ --password="$POSTGRES_PASSWORD" \ --project=$PROJECTRecupera la dirección IP privada de la instancia del 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 host bastión a través de SSH.
gcloud compute ssh $BASTION_VM_NAME \ --zone=$VM_ZONE \ --project=$PROJECTDesde la VM de host, 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 del suscriptor que copiaste en el paso 2b 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.
Por lo general, esta transición a persistente (
temporary = false) ocurre rápidamente, a menudo en segundos si el elemento principal tiene poca actividad. Con una carga de escritura pesada en el servidor principal, este proceso puede tardar más, generalmente alrededor de un minuto. La ranura debería persistir 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 guarda la dirección IP privada de la réplica de DR.
Conéctate a la VM de host 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 5a 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 deseas realizar según tu situación:
Cambio (inversión de roles planificada): Elige esta opción para el mantenimiento planificado, las pruebas de recuperación ante desastres o para cambiar los roles cuando la instancia principal esté en línea y en buen estado. Esta operación garantiza que no haya pérdida de datos en la replicación física.
gcloud sql instances switchover $DR_REPLICA_NAME \ --project=$PROJECTReplica Failover (recuperación ante desastres): Elige esta opción cuando la instancia principal no esté disponible o no responda. Esta operación promueve 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
cloudsql.synchronized_standby_replicasse haya configurado en 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=$PROJECTEl ascenso 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. Puedes hacer un seguimiento de esto buscando la operaciónRECONFIGURE_OLD_PRIMARYque se complete 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 automáticamente al nuevo $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 bases de datos necesarias en ambas instancias dentro del clúster de recuperación ante desastres durante y después de las operaciones de conmutación y conmutación por error de 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_slots,cloudsql.logical_slot_sync_dbname) sean correctas en la instancia que se convierte en la nueva réplica. - La marca
cloudsql.synchronized_standby_replicasen la instancia que se convierte en la nueva principal se actualiza automáticamente para que apunte al nombre de la nueva réplica de DR.
No es necesario que vuelvas a aplicar o cambiar manualmente estos parámetros después de una operación de conmutación o conmutación por error de réplica. Cloud SQL mantiene la configuración correcta para los roles de instancia principal y 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 nueva instancia principal. La nueva instancia principal es la antigua réplica de DR (
$DR_REPLICA_NAME).Obtén la dirección IP privada del nuevo principal.
gcloud sql instances describe $DR_REPLICA_NAME \ --project=$PROJECT --format="value(ipAddresses[0].ipAddress)"Copia y guarda la dirección IP privada del nuevo servidor principal.
Conéctate a la VM de host 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 del nuevo servidor 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';La ranura (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
Una vez que se completan 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 aún 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 al nuevo servidor 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 del acceso privado a servicios. Es posible que el suscriptor siga intentando conectarse a este intervalo antiguo en la réplica nueva hasta que se modifique la suscripción de forma manual. Si se descarta automáticamente la ranura, se podrían interrumpir 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 nueva réplica. Este error se repite a medida que el trabajador 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 slotsync establezca correctamente una nueva versión sincronizada de la ranura my_subscription en esta réplica, debes descartar manualmente la ranura huérfana. Esto garantiza que la instancia esté preparada correctamente si planeas volver a cambiar en el futuro.
Recupera la dirección IP privada de la nueva réplica (
$PRIMARY_INSTANCE_NAME).gcloud sql instances describe $PRIMARY_INSTANCE_NAME \ --project=$PROJECT --format="value(ipAddresses[0].ipAddress)"Copia y guarda la dirección IP privada de la réplica nueva.
Conéctate a la VM de host 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 nueva réplica 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 existe con
synced = falseyactive = false, y luego suéltala.SELECT pg_drop_replication_slot('my_subscription');Se quita la ranura huérfana.
Resincronización automática de intervalos
Una vez que se descarta la ranura huérfana, el trabajador slotsync en la réplica nueva ($PRIMARY_INSTANCE_NAME) se conecta automáticamente al nuevo principal ($DR_REPLICA_NAME) en su próximo ciclo. Crea una nueva ranura my_subscription local que se sincroniza con la ranura activa de la instancia primaria nueva.
Puedes ver mensajes en la nueva réplica de postgres.log que indican que la operación se realizó correctamente, similares a los siguientes:
LOG: newly created slot "my_subscription" is sync-ready now
La nueva ranura sincronizada tiene failover=true y, finalmente, se vuelve persistente (temporary=false), lo que garantiza que, si vuelves a cambiar más adelante, esta instancia estará lista.
Opcional: Realiza el cambio
Ahora, vuelve a cambiar y haz que
$PRIMARY_INSTANCE_NAMEsea la instancia principal nuevamente.gcloud sql instances switchover $PRIMARY_INSTANCE_NAME \ --project=$PROJECTRealiza la verificación después de la reversión.
Verifica el estado de la instancia del 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;La ranura debe estar activa 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. |