Uso de pgactive para admitir la replicación activa-activa - Amazon Relational Database Service

Uso de pgactive para admitir la replicación activa-activa

La extensión pgactive utiliza la replicación activa-activa para admitir y coordinar las operaciones de escritura en varias bases de datos de RDS para PostgreSQL. Amazon RDS para PostgreSQL admite la extensión pgactive en las siguientes versiones:

  • RDS para PostgreSQL 16.1 y versiones 16 posteriores

  • RDS para PostgreSQL 15.2-R2 y versiones 15 posteriores

  • RDS para PostgreSQL 14.10 y versiones 14 posteriores

  • RDS para PostgreSQL 13.13 y versiones 13 posteriores

  • RDS para PostgreSQL 12.17 y versiones 12 posteriores

  • RDS para PostgreSQL 11.22

nota

Cuando hay operaciones de escritura en más de una base de datos en una configuración de replicación, es posible que surjan conflictos. Para obtener más información, consulte Gestión de conflictos en la replicación activa-activa

Inicialización de la capacidad de la extensión pgactive

Para inicializar la capacidad de la extensión pgactive en la instancia de base de datos de RDS para PostgreSQL, defina el valor del parámetro rds.enable_pgactive en 1 y, a continuación, cree la extensión en la base de datos. Al hacerlo, se activan automáticamente los parámetros rds.logical_replication track_commit_timestamp y se establece el valor de wal_level en logical.

Debe tener permisos como el rol rds_superuser para realizar estas tareas.

Puede usar la AWS Management Console o la AWS CLI para crear las instancias de base de datos de RDS para PostgreSQL necesarias. En los pasos siguientes, se supone que la instancia de base de datos de RDS para PostgreSQL está asociada a un grupo de parámetros de base de datos personalizado. Para obtener información sobre la creación de un grupo de parámetros de base de datos personalizado, consulte Grupos de parámetros para Amazon RDS.

Para inicializar la capacidad de la extensión pgactive
  1. Inicie sesión en la AWS Management Console y abra la consola de Amazon RDS en https://console.aws.amazon.com/rds/.

  2. En el panel de navegación, elija su instancia de base de datos de RDS para PostgreSQL.

  3. Abra la pestaña Configuración para su instancia de base de datos de RDS para PostgreSQL. En los detalles de la instancia, busque el enlace Grupo de parámetros de instancia de base de datos.

  4. Elija el enlace para abrir los parámetros personalizados asociados a la instancia de base de datos de RDS para PostgreSQL.

  5. Busque el parámetro rds.enable_pgactive y configúrelo en 1 para inicializar la capacidad pgactive.

  6. Elija Guardar cambios.

  7. En el panel de navegación de la consola de Amazon RDS, elija Bases de datos.

  8. Seleccione su instancia de base de datos de RDS para PostgreSQL y, a continuación, seleccione Reinicio en el menú Acciones.

  9. Confirme el reinicio de la instancia de base de datos para que sus cambios se apliquen.

  10. Cuando la instancia de base de datos esté disponible, podrá utilizar psql o cualquier otro cliente de PostgreSQL para conectarse a la instancia de base de datos de RDS para PostgreSQL.

    En el siguiente ejemplo, se asume que su instancia de base de datos de RDS para PostgreSQL tiene una base de datos predeterminada llamada postgres.

    psql --host=mydb.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=master username --password --dbname=postgres
  11. Para comprobar que pgactive esté inicializado, ejecute el siguiente comando.

    postgres=>SELECT setting ~ 'pgactive' FROM pg_catalog.pg_settings WHERE name = 'shared_preload_libraries';

    Si pgactive está en shared_preload_libraries, el comando anterior devolverá lo siguiente:

    ?column? ---------- t
  12. Cree la extensión de la siguiente manera.

    postgres=> CREATE EXTENSION pgactive;
Para inicializar la capacidad de la extensión pgactive

Para inicializar pgactive utilizando la AWS CLI, llame a la operación modify-db-parameter-group para modificar determinados parámetros de su grupo de parámetros personalizado, tal como se muestra en el siguiente procedimiento.

  1. Utilice el siguiente comando de la AWS CLI para configurar rds.enable_pgactive en 1 para inicializar la capacidad pgactive de la instancia de base de datos de RDS para PostgreSQL.

    postgres=>aws rds modify-db-parameter-group \ --db-parameter-group-name custom-param-group-name \ --parameters "ParameterName=rds.enable_pgactive,ParameterValue=1,ApplyMethod=pending-reboot" \ --region aws-region
  2. Utilice el siguiente comando de la AWS CLI para reiniciar la instancia de base de datos de RDS para PostgreSQL para que se inicialice la biblioteca de pgactive.

    aws rds reboot-db-instance \ --db-instance-identifier your-instance \ --region aws-region
  3. Cuando la instancia esté disponible, use psql para conectarse a la instancia de base de datos de RDS para PostgreSQL.

    psql --host=mydb.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=master user --password --dbname=postgres
  4. Cree la extensión de la siguiente manera.

    postgres=> CREATE EXTENSION pgactive;

Configuración de la replicación activa-activa para las instancias de base de datos de RDS para PostgreSQL

En el siguiente procedimiento, se muestra cómo iniciar la replicación activa-activa entre dos instancias de base de datos de RDS para PostgreSQL que ejecutan PostgreSQL 15.4 o posterior en la misma región. Para ejecutar el ejemplo de alta disponibilidad multirregión, debe implementar instancias de Amazon RDS para PostgreSQL en dos regiones diferentes y configurar la interconexión de VPC. Para obtener más información, consulte Interconexión de VPC.

nota

El envío de tráfico entre varias regiones puede conllevar costes adicionales.

En estos pasos, se asume que la instancia de base de datos de RDS para PostgreSQL se ha configurado con la extensión pgactive. Para obtener más información, consulte Inicialización de la capacidad de la extensión pgactive.

Para configurar la primera instancia de base de datos de RDS para PostgreSQL con la extensión pgactive

En el siguiente ejemplo, se ilustra cómo se crea el grupo pgactive, junto con otros pasos necesarios para crear la extensión pgactive en la instancia de base de datos de RDS para PostgreSQL.

  1. Utilice psql u otra herramienta de cliente para conectarse a su primera instancia de base de datos de RDS para PostgreSQL.

    psql --host=firstinstance.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=master username --password --dbname=postgres
  2. Cree una base de datos en la instancia de RDS para PostgreSQL mediante el siguiente comando:

    postgres=> CREATE DATABASE app;
  3. Cambie la conexión a la nueva base de datos mediante el siguiente comando:

    \c app
  4. Para comprobar si el parámetro shared_preload_libraries contiene pgactive, ejecute el siguiente comando:

    app=>SELECT setting ~ 'pgactive' FROM pg_catalog.pg_settings WHERE name = 'shared_preload_libraries';
    ?column? ---------- t
  5. Cree y rellene una tabla de ejemplo utilizando las siguientes instrucciones SQL:

    1. Cree una tabla de ejemplo con la siguiente instrucción SQL.

      app=> CREATE SCHEMA inventory; CREATE TABLE inventory.products ( id int PRIMARY KEY, product_name text NOT NULL, created_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP);
    2. Rellene la tabla con algunos datos de ejemplo mediante la siguiente instrucción SQL.

      app=> INSERT INTO inventory.products (id, product_name) VALUES (1, 'soap'), (2, 'shampoo'), (3, 'conditioner');
    3. Compruebe que los datos existen en la tabla mediante la siguiente instrucción SQL.

      app=>SELECT count(*) FROM inventory.products; count ------- 3
  6. Cree la extensión pgactive en la base de datos existente.

    app=> CREATE EXTENSION pgactive;
  7. Cree e inicialice el grupo pgactive mediante los siguientes comandos:

    app=> SELECT pgactive.pgactive_create_group( node_name := 'node1-app', node_dsn := 'dbname=app host=firstinstance.111122223333.aws-region.rds.amazonaws.com user=master username password=PASSWORD');

    node1-app es el nombre que se asigna para identificar de forma exclusiva un nodo del grupo pgactive.

    nota

    Para realizar este paso correctamente en una instancia de base de datos de acceso público, debe activar el parámetro rds.custom_dns_resolution configurándolo en 1.

  8. Para comprobar si la instancia de base de datos está lista, utilice el siguiente comando:

    app=> SELECT pgactive.pgactive_wait_for_node_ready();

    Si el comando se ejecuta correctamente, verá el siguiente resultado:

    pgactive_wait_for_node_ready ------------------------------ (1 row)
Para configurar la segunda instancia de RDS para PostgreSQL y unirla al grupo pgactive

En el siguiente ejemplo, se ilustra cómo puede unir una instancia de base de datos de RDS para PostgreSQL al grupo pgactive, junto con otros pasos necesarios para crear la extensión pgactive en la instancia de base de datos.

En estos pasos se asume que otras instancias de base de datos de RDS para PostgreSQL se han configurado con la extensión pgactive. Para obtener más información, consulte Inicialización de la capacidad de la extensión pgactive.

  1. Utilice psql para conectarse a la instancia en la que desea recibir actualizaciones del publicador.

    psql --host=secondinstance.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=master username --password --dbname=postgres
  2. Cree una base de datos en la segunda instancia de base de datos de RDS para PostgreSQL mediante el siguiente comando:

    postgres=> CREATE DATABASE app;
  3. Cambie la conexión a la nueva base de datos mediante el siguiente comando:

    \c app
  4. Cree la extensión pgactive en la base de datos existente.

    app=> CREATE EXTENSION pgactive;
  5. Una la segunda instancia de base de datos de RDS para PostgreSQL al grupo pgactive de la siguiente manera.

    app=> SELECT pgactive.pgactive_join_group( node_name := 'node2-app', node_dsn := 'dbname=app host=secondinstance.111122223333.aws-region.rds.amazonaws.com user=master username password=PASSWORD', join_using_dsn := 'dbname=app host=firstinstance.111122223333.aws-region.rds.amazonaws.com user=postgres password=PASSWORD');

    node2-app es el nombre que se asigna para identificar de forma exclusiva un nodo del grupo pgactive.

  6. Para comprobar si la instancia de base de datos está lista, utilice el siguiente comando:

    app=> SELECT pgactive.pgactive_wait_for_node_ready();

    Si el comando se ejecuta correctamente, verá el siguiente resultado:

    pgactive_wait_for_node_ready ------------------------------ (1 row)

    Si la primera base de datos de RDS para PostgreSQL es relativamente grande, puede ver que pgactive.pgactive_wait_for_node_ready()emite el informe de progreso de la operación de restauración. El resultado tiene un aspecto similar al siguiente:

    NOTICE: restoring database 'app', 6% of 7483 MB complete NOTICE: restoring database 'app', 42% of 7483 MB complete NOTICE: restoring database 'app', 77% of 7483 MB complete NOTICE: restoring database 'app', 98% of 7483 MB complete NOTICE: successfully restored database 'app' from node node1-app in 00:04:12.274956 pgactive_wait_for_node_ready ------------------------------ (1 row)

    A partir de este momento, pgactive sincroniza los datos entre las dos instancias de base de datos.

  7. Puede utilizar el siguiente comando para comprobar si la base de datos de la segunda instancia de base de datos contiene los datos:

    app=> SELECT count(*) FROM inventory.products;

    Si los datos se sincronizan correctamente, verá el siguiente resultado:

    count ------- 3
  8. Ejecute el siguiente comando para insertar nuevos valores:

    app=> INSERT INTO inventory.products (id, product_name) VALUES ('lotion');
  9. Conéctese a la base de datos de la primera instancia de base de datos y ejecute la siguiente consulta:

    app=> SELECT count(*) FROM inventory.products;

    Si se inicializa la replicación activa-activa, el resultado es similar al siguiente:

    count ------- 4
Para separar y eliminar una instancia de base de datos del grupo pgactive

Para separar y eliminar una instancia de base de datos del grupo pgactive, siga estos pasos:

  1. Puede separar la segunda instancia de base de datos de la primera instancia de base de datos mediante el siguiente comando:

    app=> SELECT * FROM pgactive.pgactive_detach_nodes(ARRAY[‘node2-app']);
  2. Elimine la extensión pgactive de la segunda instancia de base de datos mediante el siguiente comando:

    app=> SELECT * FROM pgactive.pgactive_remove();

    Para eliminar la extensión a la fuerza:

    app=> SELECT * FROM pgactive.pgactive_remove(true);
  3. Suelte la extensión con el siguiente comando:

    app=> DROP EXTENSION pgactive;

Gestión de conflictos en la replicación activa-activa

La extensión pgactive funciona por base de datos y no por clúster. Cada instancia de base de datos que utiliza pgactive es una instancia independiente y puede aceptar cambios de datos de cualquier fuente. Cuando se envía un cambio a una instancia de base de datos, PostgreSQL lo confirma localmente y, a continuación, utiliza pgactive para replicar el cambio de forma asíncrona en otras instancias de base de datos. Cuando dos instancias de base de datos de PostgreSQL actualizan el mismo registro prácticamente al mismo tiempo, puede producirse un conflicto.

La extensión pgactive proporciona mecanismos para la detección y la resolución automática de conflictos. Realiza un seguimiento de la marca de tiempo en que se confirmó la transacción en ambas instancias de base de datos y aplica automáticamente el cambio con la última marca de tiempo. La extensión pgactive también registra cuando se produce un conflicto en la tabla pgactive.pgactive_conflict_history.

El pgactive.pgactive_conflict_history seguirá creciendo. Puede definir una política de depuración. Esto se puede hacer borrando algunos registros de forma regular o definiendo un esquema de partición para esta relación (y, luego, separando, descartando o truncando las particiones de interés). Para implementar la política de depuración de forma regular, una opción es usar la extensión pg_cron Consulte la siguiente información con un ejemplo para la tabla de historial de pg_cron Programación de mantenimiento con la extensión pg_cron de PostgreSQL.

Gestión de secuencias en la replicación activa-activa

Una instancia de base de datos de RDS para PostgreSQL con la extensión pgactive utiliza dos mecanismos de secuencia diferentes para generar valores únicos.

Secuencias globales

Para usar una secuencia global, cree una secuencia local con la instrucción CREATE SEQUENCE. Utilice pgactive.pgactive_snowflake_id_nextval(seqname) en lugar de usingnextval(seqname) para obtener el siguiente valor único de la secuencia.

En el siguiente ejemplo se crea una secuencia global.

postgres=> CREATE TABLE gstest ( id bigint primary key, parrot text );
postgres=>CREATE SEQUENCE gstest_id_seq OWNED BY gstest.id;
postgres=> ALTER TABLE gstest \ ALTER COLUMN id SET DEFAULT \ pgactive.pgactive_snowflake_id_nextval('gstest_id_seq');
Secuencias particionadas

En las secuencias divididas o particionadas, se utiliza una secuencia PostgreSQL normal en cada nodo. Cada secuencia se incrementa en la misma cantidad y comienza con diferentes desplazamientos. Por ejemplo, con el paso 100, el nodo 1 genera una secuencia como 101, 201, 301, etc., y el nodo 2 genera una secuencia como 102, 202, 302, etc. Este esquema funciona bien incluso si los nodos no pueden comunicarse durante períodos prolongados, pero requiere que el diseñador especifique un número máximo de nodos al establecer el esquema y requiere una configuración por nodo. Los errores pueden provocar fácilmente la superposición de secuencias.

Es relativamente sencillo configurar este enfoque con pgactive creando la secuencia deseada en un nodo de la siguiente manera:

CREATE TABLE some_table (generated_value bigint primary key);
postgres=> CREATE SEQUENCE some_seq INCREMENT 100 OWNED BY some_table.generated_value;
postgres=> ALTER TABLE some_table ALTER COLUMN generated_value SET DEFAULT nextval('some_seq');

A continuación, llame a setval en cada nodo para dar un valor inicial de desplazamiento diferente, de la siguiente manera.

postgres=> -- On node 1 SELECT setval('some_seq', 1); -- On node 2 SELECT setval('some_seq', 2);

Referencia de parámetros para la extensión pgactive

Puede utilizar la siguiente consulta para ver todos los parámetros asociados a la extensión pgactive.

postgres=> SELECT * FROM pg_settings WHERE name LIKE 'pgactive.%';

Medición del retraso de réplica entre miembros de pgactive

Puede utilizar la siguiente consulta para ver el retraso de réplica entre los miembros de pgactive. Ejecute esta consulta en todos los nodos de pgactive para obtener una idea completa.

postgres=# SELECT *, (last_applied_xact_at - last_applied_xact_committs) AS lag FROM pgactive.pgactive_node_slots; -{ RECORD 1 ]----------------+----------------------------------------------------------------- node_name | node2-app slot_name | pgactive_5_7332551165694385385_0_5__ slot_restart_lsn | 0/1A898A8 slot_confirmed_lsn | 0/1A898E0 walsender_active | t walsender_pid | 69022 sent_lsn | 0/1A898E0 write_lsn | 0/1A898E0 flush_lsn | 0/1A898E0 replay_lsn | 0/1A898E0 last_sent_xact_id | 746 last_sent_xact_committs | 2024-02-06 18:04:22.430376+00 last_sent_xact_at | 2024-02-06 18:04:22.431359+00 last_applied_xact_id | 746 last_applied_xact_committs | 2024-02-06 18:04:22.430376+00 last_applied_xact_at | 2024-02-06 18:04:52.452465+00 lag | 00:00:30.022089

Limitaciones de la extensión pgactive

  • Todas las tablas requieren una clave principal; de lo contrario, no se permiten operaciones para actualizar ni eliminar. Los valores de la columna de clave principal no deberían actualizarse.

  • Las secuencias pueden tener huecos y, a veces, es posible que no sigan un orden. Las secuencias no se replican. Para obtener más información, consulte Gestión de secuencias en la replicación activa-activa.

  • Los DDL y los objetos grandes no se replican.

  • Los índices únicos secundarios pueden provocar divergencias en los datos.

  • La intercalación debe ser idéntica en todos los nodos del grupo.

  • El equilibrador de carga entre los nodos es un antipatrón.

  • Las transacciones grandes pueden provocar retardos en la replicación.