Cambio y conmutación por error con la replicación pglogical

En esta página, se proporciona información para realizar la conmutación por error y la conmutación por falla con la replicación de pglogical.

Antes de comenzar

Después de configurar la replicación de pglogical y de que haya una solución viable de alta disponibilidad (HA) y recuperación ante desastres (DR), y de reconocer que la replicación lógica no proporciona true ni una replicación integral de todos los objetos de la base de datos, debes probar esta configuración antes de comenzar a usarla.

Para obtener más información sobre la extensión pglogical, consulta Acerca de pglogical.

Para obtener información sobre la replicación de datos con pglogical, consulta Cómo replicar datos entre Google Cloud AlloyDB y AlloyDB Omni y Cómo replicar datos entre AlloyDB Omni y otras bases de datos.

Cambio con la replicación de pglogical

El cambio es un proceso controlado que se usa para cambiar los roles entre las bases de datos del proveedor y del suscriptor. Cuando realizas un cambio, los roles de las dos bases de datos, proveedor y suscriptor, se invierten. El proveedor se convierte en el suscriptor y el suscriptor se convierte en el proveedor.

Esta función de conmutación es importante para las actualizaciones del sistema operativo, las actualizaciones de PostgreSQL o las pruebas de conmutación por error.

Para lograrlo en las configuraciones de replicación unidireccional, debes configurar una nueva relación proveedor/suscriptor y quitar la relación anterior.

Compila la nueva configuración del proveedor o suscriptor

  1. Evita que la aplicación escriba en el sistema del proveedor para evitar más cambios en la base de datos y verifica el retraso de replicación para asegurarte de que todas las transacciones se vuelvan a reproducir en el nodo del suscriptor:

    SELECT application_name,
        state,
        sync_state,
        client_addr,
        client_hostname,
        pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) AS sent_lag,
        pg_wal_lsn_diff(sent_lsn,flush_lsn) AS receiving_lag,
        pg_wal_lsn_diff(flush_lsn,replay_lsn) AS replay_lag,
        pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn) AS total_lag,
        now()-reply_time AS reply_delay
    FROM pg_stat_replication
    ORDER BY client_hostname;
    

    Cuando todos los campos de retraso muestran cero, la replicación está actualizada y la base de datos está lista para el cambio.

    El resultado es similar a este:

    -[ RECORD 1 ]----+------------------------------
    application_name | test_sub_1
    state            | streaming
    sync_state       | async
    client_addr      | 10.45.0.80
    client_hostname  | 
    sent_lag         | 0
    receiving_lag    | 0
    replay_lag       | 0
    total_lag        | 0
    reply_delay      | 00:00:26.203433
    
  2. Convierte la base de datos de suscriptores en una base de datos de proveedores:

    1. Detén la suscripción existente del suscriptor.
    2. Agrega el conjunto de replicación si es necesario.
    3. Agrega las tablas necesarias al conjunto de replicación.
    4. Compila una nueva suscripción de suscriptor en la nueva base de datos de suscriptores.
    5. Redirecciona las aplicaciones al proveedor nuevo.
  3. Detén la suscripción en la base de datos de suscriptores existente, que se convierte en el proveedor nuevo:

    SELECT pglogical.alter_subscription_disable(SUBSCRIPTION_NAME);
    
  4. Opcional: Crea un conjunto de replicación que coincida con la definición de la base de datos del proveedor original. Esto no es obligatorio si usas los conjuntos de replicación predeterminados:

    SELECT pglogical.create_replication_set(REPLICATION_SET_NAME);
    
  5. Agrega tablas a ese conjunto de replicación:

    SELECT pglogical.replication_set_add_table(REPLICATION_SET_NAME, TABLE_NAME);
    

    Reemplaza lo siguiente:

    • REPLICATION_SET_NAME: Es el nombre del conjunto de replicación.
    • TABLE_NAME: Es el nombre de la tabla de un propietario de esquema. Por ejemplo, ARRAY['public'].`
  6. En la nueva base de datos de suscriptores, que antes era la base de datos del proveedor, crea la suscripción nueva con la opción synchronize_data establecida en false para evitar la carga inicial de la tabla:

    SELECT pglogical.create_subscription (
               subscription_name := '<subscription name>',
               replication_sets := array['default'],
               synchronize_data := false,
               provider_dsn := 'host=<hostname or IP> port=5432 
               dbname=<db name> user=pglogical_replication password=<password>');
    
  7. Verifica si la suscripción funciona en el nodo del proveedor:

    SELECT application_name,
        state,
        sync_state,
        client_addr,
        client_hostname,
        pg_wal_lsn_diff(pg_current_wal_lsn(),sent_lsn) AS sent_lag,
        pg_wal_lsn_diff(sent_lsn,flush_lsn) AS receiving_lag,
        pg_wal_lsn_diff(flush_lsn,replay_lsn) AS replay_lag,
        pg_wal_lsn_diff(pg_current_wal_lsn(),replay_lsn) AS total_lag,
        now()-reply_time AS reply_delay
    FROM pg_stat_replication
    ORDER BY client_hostname;
    
  8. Si la replicación funciona, cambia las cadenas de conexión de la aplicación para usar la nueva base de datos del proveedor y reinicia los niveles de la aplicación.

Si cambias los datos del nodo de proveedor anterior después de que se detenga el suscriptor, estos cambios no se replicarán y se perderán los datos. Si hay cambios de datos no replicados en la base de datos del proveedor original o si el proveedor original, que es el suscriptor nuevo, no está en un estado coherente con la base de datos del proveedor nuevo, que es el suscriptor anterior, debes compilar la base de datos del suscriptor nuevo por completo.

Quita el proveedor y la suscripción anteriores

Si deseas la replicación unidireccional, debes quitar la configuración anterior del proveedor o suscriptor.

  1. Quita la suscripción anterior en el proveedor nuevo:

    SELECT pglogical.drop_subscription('<subscription name>')
    
  2. Quita el conjunto de réplicas del suscriptor nuevo o quita todas las tablas del conjunto de réplicas:

    SELECT pglogical.drop_replication_set('<replication set name>')
    
    SELECT pglogical.replication_set_remove_table('<replication set name>','<table name>')
    

Replicación bidireccional

Para realizar la migración sin incurrir en tiempo de inactividad o para garantizar que no se pierdan datos debido a cambios de datos no planificados, debes usar la replicación bidireccional. Cuando implementes la replicación bidireccional, ten en cuenta la resolución de conflictos, a menos que se implementen controles estrictos para evitar el acceso de escritura a ambos nodos al mismo tiempo.

Puedes configurar la resolución de conflictos con la siguiente configuración de pglogical.conflict_resolution:

  • error: El suscriptor se detiene cuando se detecta un conflicto.
  • apply_remote: Siempre aplica los cambios entrantes, independientemente de los datos de la base de datos de suscriptores. Esta es la configuración predeterminada.
  • keep_local: Siempre ignora los datos entrantes en conflicto y descarta el cambio en conflicto.
  • last_update_wins: La versión de los datos con la marca de tiempo de confirmación más reciente son los datos que se confirman.
  • first_update_wins: La versión de los datos con la marca de tiempo más antigua son los datos que se confirman.

Para configurar la replicación bidireccional, configura el proveedor y el suscriptor de modo que la replicación se realice en ambos sentidos. El suscriptor original también se convierte en un proveedor con el mismo conjunto de replicación que el proveedor original. Consulta Cómo crear una tabla y agregarla al conjunto de replicación predeterminado en la Google Cloud base de datos del proveedor de AlloyDB para crear un conjunto de replicación que duplique el conjunto de replicación original en la base de datos del proveedor inicial.

En el proveedor original, debes agregar un suscriptor nuevo. Consulta Cómo crear un nodo y una suscripción en la base de datos de suscriptores de AlloyDB Omni para crear un suscriptor nuevo y asegurarte de que el parámetro synchronize_data del comando pglogical.create_subscription esté configurado en false. Esto evita la copia inicial de la tabla de los datos.

Conmutación por error con la replicación de pglogical

La conmutación por error se produce cuando la base de datos del proveedor deja de estar disponible por algún motivo y debes cambiar la aplicación para usar la base de datos del suscriptor.

Para evitar que se apliquen datos duplicados accidentalmente a la base de datos de suscriptores con conmutación por error, debes inhabilitar la suscripción. Esto garantiza que los cambios de un proveedor restablecido no se apliquen por error cuando el proveedor vuelva a estar disponible.

  1. Detén el suscriptor, test_sub_1:

    SELECT pglogical.alter_subscription_disable(`test_sub_1`);
    
  2. Verifica que el estado esté configurado como disabled:

    SELECT pglogical.show_subscription_status('test_sub_1');
    

    El resultado es similar a este:

    show_subscription_status                                                                           
    ----------------------------------------------------------------------------
    (test_sub1,disabled,subscriber,"host=10.45.0.108 port=5432 dbname=my_test_db user=pglogical_replication",subscriber,{failover_set},{all})
    
  3. Verifica la palabra clave inhabilitada en el resultado del estado.

  4. Compila una nueva configuración de proveedor o suscriptor para mantener la alta disponibilidad y la capacidad de recuperación ante desastres.

  5. Crea un nuevo conjunto de replicación que contenga todas las tablas que se replicaron originalmente para que se cree un suscriptor nuevo cuando se recupere la base de datos del proveedor anterior y se convierta en un suscriptor nuevo o se cree uno nuevo.

  6. Configura el suscriptor.

  7. Configura esta base de datos como el suscriptor nuevo si puedes recuperar la base de datos del proveedor anterior al momento de la falla. Sigue los mismos pasos para crear una suscripción y establece el parámetro synchronize_data del comando pglogical.create_subscription en false para evitar la copia inicial de la tabla.

  8. Quita la configuración del proveedor anterior en el nodo recuperado para evitar la acumulación de archivos WAL.

  9. Si usas la base de datos del proveedor anterior, descarta el conjunto de replicación completo o quita todas las tablas del conjunto de replicación una por una:

    SELECT pglogical.drop_replication_set('<replication set name>')
    
    SELECT pglogical.replication_set_remove_table('<replication set name>','<table name>')
    
  10. Cambia la aplicación para que escriba en el nodo nuevo.

¿Qué sigue?