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 por recuperación y la conmutación por error 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 AlloyDB para PostgreSQL y AlloyDB Omni y Cómo replicar datos entre AlloyDB Omni y otras bases de datos.

Cambio con replicación de pglogical

El cambio es un proceso controlado que se usa para intercambiar los roles entre las bases de datos del proveedor y del suscriptor. Cuando realizas un cambio, se invierten los roles de las dos bases de datos, proveedor y suscriptor. El proveedor se convierte en suscriptor y el suscriptor se convierte en 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 o suscriptor

  1. Detén la escritura de la aplicación 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 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 rezago muestren cero, la replicación estará actualizada y la base de datos estará lista para un 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 del suscriptor en la base de datos de suscriptores nueva.
    5. Redirige las aplicaciones al proveedor nuevo.
  3. Detén la suscripción en la base de datos de suscriptores existente, que se convierte en el nuevo proveedor:

    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 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 del 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 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 en los datos sin replicar en la base de datos del proveedor original o si el proveedor original, que es el nuevo suscriptor, no se encuentra 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 quieres 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 replicación en el suscriptor nuevo 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 cambiar sin incurrir en tiempo de inactividad o garantizar que no se pierdan datos debido a cambios 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 los siguientes parámetros de 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 es la que se confirma.
  • first_update_wins: La versión de los datos con la marca de tiempo más antigua es la que se confirma.

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 de 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 cualquier 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 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. Crea una nueva configuración de proveedor/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 nuevo suscriptor cuando se recupere la base de datos del proveedor anterior y se convierta en un nuevo suscriptor o se cree un nuevo suscriptor.

  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. Sigue los mismos pasos para crear una suscripción y configura 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 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, 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?