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

Selecciona una versión de la documentación:

En esta página, se proporciona información sobre cómo realizar la conmutación y la conmutación por error con la replicación pglogical.

Antes de comenzar

Después de configurar la replicación 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 una replicación true y completa 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 Replica datos entre AlloyDB para PostgreSQL y AlloyDB Omni y Replica datos entre AlloyDB Omni y otras bases de datos.

Conmutación con replicación pglogical

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

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

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

Compila la nueva configuración de proveedor/suscriptor

  1. Impide 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 la replicación para asegurarte de que todas las transacciones se reproduzcan 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 una conmutación.

    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 del suscriptor en una base de datos del proveedor:

    1. Detén la suscripción del suscriptor existente.
    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 del suscriptor.
    5. Redirige las aplicaciones al nuevo proveedor.
  3. Detén la suscripción en la base de datos del suscriptor existente, que se convierte en el nuevo proveedor:

    SELECT pglogical.alter_subscription_disable(SUBSCRIPTION_NAME);
    
  4. Crea un conjunto de replicación que coincida con la definición de la base de datos del proveedor original (opcional). Esto no es necesario 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 del suscriptor, que antes era la base de datos del proveedor, crea la nueva suscripción 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 en el nodo del proveedor anterior después de que se detiene el suscriptor, estos cambios no se replican y se produce una pérdida de datos. Si hay cambios de datos no replicados en la base de datos del proveedor original o si el proveedor original, que es el nuevo suscriptor, no está en un estado coherente con la nueva base de datos del proveedor, que es el suscriptor anterior, debes compilar la nueva base de datos del suscriptor por completo.

Quita el proveedor y la suscripción anteriores

Si deseas una replicación unidireccional, debes quitar la configuración anterior de proveedor/suscriptor.

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

    SELECT pglogical.drop_subscription('<subscription name>')
    
  2. Quita el conjunto de replicación en el nuevo suscriptor o quita todas las tablas del conjunto de replicación:

    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 conmutación sin incurrir en tiempo de inactividad o para asegurarte de que no se pierdan datos debido a cambios de datos no planificados, debes usar la replicación bidireccional. Cuando implementes la replicación bidireccional, considera la resolución de conflictos, a menos que haya 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 del suscriptor. 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 Crea una tabla y agrégala al conjunto de replicación predeterminado en la base de datos del proveedor de AlloyDB para PostgreSQL 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 Crea un nodo y una suscripción en la base de datos del suscriptor de AlloyDB Omni para crear un suscriptor nuevo y asegurarte de que el parámetro synchronize_data del comando pglogical.create_subscription esté establecido en false. Esto evita la copia inicial de la tabla de los datos.

Conmutación por error con replicación 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 que use la base de datos del suscriptor.

Para evitar que se apliquen datos duplicados accidentalmente a la base de datos del suscriptor 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é establecido en 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/suscriptor para mantener la alta disponibilidad y la capacidad de recuperación ante desastres.

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

  6. Configura el suscriptor.

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

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

  9. Si usas la base de datos del proveedor anterior, quita 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?