

# Uso de extensiones PostgreSQL con Amazon RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Extensions"></a>

Puede ampliar la funcionalidad de PostgreSQL instalando una variedad de extensiones y módulos. Por ejemplo, para trabajar con datos espaciales, puede instalar y utilizar la extensión de PostGIS. Para obtener más información, consulte [Administración de datos espaciales con la extensión PostGIS](Appendix.PostgreSQL.CommonDBATasks.PostGIS.md). Otro ejemplo, si desea mejorar la entrada de datos para tablas muy grandes, puede considerar la posibilidad de particionar los datos con la extensión `pg_partman`. Para obtener más información, consulte [Administración de las particiones de PostgreSQL con la extensión pg\$1partman](PostgreSQL_Partitions.md).

**nota**  
RDS para PostgreSQL admite extensiones de lenguaje de confianza para PostgreSQL a través de la extensión `pg_tle`, que puede agregar a la instancia de base de datos. Con esta extensión, los desarrolladores pueden crear sus propias extensiones de PostgreSQL en un entorno seguro que simplifica los requisitos de instalación y configuración. Para obtener información sobre las versiones de RDS para PostgreSQL que admiten la extensión `pg_tle` y para más detalles, consulte [Uso de Extensiones de lenguaje de confianza para PostgreSQL](PostgreSQL_trusted_language_extension.md).

En algunos casos, en lugar de instalar una extensión, puede agregar un módulo específico a la lista de `shared_preload_libraries` en el grupo de parámetros de la base de datos personalizado de la instancia de base de datos de RDS para PostgreSQL. Por lo general, el grupo de parámetros del clúster de base de datos predeterminado solo carga las `pg_stat_statements`, pero hay varios otros módulos disponibles para agregarlos a la lista. Por ejemplo, puede añadir la capacidad de programación añadiendo el módulo`pg_cron`, tal como se detalla en [Programación de mantenimiento con la extensión pg\$1cron de PostgreSQL](PostgreSQL_pg_cron.md). Como otro ejemplo, puede registrar los planes de ejecución de consultas cargando el módulo `auto_explain`. Para obtener más información, consulte [Logging execution plans of queries](https://aws.amazon.com/premiumsupport/knowledge-center/rds-postgresql-tune-query-performance/#) (Registro de los planes de ejecución de las consultas) en el centro de conocimiento de AWS.

Según la versión de RDS para PostgreSQL, la instalación de una extensión podría requerir permisos `rds_superuser`, de la siguiente forma: 
+ Para versiones 12 y anteriores de RDS para PostgreSQL, la instalación de extensiones requiere privilegios de `rds_superuser`.
+ Para la versión 13 y superiores de RDS para PostgreSQL , los usuarios (roles) con permisos de creación en una instancia de base de datos determinada pueden instalar y utilizar cualquier *extensión de confianza*. Para obtener una lista de las extensiones de confianza, consulte [Extensiones de confianza de PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.Extensions.md#PostgreSQL.Concepts.General.Extensions.Trusted). 

También puede especificar con precisión qué extensiones se pueden instalar en la instancia de base de datos de RDS para PostgreSQL, enumerándolas en el parámetro `rds.allowed_extensions`. Para obtener más información, consulte [Restringir la instalación de extensiones de PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.Extensions.md#PostgreSQL.Concepts.General.FeatureSupport.Extensions.Restriction).

Para obtener más información acerca del rol `rds_superuser`, consulte [Descripción de los roles y permisos de PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Roles.md).

**Topics**
+ [Uso de las funciones de la extensión orafce](Appendix.PostgreSQL.CommonDBATasks.orafce.md)
+ [Uso de la compatibilidad de extensiones delegadas de Amazon RDS para PostgreSQL](RDS_delegated_ext.md)
+ [Administración de las particiones de PostgreSQL con la extensión pg\$1partman](PostgreSQL_Partitions.md)
+ [Uso de pgAudit para registrar la actividad de la base de datos](Appendix.PostgreSQL.CommonDBATasks.pgaudit.md)
+ [Programación de mantenimiento con la extensión pg\$1cron de PostgreSQL](PostgreSQL_pg_cron.md)
+ [Uso de pglogical para sincronizar datos entre instancias](Appendix.PostgreSQL.CommonDBATasks.pglogical.md)
+ [Uso de pgactive para admitir la replicación activa-activa](Appendix.PostgreSQL.CommonDBATasks.pgactive.md)
+ [Reducción de la sobrecarga en tablas e índices con la extensión pg\$1repack](Appendix.PostgreSQL.CommonDBATasks.pg_repack.md)
+ [Actualización y uso de la extensión PLV8](PostgreSQL.Concepts.General.UpgradingPLv8.md)
+ [Uso de PL/Rust para escribir funciones de PostgreSQL en lenguaje Rust](PostgreSQL.Concepts.General.Using.PL_Rust.md)
+ [Administración de datos espaciales con la extensión PostGIS](Appendix.PostgreSQL.CommonDBATasks.PostGIS.md)

# Uso de las funciones de la extensión orafce
<a name="Appendix.PostgreSQL.CommonDBATasks.orafce"></a>

La extensión orafce brinda funciones y operadores que emulan un subconjunto de funciones y paquetes de una base de datos de Oracle. La extensión orafce facilita la realización de la portabilidad de una aplicación Oracle a PostgreSQL. Esta extensión es compatible con la versión 9.6.6 y posteriores de RDS for PostgreSQL. Para obtener más información sobre orafce, consulte [orafce](https://github.com/orafce/orafce) en GitHub.

**nota**  
RDS for PostgreSQL no admite el paquete `utl_file` que forma parte de la extensión orafce. Esto se debe a que las funciones del esquema `utl_file` proporcionan operaciones de lectura y escritura con archivos de texto del sistema operativo, lo que requiere el acceso de los superusuarios al host subyacente. Como servicio administrado, RDS for PostgreSQL no brinda acceso al host.

**Para usar la extensión orafce**

1. Conéctese a la instancia de base de datos con el nombre de usuario principal que utilizó para crear la instancia de base de datos. 

   Si desea activar orafce para una base de datos diferente en la misma instancia de base de datos, utilice el comando psql `/c dbname`. Con este comando, cambia de la base de datos principal después de iniciar la conexión.

1. Active la extensión orafce con la instrucción `CREATE EXTENSION`.

   ```
   CREATE EXTENSION orafce;
   ```

1. Transfiera la propiedad del esquema de Oracle al rol rds\$1superuser con la instrucción `ALTER SCHEMA`.

   ```
   ALTER SCHEMA oracle OWNER TO rds_superuser;
   ```

   Si desea ver la lista de propietarios del esquema de Oracle, utilice el comando `\dn` de psql.

# Uso de la compatibilidad de extensiones delegadas de Amazon RDS para PostgreSQL
<a name="RDS_delegated_ext"></a>

Al utilizar la compatibilidad de extensiones delegadas de Amazon RDS para PostgreSQL, puede delegar la administración de la extensión a un usuario que no necesita ser un `rds_superuser`. Con esta compatibilidad de extensiones delegadas, se crea un nuevo rol denominado `rds_extension` que debe asignarse a un usuario para que administre otras extensiones. Este rol puede crear, actualizar y eliminar extensiones.

Puede especificar qué extensiones se pueden instalar en la instancia de base de datos de RDS enumerándolas en el parámetro `rds.allowed_extensions`. Para obtener más información, consulte [Uso de extensiones PostgreSQL con Amazon RDS para PostgreSQL](https://docs.aws.amazon.com//AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Extensions.html).

Puede restringir la lista de extensiones disponibles que el usuario puede administrar con el rol `rds_extension` utilizando el parámetro `rds.allowed_delegated_extensions`.

La compatibilidad de extensiones delegadas está disponible en las siguientes versiones:
+ Todas las versiones superiores
+ Versión 16.4 y otras versiones 16 superiores
+ Versión 15.8 y otras versiones 15 superiores
+ Versión 14.13 y otras versiones 14 superiores
+ Versión 13.16 y otras versiones 13 superiores
+ Versión 12.20 y otras versiones 12 superiores

**Topics**
+ [Activación de la compatibilidad con extensiones delegadas a un usuario](#RDSPostgreSQL.delegated_ext_mgmt)
+ [Configuración utilizada en la compatibilidad de extensiones delegadas de RDS para PostgreSQL](#RDSPostgreSQL.delegated_ext_config)
+ [Desactivar la compatibilidad para la extensión delegada](#RDSPostgreSQL.delegated_ext_disable)
+ [Ventajas del uso de la compatibilidad de extensiones delegadas de Amazon RDS](#RDSPostgreSQL.delegated_ext_benefits)
+ [Limitación de la compatibilidad de extensiones delegadas de Amazon RDS para PostgreSQL](#RDSPostgreSQL.delegated_ext_limit)
+ [Permisos necesarios para determinadas extensiones](#RDSPostgreSQL.delegated_ext_perm)
+ [Consideraciones de seguridad](#RDSPostgreSQL.delegated_ext_sec)
+ [Eliminación de extensión en cascada deshabilitada](#RDSPostgreSQL.delegated_ext_drop)
+ [Ejemplos de extensiones que se pueden agregar mediante la compatibilidad de extensiones delegadas](#RDSPostgreSQL.delegated_ext_support)

## Activación de la compatibilidad con extensiones delegadas a un usuario
<a name="RDSPostgreSQL.delegated_ext_mgmt"></a>

Debe realizar lo siguiente para habilitar la compatibilidad con extensiones delegadas en un usuario:

1. **Otorgar el rol `rds_extension` a un usuario**: conéctese a la base de datos como `rds_superuser` y ejecute el siguiente comando:

   ```
   Postgres => grant rds_extension to user_name;
   ```

1. **Defina la lista de extensiones disponibles para que las administren los usuarios delegados**: `rds.allowed_delegated_extensions` permite especificar un subconjunto de las extensiones disponibles utilizando `rds.allowed_extensions` en el parámetro del clúster de base de datos. Puede realizar esto en uno de los siguientes niveles:
   + En el clúster o en el grupo de parámetros de la instancia, a través de la Consola de administración de AWS o la API. Para obtener más información, consulte [Grupos de parámetros para Amazon RDS](USER_WorkingWithParamGroups.md).
   + Use el siguiente comando en el nivel de la base de datos:

     ```
     alter database database_name set rds.allowed_delegated_extensions = 'extension_name_1,
                         extension_name_2,...extension_name_n';
     ```
   + Use el siguiente comando en el nivel de usuario:

     ```
     alter user user_name set rds.allowed_delegated_extensions = 'extension_name_1,
                         extension_name_2,...extension_name_n';
     ```
**nota**  
No es necesario reiniciar la base de datos después de cambiar el parámetro dinámico `rds.allowed_delegated_extensions`.

1. **Permita el acceso del usuario delegado a los objetos creados durante el proceso de creación de la extensión**: algunas extensiones crean objetos que requieren la concesión de permisos adicionales antes de que el usuario con el rol `rds_extension` pueda acceder a ellos. El `rds_superuser` debe conceder al usuario delegado acceso a esos objetos. Una de las opciones es utilizar un desencadenador de eventos para conceder automáticamente el permiso al usuario delegado.

   **Ejemplo de desencadenador de eventos**

   Si desea permitir que un usuario delegado con `rds_extension` utilice extensiones que requieran configurar permisos en los objetos creados al crear la extensión, puede personalizar el siguiente ejemplo de un desencadenador de eventos y agregar solo las extensiones para las que desee que los usuarios delegados tengan acceso a todas las funciones. Este activador de eventos se puede crear en la plantilla 1 (la plantilla predeterminada), por lo que todas las bases de datos creadas a partir de la plantilla 1 tendrán ese desencadenador de eventos. Cuando un usuario delegado instala la extensión, este desencadenador otorgará automáticamente la propiedad de los objetos creados por la extensión.

   ```
   CREATE OR REPLACE FUNCTION create_ext()
   
     RETURNS event_trigger AS $$
   
   DECLARE
   
     schemaname TEXT;
     databaseowner TEXT;
   
     r RECORD;
   
   BEGIN
   
     IF tg_tag = 'CREATE EXTENSION' and current_user != 'rds_superuser' THEN
       RAISE NOTICE 'SECURITY INVOKER';
       RAISE NOTICE 'user: %', current_user;
       FOR r IN SELECT * FROM pg_catalog.pg_event_trigger_ddl_commands()
       LOOP
           CONTINUE WHEN r.command_tag != 'CREATE EXTENSION' OR r.object_type != 'extension';
   
           schemaname = (
               SELECT n.nspname
               FROM pg_catalog.pg_extension AS e
               INNER JOIN pg_catalog.pg_namespace AS n
               ON e.extnamespace = n.oid
               WHERE e.oid = r.objid
           );
   
           databaseowner = (
               SELECT pg_catalog.pg_get_userbyid(d.datdba)
               FROM pg_catalog.pg_database d
               WHERE d.datname = current_database()
           );
           RAISE NOTICE 'Record for event trigger %, objid: %,tag: %, current_user: %, schema: %, database_owenr: %', r.object_identity, r.objid, tg_tag, current_user, schemaname, databaseowner;
           IF r.object_identity = 'address_standardizer_data_us' THEN
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_gaz TO %I WITH GRANT OPTION;', schemaname, databaseowner);
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_lex TO %I WITH GRANT OPTION;', schemaname, databaseowner);
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_rules TO %I WITH GRANT OPTION;', schemaname, databaseowner);
           ELSIF r.object_identity = 'dict_int' THEN
               EXECUTE pg_catalog.format('ALTER TEXT SEARCH DICTIONARY %I.intdict OWNER TO %I;', schemaname, databaseowner);
           ELSIF r.object_identity = 'pg_partman' THEN
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.part_config TO %I WITH GRANT OPTION;', schemaname, databaseowner);
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.part_config_sub TO %I WITH GRANT OPTION;', schemaname, databaseowner);
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.custom_time_partitions TO %I WITH GRANT OPTION;', schemaname, databaseowner);
           ELSIF r.object_identity = 'postgis_topology' THEN
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON ALL TABLES IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner);
               EXECUTE pg_catalog.format('GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner);
               EXECUTE pg_catalog.format('GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner);
               EXECUTE pg_catalog.format('GRANT USAGE ON SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner);
           END IF;
       END LOOP;
     END IF;
   END;
   $$ LANGUAGE plpgsql SECURITY DEFINER;
   
   CREATE EVENT TRIGGER log_create_ext ON ddl_command_end EXECUTE PROCEDURE create_ext();
   ```

## Configuración utilizada en la compatibilidad de extensiones delegadas de RDS para PostgreSQL
<a name="RDSPostgreSQL.delegated_ext_config"></a>


| Nombre de la configuración | Descripción | Valor predeterminado | Notas | Quién puede modificar o conceder el permiso | 
| --- | --- | --- | --- | --- | 
| `rds.allowed_delegated_extensions` | Este parámetro limita las extensiones que un rol de rds\$1extension puede administrar en una base de datos. Debe ser un subconjunto de rds.allowed\$1extensions. | empty string | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonRDS/latest/UserGuide/RDS_delegated_ext.html) Para obtener más información sobre la configuración de este parámetro, consulte [Activación de la compatibilidad con extensiones delegadas a un usuario](#RDSPostgreSQL.delegated_ext_mgmt). | rds\$1superuser | 
| `rds.allowed_extensions` | Este parámetro permite que un cliente limite las extensiones que se pueden instalar en la instancia de base de datos de RDS. Para obtener más información, consulte [Restringir la instalación de extensiones de PostgreSQL](https://docs.aws.amazon.com//AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts.General.FeatureSupport.Extensions.Restriction). | "\$1" | De forma predeterminada, este parámetro está establecido en “\$1”, lo que significa que los usuarios con los privilegios necesarios pueden crear todas las extensiones compatibles con RDS para PostgreSQL y Aurora PostgreSQL. Vacío significa que no se pueden instalar extensiones en la instancia de base de datos de RDS. | administrator | 
| `rds-delegated_extension_allow_drop_cascade` | Este parámetro controla la capacidad del usuario con `rds_extension` de eliminar la extensión mediante una opción en cascada. | apagar | De forma predeterminada, `rds-delegated_extension_allow_drop_cascade` está establecido en `off`. Esto significa que los usuarios con `rds_extension` no pueden eliminar una extensión mediante la opción en cascada. Para otorgar esa habilidad, el parámetro `rds.delegated_extension_allow_drop_cascade` debe configurarse como `on`. | rds\$1superuser | 

## Desactivar la compatibilidad para la extensión delegada
<a name="RDSPostgreSQL.delegated_ext_disable"></a>

**Desactivación parcial**  
Los usuarios delegados no pueden crear nuevas extensiones, pero sí pueden actualizar las existentes.
+ Restablece `rds.allowed_delegated_extensions` al valor predeterminado en el grupo de parámetros del clúster de base de datos.
+ Use el siguiente comando en el nivel de la base de datos:

  ```
  alter database database_name reset rds.allowed_delegated_extensions;
  ```
+ Use el siguiente comando en el nivel de usuario:

  ```
  alter user user_name reset rds.allowed_delegated_extensions;
  ```

**Desactivación completa**  
Al revocar el rol `rds_extension` de un usuario, el usuario recuperará los permisos estándar. El usuario ya no puede crear, actualizar ni eliminar extensiones. 

```
postgres => revoke rds_extension from user_name;
```

## Ventajas del uso de la compatibilidad de extensiones delegadas de Amazon RDS
<a name="RDSPostgreSQL.delegated_ext_benefits"></a>

Al utilizar la compatibilidad de extensiones delegadas de Amazon RDS para PostgreSQL, delega de forma segura la administración de la extensión a los usuarios que no tengan el rol `rds_superuser`. Esta característica proporciona los siguientes beneficios:
+ Puede delegar fácilmente la administración de extensiones a los usuarios de su elección.
+ Esto no requiere el rol `rds_superuser`.
+ Ofrece la posibilidad de admitir diferentes conjuntos de extensiones para diferentes bases de datos en el mismo clúster de base de datos.

## Limitación de la compatibilidad de extensiones delegadas de Amazon RDS para PostgreSQL
<a name="RDSPostgreSQL.delegated_ext_limit"></a>
+ Los objetos creados durante el proceso de creación de la extensión pueden requerir privilegios adicionales para que la extensión funcione correctamente.
+ De forma predeterminada, hay algunas extensiones que el usuario de la extensión delegada no puede administrar, como `log_fdw`, `pg_cron`, `pg_tle`, `pgactive`, `pglogical`, `postgis_raster`, `postgis_tiger_geocoder`, `postgis_topology`.

## Permisos necesarios para determinadas extensiones
<a name="RDSPostgreSQL.delegated_ext_perm"></a>

Para crear, usar o actualizar las siguientes extensiones, el usuario delegado debe tener los privilegios necesarios en las siguientes funciones, tablas y esquemas.


| Extensiones que necesitan propiedad o permisos | Función | Tablas | Esquema | Diccionario de búsqueda de texto | Comment | 
| --- | --- | --- | --- | --- | --- | 
| address\$1standardizer\$1data\$1us | none | us\$1gaz, us\$1lex, us\$1lex, I.us\$1rules | none | none | none | 
| amcheck | bt\$1index\$1check, bt\$1index\$1parent\$1check | none | none | none | none | 
| dict\$1int | none | none | none | intdict | none | 
| pg\$1partman | none | custom\$1time\$1partitions, part\$1config, part\$1config\$1sub | none | none | none | 
| pg\$1stat\$1statements | none | none | none | none | none | 
| PostGIS | st\$1tileenvelope | spatial\$1ref\$1sys | none | none | none | 
| postgis\$1raster | none | none | none | none | none | 
| postgis\$1topology | none | topology, layer | topology | none | el usuario delegado debe ser el propietario de la base de datos | 
| log\$1fdw | create\$1foreign\$1table\$1for\$1log\$1file | none | none | none | none | 
| rds\$1tools | role\$1password\$1encryption\$1type | none | none | none | none | 
| postgis\$1tiger\$1geocoder | none | geocode\$1settings\$1default, geocode\$1settings | tiger | none | none | 
| pg\$1freespacemap | pg\$1freespace | none | none | none | none | 
| pg\$1visibility | pg\$1visibility | none | none | none | none | 

## Consideraciones de seguridad
<a name="RDSPostgreSQL.delegated_ext_sec"></a>

 Tenga en cuenta que un usuario con el rol `rds_extension` podrá administrar las extensiones en todas las bases de datos en las que tenga el privilegio de conexión. Si la intención es que un usuario delegado administre la extensión en una única base de datos, una práctica recomendada consiste en revocar todos los privilegios del público en cada base de datos y, a continuación, conceder de forma explícita el privilegio de conexión para esa base de datos específica al usuario delegado. 

 Existen varias extensiones que permiten a un usuario acceder a la información de varias bases de datos. Asegúrese de que los usuarios a los que conceda `rds_extension` tengan capacidades para múltiples bases de datos antes de agregar estas extensiones a `rds.allowed_delegated_extensions`. Por ejemplo, `postgres_fdw` y `dblink` proporcionan la funcionalidad de realizar consultas en todas las bases de datos de la misma instancia o de instancias remotas. `log_fdw` lee los archivos de registro del motor postgres, que son de todas las bases de datos de la instancia, y pueden contener consultas lentas o mensajes de error de varias bases de datos. `pg_cron` permite ejecutar trabajos en segundo plano programados en la instancia de base de datos y puede configurar los trabajos para que se ejecuten en una base de datos diferente. 

## Eliminación de extensión en cascada deshabilitada
<a name="RDSPostgreSQL.delegated_ext_drop"></a>

 La posibilidad de eliminar la extensión con la opción en cascada por parte de un usuario con el rol `rds_extension` la controla el parámetro `rds.delegated_extension_allow_drop_cascade`. De forma predeterminada, `rds-delegated_extension_allow_drop_cascade` está establecido en `off`. Esto significa que los usuarios con el tol `rds_extension` no pueden eliminar una extensión mediante la opción en cascada como se muestra en la siguiente consulta. 

```
DROP EXTENSION CASCADE;
```

Esto eliminará automáticamente los objetos que dependan de la extensión y, a su vez, todos los objetos que dependan de esos objetos. El intento de utilizar la opción en cascada generará un error.

 Para otorgar esa habilidad, el parámetro `rds.delegated_extension_allow_drop_cascade` debe configurarse como `on`. 

 Cambiar el parámetro dinámico `rds.delegated_extension_allow_drop_cascade` no requiere un reinicio de la base de datos. Puede realizar esto en uno de los siguientes niveles: 
+ En el clúster o en el grupo de parámetros de la instancia, a través de la Consola de administración de AWS o la API.
+ Con el siguiente comando en el nivel de la base de datos:

  ```
  alter database database_name set rds.delegated_extension_allow_drop_cascade = 'on';
  ```
+ Con el siguiente comando en el nivel de usuario:

  ```
  alter role tenant_user set rds.delegated_extension_allow_drop_cascade = 'on';
  ```

## Ejemplos de extensiones que se pueden agregar mediante la compatibilidad de extensiones delegadas
<a name="RDSPostgreSQL.delegated_ext_support"></a>
+ `rds_tools`

  ```
  extension_test_db=> create extension rds_tools;
  CREATE EXTENSION
  extension_test_db=> SELECT * from rds_tools.role_password_encryption_type() where rolname = 'pg_read_server_files';
  ERROR: permission denied for function role_password_encryption_type
  ```
+ `amcheck`

  ```
  extension_test_db=> CREATE TABLE amcheck_test (id int);
  CREATE TABLE
  extension_test_db=> INSERT INTO amcheck_test VALUES (generate_series(1,100000));
  INSERT 0 100000
  extension_test_db=> CREATE INDEX amcheck_test_btree_idx ON amcheck_test USING btree (id);
  CREATE INDEX
  extension_test_db=> create extension amcheck;
  CREATE EXTENSION
  extension_test_db=> SELECT bt_index_check('amcheck_test_btree_idx'::regclass);
  ERROR: permission denied for function bt_index_check
  extension_test_db=> SELECT bt_index_parent_check('amcheck_test_btree_idx'::regclass);
  ERROR: permission denied for function bt_index_parent_check
  ```
+ `pg_freespacemap`

  ```
  extension_test_db=> create extension pg_freespacemap;
  CREATE EXTENSION
  extension_test_db=> SELECT * FROM pg_freespace('pg_authid');
  ERROR: permission denied for function pg_freespace
  extension_test_db=> SELECT * FROM pg_freespace('pg_authid',0);
  ERROR: permission denied for function pg_freespace
  ```
+ `pg_visibility`

  ```
  extension_test_db=> create extension pg_visibility;
  CREATE EXTENSION
  extension_test_db=> select * from pg_visibility('pg_database'::regclass);
  ERROR: permission denied for function pg_visibility
  ```
+ `postgres_fdw`

  ```
  extension_test_db=> create extension postgres_fdw;
  CREATE EXTENSION
  extension_test_db=> create server myserver foreign data wrapper postgres_fdw options (host 'foo', dbname 'foodb', port '5432');
  ERROR: permission denied for foreign-data wrapper postgres_fdw
  ```

# Administración de las particiones de PostgreSQL con la extensión pg\$1partman
<a name="PostgreSQL_Partitions"></a>

Las particiones de tablas de PostgreSQL proporcionan un marco para el manejo de alto rendimiento de la entrada de datos y la generación de informes. Utilice particiones para bases de datos que requieren una entrada muy rápida de grandes cantidades de datos. Las particiones también proporcionan consultas más rápidas de tablas grandes. Las particiones ayudan a mantener los datos sin afectar la instancia de base de datos porque requiere menos recursos de E/S.

Mediante el uso de particiones, puede dividir los datos en fragmentos de tamaño personalizado para su procesamiento. Por ejemplo, puede dividir datos de series temporales para rangos como por hora, por día, por semana, por mes, por trimestre, por año, personalizados o cualquier combinación de estos. Para un ejemplo de datos de series temporales, si divide la tabla por hora, cada partición contiene una hora de datos. Si divide la tabla de series temporales por día, las particiones contienen datos de un día, y así sucesivamente. La clave de partición controla el tamaño de una partición. 

Cuando se utiliza un comando `INSERT` o `UPDATE` de SQL en una tabla particionada, el motor de base de datos enruta los datos a la partición adecuada. Las particiones de tablas de PostgreSQL que almacenan los datos son tablas secundarias de la tabla principal. 

Durante las lecturas de consultas de la base de datos, el optimizador de PostgreSQL analiza la cláusula `WHERE` de la consulta y, si es posible, dirige el análisis de la base de datos solo a las particiones relevantes.

A partir de la versión 10, PostgreSQL utiliza particiones declarativas para implementar particiones de tablas. Esto también se conoce como particionado PostgreSQL nativo. Antes de PostgreSQL versión 10, usaba desencadenadores para implementar particiones. 

Las particiones de tablas de PostgreSQL proporcionan las siguientes características:
+ Creación de nuevas particiones en cualquier momento.
+ Rangos de particiones variables.
+ Particiones desmontables y reconectables mediante instrucciones de lenguaje de definición de datos (DDL).

  Por ejemplo, las particiones desmontables son útiles para eliminar datos históricos de la partición principal, pero mantienen los datos históricos para su análisis.
+ Las nuevas particiones heredan las propiedades de la tabla de base de datos principal, incluidas las siguientes:
  + Índices
  + Claves principales, que deben incluir la columna de la clave de partición
  + Claves externas
  + Restricciones de comprobación
  + Referencias
+ creación de índices para la tabla completa o cada partición específica

No se puede modificar el esquema de una partición individual. Sin embargo, se puede modificar la tabla principal (como agregar una nueva columna), que se propaga a las particiones. 

**Topics**
+ [Información general de la extensión pg\$1partman de PostgreSQL](#PostgreSQL_Partitions.pg_partman)
+ [Habilitación de la extensión pg\$1partman](#PostgreSQL_Partitions.enable)
+ [Configuración de particiones mediante la función create\$1parent](#PostgreSQL_Partitions.create_parent)
+ [Configuración del mantenimiento de particiones mediante la función run\$1maintenance\$1proc](#PostgreSQL_Partitions.run_maintenance_proc)

## Información general de la extensión pg\$1partman de PostgreSQL
<a name="PostgreSQL_Partitions.pg_partman"></a>

Puede utilizar la extensión `pg_partman` de PostgreSQL para automatizar la creación y el mantenimiento de las particiones de tablas. Para obtener más información general, consulte [PG Partition Manager](https://github.com/pgpartman/pg_partman) en la documentación de `pg_partman`.

**nota**  
La extensión `pg_partman` es compatible con las versiones 12.5 y posteriores de RDS for PostgreSQL.

En lugar de tener que crear manualmente cada partición, configure `pg_partman` con las siguientes opciones: 
+ Tabla que se dividirá
+ Tipo de partición
+ Clave de partición
+ Grado de detalle de la partición
+ Opciones de precreación y administración de particiones

Después de crear una tabla con particiones de PostgreSQL, la registra con `pg_partman` al llamar a la función `create_parent`. Al hacerlo, se crean las particiones necesarias en función de los parámetros que pase a la función.

La extensión `pg_partman` también proporciona la función `run_maintenance_proc`, que puede ejecutarse de forma programada para administrar automáticamente las particiones. Para asegurarse de que se creen las particiones apropiadas según sea necesario, programe esta función para que se ejecute periódicamente (por ejemplo, por hora). También puede asegurarse de que las particiones se eliminen automáticamente.

## Habilitación de la extensión pg\$1partman
<a name="PostgreSQL_Partitions.enable"></a>

Si tiene varias bases de datos dentro de la misma instancia de base de dato de PostgreSQL para la que desea administrar particiones, debe habilitar la extensión `pg_partman` por separado para cada base de datos. Para habilitar la extensión `pg_partman` para una base de datos específica, cree el esquema de mantenimiento de particiones y, después, cree la extensión `pg_partman` de la siguiente manera:

```
CREATE SCHEMA partman;
CREATE EXTENSION pg_partman WITH SCHEMA partman;
```

**nota**  
Para crear la extensión `pg_partman`, asegúrese de tener privilegios `rds_superuser`. 

Si recibe un error como el siguiente, conceda los privilegios `rds_superuser` a la cuenta o utilice su cuenta de superusuario. 

```
ERROR: permission denied to create extension "pg_partman"
HINT: Must be superuser to create this extension.
```

Para conceder privilegios `rds_superuser`, conéctese con su cuenta de superusuario y ejecute el siguiente comando:

```
GRANT rds_superuser TO user-or-role;
```

Para los ejemplos que muestran el uso de la extensión pg\$1partman, utilizamos la siguiente tabla de base de datos y partición de muestra. Esta base de datos utiliza una tabla particionada basada en una marca temporal. Un esquema `data_mart` contiene una tabla denominada `events` con una columna denominada `created_at`. En la `events` tabla se incluyen los siguientes ajustes:
+  Claves primarias `event_id` y `created_at`, que deben tener la columna utilizada para guiar la partición.
+ Una restricción de comprobación `ck_valid_operation` para aplicar los valores para una columna de la tabla `operation`.
+ Dos claves externas, donde una (`fk_orga_membership)` apunta a la tabla externa `organization` y la otra (`fk_parent_event_id`) es una clave externa con referencia propia. 
+ Dos índices, donde uno (`idx_org_id`) es para la clave externa y el otro (`idx_event_type`) es para el tipo de evento.

Las siguientes instrucciones DDL crean estos objetos, que se incluyen automáticamente en cada partición.

```
CREATE SCHEMA data_mart;
CREATE TABLE data_mart.organization ( org_id BIGSERIAL,
        org_name TEXT,
        CONSTRAINT pk_organization PRIMARY KEY (org_id)  
    );

CREATE TABLE data_mart.events(
        event_id        BIGSERIAL, 
        operation       CHAR(1), 
        value           FLOAT(24), 
        parent_event_id BIGINT, 
        event_type      VARCHAR(25), 
        org_id          BIGSERIAL, 
        created_at      timestamp, 
        CONSTRAINT pk_data_mart_event PRIMARY KEY (event_id, created_at), 
        CONSTRAINT ck_valid_operation CHECK (operation = 'C' OR operation = 'D'), 
        CONSTRAINT fk_orga_membership 
            FOREIGN KEY(org_id) 
            REFERENCES data_mart.organization (org_id),
        CONSTRAINT fk_parent_event_id 
            FOREIGN KEY(parent_event_id, created_at) 
            REFERENCES data_mart.events (event_id,created_at)
    ) PARTITION BY RANGE (created_at);

CREATE INDEX idx_org_id     ON  data_mart.events(org_id);
CREATE INDEX idx_event_type ON  data_mart.events(event_type);
```



## Configuración de particiones mediante la función create\$1parent
<a name="PostgreSQL_Partitions.create_parent"></a>

Después de habilitar la extensión `pg_partman`, utilice la función `create_parent` para configurar las particiones dentro del esquema de mantenimiento de particiones. En este ejemplo se utiliza el ejemplo de la tabla `events` creado en [Habilitación de la extensión pg\$1partmanConfiguración del mantenimiento de particiones mediante la función run\$1maintenance\$1proc](#PostgreSQL_Partitions.enable). Ejecute la función `create_parent` de la siguiente manera:

```
SELECT partman.create_parent( 
 p_parent_table => 'data_mart.events',
 p_control      => 'created_at',
 p_type         => 'range',
 p_interval     => '1 day',
 p_premake      => 30);
```

Los parámetros son los siguientes:
+ `p_parent_table` – La tabla principal particionada. Esta tabla ya debe existir y estar totalmente cualificada, incluido el esquema. 
+ `p_control` – La columna en la que se basará la partición. El tipo de datos debe ser entero o basado en el tiempo.
+ `p_type`: el tipo es `'range'` o `'list'`.
+ `p_interval` – El intervalo de tiempo o intervalo de enteros para cada partición. Los valores de ejemplo incluyen `1 day`, `1 hour`, etc.
+ `p_premake` – La cantidad de particiones que se debe crear de antemano para admitir nuevas inserciones.

Para obtener una descripción completa de la función `create_parent`, consulte [Funciones de creación](https://github.com/pgpartman/pg_partman/blob/master/doc/pg_partman.md#user-content-creation-functions) en la documentación de `pg_partman`.

## Configuración del mantenimiento de particiones mediante la función run\$1maintenance\$1proc
<a name="PostgreSQL_Partitions.run_maintenance_proc"></a>

Puede ejecutar operaciones de mantenimiento de particiones para crear automáticamente nuevas particiones, desasociar particiones o eliminar particiones antiguas. El mantenimiento de particiones se basa en la función `run_maintenance_proc` de la extensión `pg_partman` y la extensión `pg_cron`, que inicia un programador interno. El programador `pg_cron` ejecuta automáticamente instrucciones SQL, funciones y procedimientos definidos en las bases de datos. 

En el ejemplo siguiente se utiliza el ejemplo de la tabla `events` creado en [Habilitación de la extensión pg\$1partmanConfiguración del mantenimiento de particiones mediante la función run\$1maintenance\$1proc](#PostgreSQL_Partitions.enable) para establecer que las operaciones de mantenimiento de particiones se ejecuten automáticamente. Como requisito previo, agregue `pg_cron` al parámetro `shared_preload_libraries` en el grupo de parámetros de la instancia de base de datos.

```
CREATE EXTENSION pg_cron;

UPDATE partman.part_config 
SET infinite_time_partitions = true,
    retention = '3 months', 
    retention_keep_table=true 
WHERE parent_table = 'data_mart.events';
SELECT cron.schedule('@hourly', $$CALL partman.run_maintenance_proc()$$);
```

A continuación, puede encontrar una explicación paso a paso del ejemplo anterior: 

1. Modifique el grupo de parámetros asociado a la instancia de base de datos y agregue `pg_cron` al valor del parámetro `shared_preload_libraries`. Este cambio requiere un reinicio de la instancia de base de datos para que surta efecto. Para obtener más información, consulte [Modificación de los parámetros de un grupo de parámetros de base de datos en Amazon RDS](USER_WorkingWithParamGroups.Modifying.md). 

1. Ejecute el comando `CREATE EXTENSION pg_cron;` con una cuenta que tenga los permisos `rds_superuser`. Esto habilita la extensión `pg_cron`. Para obtener más información, consulte [Programación de mantenimiento con la extensión pg\$1cron de PostgreSQL](PostgreSQL_pg_cron.md).

1. Ejecute el comando `UPDATE partman.part_config` para ajustar la configuración de `pg_partman` para la tabla `data_mart.events`. 

1. Ejecute el comando `SET` . . . para configurar la tabla `data_mart.events`, con estas cláusulas:

   1. `infinite_time_partitions = true,` – Configura la tabla para que pueda crear automáticamente nuevas particiones sin ningún límite.

   1. `retention = '3 months',` – Configura la tabla para que tenga una retención máxima de tres meses. 

   1. `retention_keep_table=true `– Configura la tabla para que cuando venza el periodo de retención, la tabla no se elimine automáticamente. En su lugar, las particiones que son anteriores al periodo de retención solo se separan de la tabla principal.

1. Ejecute el comando `SELECT cron.schedule` . . . para hacer una llamada a la función `pg_cron`. Esta llamada define la frecuencia con la que el programador ejecuta el procedimiento de mantenimiento de `pg_partman`, `partman.run_maintenance_proc`. Para este ejemplo, el procedimiento se ejecuta cada hora. 

Para obtener una descripción completa de la función `run_maintenance_proc`, consulte [Funciones de mantenimiento](https://github.com/pgpartman/pg_partman/blob/master/doc/pg_partman.md#maintenance-functions) en la documentación de `pg_partman`. 

# Uso de pgAudit para registrar la actividad de la base de datos
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit"></a>

Las instituciones financieras, las agencias gubernamentales y muchas industrias necesitan mantener *registros de auditoría* para cumplir con los requisitos reglamentarios. Al utilizar la extensión de auditoría de PostgreSQL (PGAudit) con su Instancia de base de datos de RDS for PostgreSQL, puede capturar los registros detallados que suelen necesitar los auditores o para cumplir con los requisitos reglamentarios. Por ejemplo, puede configurar la extensión pgAudit para realizar un seguimiento de los cambios realizados en bases de datos y tablas específicas, para registrar el usuario que realizó el cambio y muchos otros detalles.

La extensión pgAudit se basa en la funcionalidad de la infraestructura de registro nativa de PostgreSQL ampliando los mensajes de registro con más detalle. En otras palabras, utiliza el mismo método para ver el registro de auditoría que para ver cualquier mensaje de registro. Para obtener más información sobre los registros de PostgreSQL, consulte [Archivos de registro de base de datos de RDS para PostgreSQL](USER_LogAccess.Concepts.PostgreSQL.md). 

La extensión PGAudit elimina los datos confidenciales, como las contraseñas de texto no cifrado, de los registros. Si su instancia de base de datos de RDS for PostgreSQL está configurado para registrar las instrucciones del lenguaje de manipulación de datos (DML) tal como se detalla en [Activación de registro de consultas para su instancia de base de datos de RDS para PostgreSQL](USER_LogAccess.Concepts.PostgreSQL.Query_Logging.md), puede evitar el problema de la contraseña de texto sin cifrar mediante la extensión de auditoría de PostgreSQL. 

Puede configurar la auditoría en las instancias de la base de datos con un alto grado de especificidad. Puede auditar todas las bases de datos y todos los usuarios. O bien, puede optar por auditar solo determinadas bases de datos, usuarios y otros objetos. También puede excluir explícitamente a determinados usuarios y bases de datos de la auditoría. Para obtener más información, consulte [Exclusión de usuarios o bases de datos del registro de auditoría](Appendix.PostgreSQL.CommonDBATasks.pgaudit.exclude-user-db.md). 

Dada la cantidad de detalles que se pueden capturar, le recomendamos que, si usa pgAudit, controle su consumo de almacenamiento. 

La extensión pgAudit es compatible con todas las Versiones de RDS para PostgreSQL: Para obtener una lista de las versiones de pgAudit compatibles con la versión de RDS para PostgreSQL, consulte [Versiones de extensión para Amazon RDS for PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html) en las *Notas de la versión de Amazon RDS for PostgreSQL.* 

**Topics**
+ [Configuración de la extensión pgAudit](Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup.md)
+ [Auditoría de objetos de base de datos](Appendix.PostgreSQL.CommonDBATasks.pgaudit.auditing.md)
+ [Exclusión de usuarios o bases de datos del registro de auditoría](Appendix.PostgreSQL.CommonDBATasks.pgaudit.exclude-user-db.md)
+ [Referencia para la extensión pgAudit](Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.md)

# Configuración de la extensión pgAudit
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup"></a>

Para configurar la extensión pgAudit en la instancia de base de datos de RDS for PostgreSQL , primero hay que añadir pgAudit a las bibliotecas compartidas en el grupo de parámetros de base de datos personalizado para su instancia de base de datos RDS for PostgreSQL. Para obtener información acerca de cómo crear el grupo de parámetros de base de datos, consulte [Grupos de parámetros para Amazon RDS](USER_WorkingWithParamGroups.md). A continuación, instale la extensión pgAudit. Por último, especifique las bases de datos y objetos que desea auditar. Los procedimientos de esta sección le muestran cómo hacerlo. Puede utilizar la Consola de administración de AWS o la AWS CLI. 

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

En los pasos siguientes se supone que la instancia de base de datos de RDS for PostgreSQL está asociada a un grupo de parámetros de DB. 

## Consola
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup.CON"></a>

**Para configurar la extensión pgAudit**

1. Inicie sesión en la Consola de administración de AWS y abra la consola de Amazon RDS en [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

1. En el panel de navegación, elija la instancia de base de datos de RDS for PostgreSQL.

1. Abra la pestaña **Configuration** (Configuración) para su Instancia de base de datos RDS para PostgreSQL. Entre los detalles de la instancia, busque el enlace del **grupo de parámetros**. 

1. Elija el enlace para abrir los parámetros personalizados asociados al Instancia de base de datos RDS para PostgreSQL. 

1. En el campo de búsqueda **Parametes** (Parámetros), escriba `shared_pre` para buscar el parámetro `shared_preload_libraries`.

1. Seleccione **Edit parameters** (Editar parámetros) para acceder a los valores de las propiedades.

1. Añada `pgaudit` a la lista en el campo **Values** (Valores). Utilice una coma para separar los elementos de la lista de valores.   
![\[Imagen del parámetro shared_preload_libaries con pgAudit añadido.\]](http://docs.aws.amazon.com/es_es/AmazonRDS/latest/UserGuide/images/apg_rpg_shared_preload_pgaudit.png)

1. Reinicie la instancia de base de datos de RDS for PostgreSQL para que surta efecto el cambio en el parámetro `shared_preload_libraries`. 

1. Cuando la instancia esté disponible, compruebe que pgAudit se haya inicializado. Use `psql` para conectarse a la instancia de base de datos de RDS for PostgreSQL y, a continuación, ejecute el siguiente comando.

   ```
   SHOW shared_preload_libraries;
   shared_preload_libraries 
   --------------------------
   rdsutils,pgaudit
   (1 row)
   ```

1. Con pgAudit inicializado, ahora puede crear la extensión. Debe crear la extensión después de inicializar la biblioteca, ya que la extensión `pgaudit` instala activadores de eventos para auditar las sentencias del lenguaje de definición de datos (DDL). 

   ```
   CREATE EXTENSION pgaudit;
   ```

1. Cierre la sesión de `psql`.

   ```
   labdb=> \q
   ```

1. Inicie sesión en la Consola de administración de AWS y abra la consola de Amazon RDS en [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

1. Busque el parámetro `pgaudit.log` en la lista y configúrelo con el valor adecuado para su caso de uso. Por ejemplo, al establecer el parámetro `pgaudit.log` en `write` como se muestra en la siguiente imagen, se capturan las inserciones, las actualizaciones, las eliminaciones y algunos otros tipos de cambios en el registro.   
![\[Imagen del parámetro pgaudit.log con la configuración.\]](http://docs.aws.amazon.com/es_es/AmazonRDS/latest/UserGuide/images/rpg_set_pgaudit-log-level.png)

   También puede elegir uno de los siguientes valores para el parámetro `pgaudit.log`.
   + none: es el valor predeterminado. No se registran cambios en la base de datos. 
   + all: registra todo (read, write, function, role, ddl, misc). 
   + ddl: registra todas las instrucciones del lenguaje de definición de datos (DDL) que no están incluidas en la clase `ROLE`.
   + function: registra llamadas a funciones y bloques `DO`.
   + misc: registra comandos variados como, por ejemplo, `DISCARD`, `FETCH`, `CHECKPOINT`, `VACUUM` y `SET`.
   + read: registra `SELECT` y `COPY` cuando el origen es una relación (como una tabla) o una consulta.
   + role: registra instrucciones relacionadas con roles y privilegios, como `GRANT`, `REVOKE`, `CREATE ROLE`, `ALTER ROLE` y `DROP ROLE`.
   + write: registra `INSERT`, `UPDATE`, `DELETE`, `TRUNCATE` y `COPY` cuando el destino es una relación (tabla).

1. Elija **Guardar cambios**.

1. Abra la consola de Amazon RDS en [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

1. Elija su instancia de base de datos de RDS para PostgreSQL desde la lista de bases de datos.

## AWS CLI
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup.CLI"></a>

**Para configurar pgAudit**

Para configurar pgAudit mediante AWS CLI, llame a la operación [modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html) para modificar los parámetros del registro de auditoría de su grupo de parámetros personalizado, como se muestra en el siguiente procedimiento.

1. Utilice el siguiente comando AWS CLI para añadir `pgaudit` al parámetro `shared_preload_libraries`.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=shared_preload_libraries,ParameterValue=pgaudit,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. Utilice el siguiente comando AWS CLI para reiniciar la instancia de base de datos de RDS for PostgreSQL para que se inicialice la biblioteca pgaudit.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. Cuando la instancia esté disponible, puede verificar si `pgaudit` se ha inicializado. Use `psql` para conectarse a la instancia de base de datos de RDS for PostgreSQL y, a continuación, ejecute el siguiente comando.

   ```
   SHOW shared_preload_libraries;
   shared_preload_libraries 
   --------------------------
   rdsutils,pgaudit
   (1 row)
   ```

   Con pgAudit inicializado, ahora puede crear la extensión.

   ```
   CREATE EXTENSION pgaudit;
   ```

1. Cierre la sesión de `psql` para poder utilizar AWS CLI.

   ```
   labdb=> \q
   ```

1. Utilice el siguiente comando AWS CLI para especificar las clases de instrucciones que desea registrar con el registro de auditoría de sesión. El ejemplo establece el parámetro `pgaudit.log` en`write`, que captura las inserciones, las actualizaciones y las eliminaciones del registro.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=pgaudit.log,ParameterValue=write,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

   También puede elegir uno de los siguientes valores para el parámetro `pgaudit.log`.
   + none: es el valor predeterminado. No se registran cambios en la base de datos. 
   + all: registra todo (read, write, function, role, ddl, misc). 
   + ddl: registra todas las instrucciones del lenguaje de definición de datos (DDL) que no están incluidas en la clase `ROLE`.
   + function: registra llamadas a funciones y bloques `DO`.
   + misc: registra comandos variados como, por ejemplo, `DISCARD`, `FETCH`, `CHECKPOINT`, `VACUUM` y `SET`.
   + read: registra `SELECT` y `COPY` cuando el origen es una relación (como una tabla) o una consulta.
   + role: registra instrucciones relacionadas con roles y privilegios, como `GRANT`, `REVOKE`, `CREATE ROLE`, `ALTER ROLE` y `DROP ROLE`.
   + write: registra `INSERT`, `UPDATE`, `DELETE`, `TRUNCATE` y `COPY` cuando el destino es una relación (tabla).

   Reinicie la instancia de base de datos de RDS for PostgreSQL mediante el siguiente comando AWS CLI.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

# Auditoría de objetos de base de datos
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.auditing"></a>

Con PGAudit configurado en su instancia de base de datos de RDS for PostgreSQL y configurado según sus requisitos, se captura información más detallada en el registro de PostgreSQL. Por ejemplo, si bien la configuración de registro predeterminada de PostgreSQL identifica la fecha y la hora en que se realizó un cambio en una tabla de base de datos, con la extensión pgAudit la entrada de registro puede incluir el esquema, el usuario que realizó el cambio y otros detalles, según cómo estén configurados los parámetros de la extensión. Puede configurar la auditoría para realizar un seguimiento de los cambios de las siguientes maneras.
+ Para cada sesión, por usuario. Para el nivel de sesión, puede capturar el texto completo del comando.
+ Para cada objeto, por usuario y por base de datos. 

La capacidad de auditoría de objetos se activa cuando se crea el rol `rds_pgaudit` en el sistema y, a continuación, se agrega este rol al parámetro `pgaudit.role` del grupo de parámetros personalizados. De forma predeterminada, el parámetro `pgaudit.role` no está configurado y el único valor permitido es `rds_pgaudit`. En los siguientes pasos se asume que `pgaudit` se ha inicializado y que ha se ha creado la extensión `pgaudit` siguiendo el procedimiento descrito en [Configuración de la extensión pgAudit](Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup.md). 

![\[Imagen del archivo de registro de PostgreSQL después de configurar pgAudit.\]](http://docs.aws.amazon.com/es_es/AmazonRDS/latest/UserGuide/images/pgaudit-log-example.png)


Como se muestra en este ejemplo, la línea «LOG: AUDIT: SESSION» proporciona información sobre la tabla y su esquema, entre otros detalles. 

**Para configurar la auditoría de objetos**

1. Use `psql` para conectarse a la insancia de base de tos de RDS for PostgreSQL.

   ```
   psql --host=your-instance-name.aws-region.rds.amazonaws.com --port=5432 --username=postgrespostgres --password --dbname=labdb
   ```

1. Cree un rol de base de datos llamado `rds_pgaudit` mediante el siguiente comando.

   ```
   labdb=> CREATE ROLE rds_pgaudit;
   CREATE ROLE
   labdb=>
   ```

1. Cierre la sesión de `psql`.

   ```
   labdb=> \q
   ```

   En los siguientes pasos, use elAWS CLI para modificar los parámetros del registro de auditoría en el grupo de parámetros personalizado. 

1. Utilice el siguiente comando AWS CLI para establecer el parámetro `pgaudit.role` en `rds_pgaudit`. De forma predeterminada, este parámetro está vacío y `rds_pgaudit` es el único valor permitido.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=pgaudit.role,ParameterValue=rds_pgaudit,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. Reinicie AWS CLIla instancia de la instancia de base de datos de RDS for PostgreSQL para que sus cambios en los parámetros surtan efecto.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. Ejecute el siguiente comando para confirmar que `pgaudit.role` se establece en `rds_pgaudit`.

   ```
   SHOW pgaudit.role;
   pgaudit.role 
   ------------------
   rds_pgaudit
   ```

Para probar el registro de pgAudit, puede ejecutar varios comandos de ejemplo que desee auditar. Por ejemplo, podría ejecutar los siguientes comandos.

```
CREATE TABLE t1 (id int);
GRANT SELECT ON t1 TO rds_pgaudit;
SELECT * FROM t1;
id 
----
(0 rows)
```

Los registros de base de datos contendrán una entrada similar a la siguiente.

```
...
2017-06-12 19:09:49 UTC:...:rds_test@postgres:[11701]:LOG: AUDIT:
OBJECT,1,1,READ,SELECT,TABLE,public.t1,select * from t1;
...
```

Para obtener información acerca de la visualización de los registros, consulte [Supervisión de archivos de registro de Amazon RDS](USER_LogAccess.md).

Para obtener más información sobre la extensión pgAudit, consulte [pgAudit](https://github.com/pgaudit/pgaudit/blob/master/README.md) en GitHub.

# Exclusión de usuarios o bases de datos del registro de auditoría
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.exclude-user-db"></a>

Como se explica en [Archivos de registro de base de datos de RDS para PostgreSQL](USER_LogAccess.Concepts.PostgreSQL.md), los registros de PostgreSQL consumen espacio de almacenamiento. El uso de la extensión pgAudit aumenta el volumen de datos recopilados en los registros en diversos grados, según los cambios de los que realice un seguimiento. Es posible que no necesite auditar todos los usuarios o bases de datos de su Instancia de base de datos RDS para PostgreSQL.

Para minimizar los impactos en el almacenamiento y evitar la captura innecesaria de registros de auditoría, puede excluir a los usuarios y las bases de datos de la auditoría. También puede cambiar el registro dentro de una sesión determinada. Los siguientes ejemplos muestran cola forma de hacerlo. 

**nota**  
La configuración de los parámetros a nivel de sesión tiene prioridad sobre la configuración del grupo de parámetros del grupo de parámetros de la base de datos personalizada para la instancia de la base de datos de RDS for PostgreSQL. Si no desea que los usuarios de la base de datos omitan los ajustes de configuración del registro de auditoría, asegúrese de cambiar sus permisos. 

Supongamos que su instancia de base de datos de RDS for PostgreSQL está configurado para auditar el mismo nivel de actividad para todos los usuarios y bases de datos. A continuación, decide que no desea auditar al usuario `myuser`. Puede desactivar la auditoría de `myuser` con el siguiente comando de SQL.

```
ALTER USER myuser SET pgaudit.log TO 'NONE';
```

A continuación, puede utilizar la siguiente consulta para comprobar la columna `user_specific_settings` de `pgaudit.log` para confirmar que el parámetro está establecido en `NONE`.

```
SELECT
    usename AS user_name,
    useconfig AS user_specific_settings
FROM
    pg_user
WHERE
    usename = 'myuser';
```

Debería ver una salida como la siguiente.

```
 user_name | user_specific_settings
-----------+------------------------
 myuser    | {pgaudit.log=NONE}
(1 row)
```

Puede desactivar el registro de un usuario determinado en medio de su sesión con la base de datos con el siguiente comando.

```
ALTER USER myuser IN DATABASE mydatabase SET pgaudit.log TO 'none';
```

Utilice la siguiente consulta para comprobar la columna de configuración de pgaudit.log para una combinación específica de usuario y base de datos. 

```
SELECT
    usename AS "user_name",
    datname AS "database_name",
    pg_catalog.array_to_string(setconfig, E'\n') AS "settings"
FROM
    pg_catalog.pg_db_role_setting s
    LEFT JOIN pg_catalog.pg_database d ON d.oid = setdatabase
    LEFT JOIN pg_catalog.pg_user r ON r.usesysid = setrole
WHERE
    usename = 'myuser'
    AND datname = 'mydatabase'
ORDER BY
    1,
    2;
```

Se muestra una salida similar a la siguiente.

```
  user_name | database_name |     settings
-----------+---------------+------------------
 myuser    | mydatabase    | pgaudit.log=none
(1 row)
```

Tras desactivar la auditoría de `myuser`, decide que no desea realizar un seguimiento de los cambios en `mydatabase`. Puede desactivar la auditoría de esa base de datos específica mediante el siguiente comando.

```
ALTER DATABASE mydatabase SET pgaudit.log to 'NONE';
```

A continuación, utilice la siguiente consulta para comprobar la columna database\$1specific\$1settings y confirmar que pgaudit.log tiene el valor NONE.

```
SELECT
a.datname AS database_name,
b.setconfig AS database_specific_settings
FROM
pg_database a
FULL JOIN pg_db_role_setting b ON a.oid = b.setdatabase
WHERE
a.datname = 'mydatabase';
```

Debería ver una salida como la siguiente.

```
 database_name | database_specific_settings
---------------+----------------------------
 mydatabase    | {pgaudit.log=NONE}
(1 row)
```

Para restablecer la configuración predeterminada de myuser, use el siguiente comando:

```
ALTER USER myuser RESET pgaudit.log;
```

Para restablecer la configuración predeterminada de una base de datos, use el siguiente comando:

```
ALTER DATABASE mydatabase RESET pgaudit.log;
```

Para restablecer el usuario y la base de datos a la configuración por defecto, utilice el siguiente comando.

```
ALTER USER myuser IN DATABASE mydatabase RESET pgaudit.log;
```

También puede capturar eventos específicos en el registro configurando `pgaudit.log` en uno de los otros valores permitidos para el parámetro `pgaudit.log`. Para obtener más información, consulte [Lista de ajustes permitidos para el parámetro `pgaudit.log`](Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.md#Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.pgaudit-log-settings).

```
ALTER USER myuser SET pgaudit.log TO 'read';
ALTER DATABASE mydatabase SET pgaudit.log TO 'function';
ALTER USER myuser IN DATABASE mydatabase SET pgaudit.log TO 'read,function'
```

# Referencia para la extensión pgAudit
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference"></a>

Puede especificar el nivel de detalle que desea para el registro de auditoría cambiando uno o más de los parámetros que se enumeran en esta sección. 

## Control del comportamiento de pgAudit
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.basic-setup.parameters"></a>

Puede controlar el registro de auditoría cambiando uno o más de los parámetros que aparecen en la tabla siguiente. 


| Parámetro | Descripción | 
| --- | --- | 
| `pgaudit.log`  | Especifica las clases de instrucciones que se registrarán mediante el registro de auditoría de sesión. Los valores permitidos incluyen ddl, function, misc, read, role, write, none, all. Para obtener más información, consulte [Lista de ajustes permitidos para el parámetro `pgaudit.log`](#Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.pgaudit-log-settings).  | 
| `pgaudit.log_catalog` | Cuando se activa (se establece en 1), agrega instrucciones al registro de auditoría si todas las relaciones de una instrucción se encuentran en pg\$1catalog. | 
| `pgaudit.log_level` | Especifica el nivel de registro que se usará para las entradas de registro. Valores permitidos, debug5, debug4, debug3, debug2, debug1, info, notice, warning, log. | 
| `pgaudit.log_parameter` | Cuando se activa (se establece en 1), los parámetros transmitidos con la instrucción se capturan en el registro de auditoría. | 
| `pgaudit.log_relation` | Cuando se activa (se establece en 1), el registro de auditoría de la sesión crea una entrada de registro separada para cada relación (TABLE, VIEW, etc.) referenciada en una instrucción SELECT o DML. | 
| `pgaudit.log_statement_once` | Especifica si el registro incluirá el texto de la instrucción y los parámetros con la primera entrada de registro para una combinación de instrucción o subinstrucción o con cada entrada. | 
| `pgaudit.role` | Especifica el rol maestro que se usará para el registro de auditoría de objetos. La única entrada permitida es `rds_pgaudit`. | 

## Lista de ajustes permitidos para el parámetro `pgaudit.log`
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.pgaudit-log-settings"></a>

 


| Valor | Descripción | 
| --- | --- | 
| none | Esta es la opción predeterminada. No se registran cambios en la base de datos.  | 
| all | Registra todo (read, write, function, role, ddl, misc).  | 
| ddl | Registra todas las instrucciones del lenguaje de definición de datos (DDL) que no están incluidas en la clase `ROLE`. | 
| función | Registra llamadas a funciones y bloques `DO`. | 
| misc | Registra comandos variados como, por ejemplo, `DISCARD`, `FETCH`, `CHECKPOINT`, `VACUUM` y `SET`. | 
| lectura | Registra `SELECT` y `COPY` cuando el origen es una relación (como una tabla) o una consulta. | 
| rol | Registra instrucciones relacionadas con roles y privilegios, como, por ejemplo, `GRANT`, `REVOKE`, `CREATE ROLE`, `ALTER ROLE` y `DROP ROLE`. | 
| escritura | Registra `INSERT`, `UPDATE`, `DELETE`, `TRUNCATE` y `COPY` cuando el destino es una relación (tabla). | 

Para registrar varios tipos de eventos con auditorías de sesiones, utilice una lista separada por comas. Para registrar todos los tipos de eventos, establezca `pgaudit.log` en `ALL`. Reinicie la instancia de base de datos para aplicar los cambios.

Con la auditoría de objetos, puede mejorar los registros de auditoría para que funcionen con algunas relaciones específicas. Por ejemplo, puede especificar que desea crear registros de auditoría para las operaciones `READ` en una o más tablas.

# Programación de mantenimiento con la extensión pg\$1cron de PostgreSQL
<a name="PostgreSQL_pg_cron"></a>

Puede utilizar la extensión `pg_cron` de PostgreSQL para programar comandos de mantenimiento dentro de una base de datos de PostgreSQL. Para obtener más información sobre la extensión, consulte [¿Qué es pg\$1cron?](https://github.com/citusdata/pg_cron) en la documentación de pg\$1cron. 

La extensión `pg_cron` es compatible con las versiones 12.5 y posteriores del motor de RDS para PostgreSQL.

Para obtener más información acerca del uso de `pg_cron`, consulte [Programación de mantenimiento con la extensión pg\$1cron de PostgreSQL para sus bases de datos de RDS para PostgreSQL o las bases de datos de Aurora PostgreSQL-Compatible Edition](https://aws.amazon.com/blogs/database/schedule-jobs-with-pg_cron-on-your-amazon-rds-for-postgresql-or-amazon-aurora-for-postgresql-databases/)

**nota**  
La versión de la extensión de `pg_cron` se muestra como una versión de dos dígitos, por ejemplo, 1.6, en la vista pg\$1available\$1extensions. Si bien es posible que vea versiones de tres dígitos, por ejemplo, 1.6.4 o 1.6.5, en algunos contextos, debe especificar la versión de dos dígitos al realizar una actualización de extensión.

**Topics**
+ [Configuración de la extensión pg\$1cron](#PostgreSQL_pg_cron.enable)
+ [Concesión de permisos para usuarios de base de datos para usar pg\$1cron](#PostgreSQL_pg_cron.permissions)
+ [Programación de trabajos pg\$1cron](#PostgreSQL_pg_cron.examples)
+ [Referencia para la extensión pg\$1cron](#PostgreSQL_pg_cron.reference)

## Configuración de la extensión pg\$1cron
<a name="PostgreSQL_pg_cron.enable"></a>

Habilite la extensión de `pg_cron` de la siguiente manera:

1. Modifique el grupo de parámetros personalizado asociado a la instancia de base de datos de PostgreSQL agregando `pg_cron` al valor del parámetro `shared_preload_libraries`.
   + Si su instancia de base de datos de RDS para PostgreSQL utiliza el parámetro `rds.allowed_extensions` para enumerar de forma explícita las extensiones que se pueden instalar, debe añadir la extensión `pg_cron` a la lista. Solo ciertas versiones de RDS para PostgreSQL admiten el parámetro `rds.allowed_extensions`. De forma predeterminada, se permiten todas las extensiones disponibles. Para obtener más información, consulte [Restringir la instalación de extensiones de PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.Extensions.md#PostgreSQL.Concepts.General.FeatureSupport.Extensions.Restriction).

   Reinicie la instancia de base de datos de PostgreSQL para que se apliquen los cambios en el grupo de parámetros. Para obtener más información acerca de cómo trabajar con grupos de parámetros, consulte [Modificación de los parámetros de un grupo de parámetros de base de datos en Amazon RDS](USER_WorkingWithParamGroups.Modifying.md). 

1. Una vez reiniciada la instancia de base de datos de PostgreSQL, ejecute el siguiente comando con una cuenta que tenga permisos `rds_superuser`. Por ejemplo, si utilizó la configuración predeterminada al crear la instancia de base de datos RDS para PostgreSQL, conéctese como usuario `postgres` y cree la extensión. 

   ```
   CREATE EXTENSION pg_cron;
   ```

   El programador `pg_cron` se establece en la base de datos de PostgreSQL predeterminada que se denomina `postgres`. Los objetos `pg_cron` se crean en esta base de datos `postgres` y todas las acciones de programación se ejecutan en esta base de datos.

1. Puede utilizar la configuración predeterminada o programar trabajos que ejecutar en otras bases de datos en la instancia de base de datos de PostgreSQL. Para programar trabajos de otras bases de datos en la instancia de base de datos de PostgreSQL, consulte el ejemplo en [Programación de un trabajo cron para una base de datos que no sea la predeterminada](#PostgreSQL_pg_cron.otherDB).

## Concesión de permisos para usuarios de base de datos para usar pg\$1cron
<a name="PostgreSQL_pg_cron.permissions"></a>

La instalación de la extensión `pg_cron` requiere privilegios de `rds_superuser`. Sin embargo, los permisos para usar `pg_cron` se pueden conceder (los concede un miembro del grupo/rol `rds_superuser`) a otros usuarios de la base de datos para que puedan programar sus propios trabajos. Es recomendable que conceda permisos al esquema `cron` solo según sea necesario si mejora las operaciones en su entorno de producción. 

Para conceder permiso a un usuario de base de datos en el esquema `cron`, ejecute el siguiente comando:

```
postgres=> GRANT USAGE ON SCHEMA cron TO db-user;
```

Esto da permiso *db-user* para acceder al esquema de `cron` para programar trabajos cron para los objetos a los que tienen permiso de acceso. Si el usuario de la base de datos no tiene permisos, se produce un error en el trabajo tras publicar el mensaje de error en el `postgresql.log`, como se muestra a continuación:

```
2020-12-08 16:41:00 UTC::@:[30647]:ERROR: permission denied for table table-name
2020-12-08 16:41:00 UTC::@:[27071]:LOG: background worker "pg_cron" (PID 30647) exited with exit code 1
```

En otras palabras, asegúrese de que los usuarios de bases de datos a los que se les conceden permisos en el esquema de `cron` también tengan permisos sobre los objetos (tablas, esquemas, etc.) que tienen pensado programar.

Los detalles del trabajo cron y su éxito o fracaso también se capturan en la tabla `cron.job_run_details`. Para obtener más información, consulte [Tablas para programar trabajos y capturar estado](#PostgreSQL_pg_cron.tables).

## Programación de trabajos pg\$1cron
<a name="PostgreSQL_pg_cron.examples"></a>

En las secciones que siguen se muestra cómo programar varias tareas de administración con trabajos `pg_cron`.

**nota**  
Al crear trabajos `pg_cron`, compruebe que el valor `max_worker_processes` sea mayor que el número de `cron.max_running_jobs`. Se producirá un error en el trabajo `pg_cron` si se queda sin procesos de trabajo en segundo plano. El número predeterminado de trabajos `pg_cron` es `5`. Para obtener más información, consulte [Parámetros para administrar la extensión pg\$1cron](#PostgreSQL_pg_cron.parameters).

**Topics**
+ [Limpieza de tablas](#PostgreSQL_pg_cron.vacuum)
+ [Depuración de la tabla del historial pg\$1cron](#PostgreSQL_pg_cron.job_run_details)
+ [Registrar errores únicamente en el archivo postgresql.log](#PostgreSQL_pg_cron.log_run)
+ [Programación de un trabajo cron para una base de datos que no sea la predeterminada](#PostgreSQL_pg_cron.otherDB)

### Limpieza de tablas
<a name="PostgreSQL_pg_cron.vacuum"></a>

En la mayoría de los casos, autovacuum maneja el mantenimiento de limpieza. Sin embargo, se recomienda programar una limpieza de una tabla específica en el momento que lo desee. 

Véase también, [Uso de autovacuum de PostgreSQL en Amazon RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md). 

A continuación, se muestra un ejemplo del uso de la función `cron.schedule` para configurar un trabajo para usar `VACUUM FREEZE` en una tabla específica todos los días a las 22:00 (GMT).

```
SELECT cron.schedule('manual vacuum', '0 22 * * *', 'VACUUM FREEZE pgbench_accounts');
 schedule
----------
1
(1 row)
```

Una vez ejecutado el ejemplo anterior, puede comprobar del siguiente modo el historial de la `cron.job_run_details` tabla.

```
postgres=> SELECT * FROM cron.job_run_details;
jobid  | runid | job_pid | database | username | command                        | status    | return_message | start_time                    | end_time
-------+-------+---------+----------+----------+--------------------------------+-----------+----------------+-------------------------------+-------------------------------
 1     | 1     | 3395    | postgres | adminuser| vacuum freeze pgbench_accounts | succeeded | VACUUM         | 2020-12-04 21:10:00.050386+00 | 2020-12-04 21:10:00.072028+00
(1 row)
```

A continuación, se presenta una consulta de la tabla `cron.job_run_details` para ver los trabajos fallidos.

```
postgres=> SELECT * FROM cron.job_run_details WHERE status = 'failed';
jobid | runid | job_pid | database | username | command                       | status | return_message                                   | start_time                    | end_time
------+-------+---------+----------+----------+-------------------------------+--------+--------------------------------------------------+-------------------------------+------------------------------
 5    | 4     | 30339   | postgres | adminuser| vacuum freeze pgbench_account | failed | ERROR: relation "pgbench_account" does not exist | 2020-12-04 21:48:00.015145+00 | 2020-12-04 21:48:00.029567+00
(1 row)
```

Para obtener más información, consulte [Tablas para programar trabajos y capturar estado](#PostgreSQL_pg_cron.tables).

### Depuración de la tabla del historial pg\$1cron
<a name="PostgreSQL_pg_cron.job_run_details"></a>

La tabla `cron.job_run_details` contiene un historial de los trabajos cron que con el tiempo pueden volverse muy grandes. Se recomienda programar un trabajo que depure esta tabla. Por ejemplo, mantener entradas de una semana podría ser suficiente para solucionar problemas. 

En el siguiente ejemplo se utiliza la función [cron.schedule](#PostgreSQL_pg_cron.schedule) para programar un trabajo que se ejecuta todos los días a la medianoche para depurar la tabla `cron.job_run_details`. El trabajo mantiene solo los últimos siete días. Utilice su cuenta de `rds_superuser` para programar el trabajo de la siguiente manera:

```
SELECT cron.schedule('0 0 * * *', $$DELETE 
    FROM cron.job_run_details 
    WHERE end_time < now() - interval '7 days'$$);
```

Para obtener más información, consulte [Tablas para programar trabajos y capturar estado](#PostgreSQL_pg_cron.tables).

### Registrar errores únicamente en el archivo postgresql.log
<a name="PostgreSQL_pg_cron.log_run"></a>

Para evitar escribir en la tabla `cron.job_run_details`, modifique el grupo de parámetros asociado a la instancia de base de datos de PostgreSQL y establezca el parámetro `cron.log_run` en Off (Desactivado). La extensión `pg_cron` ya no escribe en la tabla y captura errores solo en el archivo `postgresql.log`. Para obtener más información, consulte [Modificación de los parámetros de un grupo de parámetros de base de datos en Amazon RDS](USER_WorkingWithParamGroups.Modifying.md). 

Utilice el siguiente comando para comprobar el valor del parámetro `cron.log_run`.

```
postgres=> SHOW cron.log_run;
```

Para obtener más información, consulte [Parámetros para administrar la extensión pg\$1cron](#PostgreSQL_pg_cron.parameters).

### Programación de un trabajo cron para una base de datos que no sea la predeterminada
<a name="PostgreSQL_pg_cron.otherDB"></a>

Todos los metadatos de `pg_cron` se mantienen en la base de datos predeterminada de PostgreSQL que se denomina `postgres`. Dado que los trabajadores en segundo plano se utilizan para ejecutar los trabajos cron de mantenimiento, puede programar un trabajo en cualquiera de sus bases de datos dentro de la instancia de base de datos de PostgreSQL:

**nota**  
Solo los usuarios con el rol `rds_superuser` o los privilegios `rds_superuser` pueden mostrar todos los trabajos cron en la base de datos. Los demás usuarios solo pueden ver sus propios trabajos en la tabla `cron.job`.

1. En la base de datos cron, programe el trabajo como lo hace normalmente mediante el uso de [cron.schedule](#PostgreSQL_pg_cron.schedule).

   ```
   postgres=> SELECT cron.schedule('database1 manual vacuum', '29 03 * * *', 'vacuum freeze test_table');
   ```

1. Como usuario con el rol `rds_superuser`, actualice la columna de base de datos para el trabajo que acaba de crear a fin de que se ejecute en otra base de datos dentro de la instancia de base de datos de PostgreSQL.

   ```
   postgres=> UPDATE cron.job SET database = 'database1' WHERE jobid = 106;
   ```

1.  Verifique consultando la tabla `cron.job`.

   ```
   postgres=> SELECT * FROM cron.job;
   jobid | schedule    | command                        | nodename  | nodeport | database | username  | active | jobname
   ------+-------------+--------------------------------+-----------+----------+----------+-----------+--------+-------------------------
   106   | 29 03 * * * | vacuum freeze test_table       | localhost | 8192     | database1| adminuser | t      | database1 manual vacuum
     1   | 59 23 * * * | vacuum freeze pgbench_accounts | localhost | 8192     | postgres | adminuser | t      | manual vacuum
   (2 rows)
   ```

**nota**  
En algunas situaciones, puede agregar un trabajo cron que desea ejecutar en otra base de datos. En tales casos, el trabajo podría intentar ejecutarse en la base de datos predeterminada (`postgres`) antes de actualizar la columna de la base de datos correcta. Si el nombre de usuario tiene permisos, el trabajo se ejecuta correctamente en la base de datos predeterminada.

## Referencia para la extensión pg\$1cron
<a name="PostgreSQL_pg_cron.reference"></a>

Con la extensión `pg_cron`, puede utilizar los siguientes parámetros, funciones y tablas. Para obtener más información, consulte [¿Qué es pg\$1cron? ](https://github.com/citusdata/pg_cron) en la documentación de pg\$1cron.

**Topics**
+ [Parámetros para administrar la extensión pg\$1cron](#PostgreSQL_pg_cron.parameters)
+ [Referencia de función: cron.schedule](#PostgreSQL_pg_cron.schedule)
+ [Referencia de función: cron.unschedule](#PostgreSQL_pg_cron.unschedule)
+ [Tablas para programar trabajos y capturar estado](#PostgreSQL_pg_cron.tables)

### Parámetros para administrar la extensión pg\$1cron
<a name="PostgreSQL_pg_cron.parameters"></a>

A continuación, aparece la lista de parámetros para controlar el comportamiento de la extensión `pg_cron`. 


| Parámetro | Descripción | 
| --- | --- | 
| cron.database\$1name |  La base de datos en la que se conservan los metadatos de `pg_cron`.  | 
| cron.host |  El nombre de host que se va a conectar a PostgreSQL. No se puede modificar este valor.  | 
| cron.log\$1run |  Registre todos los trabajos que se ejecutan en la tabla `job_run_details`. Los valores son `on` o `off`. Para obtener más información, consulte [Tablas para programar trabajos y capturar estado](#PostgreSQL_pg_cron.tables).  | 
| cron.log\$1statement |  Registre todas las instrucciones cron antes de ejecutarlas. Los valores son `on` o `off`.  | 
| cron.max\$1running\$1jobs |  La cantidad máxima de trabajos que se pueden ejecutar simultáneamente.  | 
| cron.use\$1background\$1workers |  Utilice procesos de trabajo secundarios en lugar de sesiones de cliente. No se puede modificar este valor.  | 

Utilice el siguiente comando SQL para mostrar estos parámetros y sus valores:

```
postgres=> SELECT name, setting, short_desc FROM pg_settings WHERE name LIKE 'cron.%' ORDER BY name;
```

### Referencia de función: cron.schedule
<a name="PostgreSQL_pg_cron.schedule"></a>

Esta función programa un trabajo cron. El trabajo se programa inicialmente en la base de datos predeterminada `postgres`. La función devuelve un valor `bigint` que representa el identificador del trabajo. Para programar trabajos para que se ejecuten en otras bases de datos dentro de la instancia de base de datos de PostgreSQL, consulte el ejemplo en [Programación de un trabajo cron para una base de datos que no sea la predeterminada](#PostgreSQL_pg_cron.otherDB).

La función presenta dos formatos de sintaxis.

**Sintaxis**  

```
cron.schedule (job_name,
    schedule,
    command
);

cron.schedule (schedule,
    command
);
```

**Parámetros**      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonRDS/latest/UserGuide/PostgreSQL_pg_cron.html)

**Ejemplos**  

```
postgres=> SELECT cron.schedule ('test','0 10 * * *', 'VACUUM pgbench_history');
 schedule
----------
      145
(1 row)

postgres=> SELECT cron.schedule ('0 15 * * *', 'VACUUM pgbench_accounts');
 schedule
----------
      146
(1 row)
```

### Referencia de función: cron.unschedule
<a name="PostgreSQL_pg_cron.unschedule"></a>

Esta función elimina un trabajo cron. Puede especificar `job_name` o `job_id`. Una política se asegura de que usted es el propietario para quitar la programación del trabajo. La función devuelve un valor booleano que indica éxito o error.

La función tiene los siguientes formatos de sintaxis.

**Sintaxis**  

```
cron.unschedule (job_id);

cron.unschedule (job_name);
```

**Parámetros**      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonRDS/latest/UserGuide/PostgreSQL_pg_cron.html)

**Ejemplos**  

```
postgres=> SELECT cron.unschedule(108);
 unschedule
------------
 t
(1 row)

postgres=> SELECT cron.unschedule('test');
 unschedule
------------
 t
(1 row)
```

### Tablas para programar trabajos y capturar estado
<a name="PostgreSQL_pg_cron.tables"></a>

Las siguientes tablas se crean y utilizan para programar los trabajos cron y registrar la forma en la que se completaron. 


| Tabla | Descripción | 
| --- | --- | 
| cron.job |  Contiene los metadatos de cada trabajo programado. La mayoría de las interacciones con esta tabla se deben hacer mediante el uso de las funciones `cron.schedule` y `cron.unschedule`.  No recomendamos conceder privilegios de actualización o inserción directamente a esta tabla. Al hacerlo, el usuario podría actualizar la columna `username` para que se ejecute como `rds-superuser`.   | 
| cron.job\$1run\$1details |  Contiene información histórica sobre ejecuciones de trabajos programados anteriores. Esto resulta útil para investigar el estado, los mensajes devueltos y la hora de inicio y finalización de la ejecución del trabajo.  Para evitar que esta tabla crezca indefinidamente, púrguela regularmente. Para ver un ejemplo, consulte [Depuración de la tabla del historial pg\$1cron](#PostgreSQL_pg_cron.job_run_details).   | 

# Uso de pglogical para sincronizar datos entre instancias
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical"></a>

Todas las versiones de RDS para PostgreSQL disponibles actualmente admiten la extensión `pglogical`. La extensión pglogical es anterior a la función de replicación lógica funcionalmente similar que se introdujo en la versión 10 de PostgreSQL. Para obtener más información, consulte [Replicación lógica para Amazon RDS para PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.LogicalReplication.md).

La extensión `pglogical` admite la replicación lógica entre dos o más Instancias de base de datos de RDS para PostgreSQL. También admite la replicación entre diferentes versiones de PostgreSQL y entre bases de datos que se ejecutan en instancias de base de datos de RDS para PostgreSQL y clústeres de bases de datos de Aurora PostgreSQL. La extensión `pglogical` utiliza un modelo de publicación y suscripción para replicar los cambios en las tablas y otros objetos, como secuencias, de un publicador a un suscriptor. Se basa en una ranura de replicación para garantizar que los cambios se sincronicen de un nodo publicador a un nodo suscriptor, que se define de la siguiente manera. 
+ El *nodo publicador* es la instancia de base de datos de RDS para PostgreSQL, que es la fuente de datos que se van a replicar en otros nodos. El nodo publicador define las tablas que se van a replicar en un conjunto de publicaciones. 
+ El *nodo suscriptor* es la instancia de base de datos de RDS para PostgreSQL que recibe las actualizaciones WAL del publicador. El suscriptor crea una suscripción para conectarse al publicador y obtener los datos WAL decodificados. Cuando el suscriptor crea la suscripción, se crea la ranura de replicación en el nodo del publicador. 

A continuación, encontrará información sobre cómo configurar la extensión `pglogical`. 

**Topics**
+ [Requisitos y limitaciones de la extensión pglogical](#Appendix.PostgreSQL.CommonDBATasks.pglogical.requirements-limitations)
+ [Configuración de la extensión pglogical](Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.md)
+ [Configuración de la replicación lógica para la instancia de base de datos de RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.pglogical.setup-replication.md)
+ [Restablecimiento de la replicación lógica después de una actualización principal](Appendix.PostgreSQL.CommonDBATasks.pglogical.recover-replication-after-upgrade.md)
+ [Administración de ranuras de replicación lógica para RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.pglogical.handle-slots.md)
+ [Referencia de parámetros para la extensión pglogical](Appendix.PostgreSQL.CommonDBATasks.pglogical.reference.md)

## Requisitos y limitaciones de la extensión pglogical
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.requirements-limitations"></a>

Todas las versiones disponibles actualmente de RDS para PostgreSQL admiten la extensión `pglogical`. 

Tanto el nodo publicador como el nodo suscriptor deben estar configurados para la replicación lógica.

Las tablas que desee replicar desde un publicador a un suscriptor deben tener los mismos nombres y el mismo esquema. Estas tablas también deben contener las mismas columnas y las columnas deben utilizar los mismos tipos de datos. Tanto las tablas de los publicadores como las de suscriptores deben tener las mismas claves principales. Se recomienda utilizar únicamente la PRIMARY KEY como restricción única.

Las tablas del nodo suscriptor pueden tener restricciones más permisivas que las del nodo publicador para las restricciones CHECK y NOT NULL. 

La extensión `pglogical` proporciona funciones como la replicación bidireccional que no son compatibles con la función de replicación lógica integrada en PostgreSQL (versión 10 y posteriores). Para obtener más información, consulte [PostgreSQL bi-directional replication using pglogical](https://aws.amazon.com/blogs/database/postgresql-bi-directional-replication-using-pglogical/) (Replicación bidireccional de PostgreSQL mediante pglogical).

# Configuración de la extensión pglogical
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup"></a>

Para configurar la extensión `pglogical` en la instancia de base de datos de RDS para PostgreSQL , añada `pglogical` a las bibliotecas compartidas en el grupo de parámetros de base de datos personalizado para su instancia de base de datos de RDS para PostgreSQL. También debe establecer el valor del parámetro `rds.logical_replication` en `1` para activar la descodificación lógica. Por último, cree la extensión en la base de datos. Puede utilizar la Consola de administración de AWS o la AWS CLI para estas tareas. 

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

En los pasos siguientes se supone que su 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 acerca de cómo crear el grupo de parámetros de base de datos, consulte [Grupos de parámetros para Amazon RDS](USER_WorkingWithParamGroups.md).

## Consola
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.CON"></a>

**Para configurar la extensión pglogical**

1. Inicie sesión en la Consola de administración de AWS y abra la consola de Amazon RDS en [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

1. En el panel de navegación, elija la instancia de base de datos de RDS for PostgreSQL.

1. Abra la pestaña **Configuration** (Configuración) para su Instancia de base de datos RDS para PostgreSQL. Entre los detalles de la instancia, busque el enlace del **grupo de parámetros**. 

1. Elija el enlace para abrir los parámetros personalizados asociados al Instancia de base de datos RDS para PostgreSQL. 

1. En el campo de búsqueda **Parametes** (Parámetros), escriba `shared_pre` para buscar el parámetro `shared_preload_libraries`.

1. Seleccione **Edit parameters** (Editar parámetros) para acceder a los valores de las propiedades.

1. Añada `pglogical` a la lista en el campo **Values** (Valores). Utilice una coma para separar los elementos de la lista de valores.   
![\[Imagen del parámetro shared_preload_libraries con pglogical añadido.\]](http://docs.aws.amazon.com/es_es/AmazonRDS/latest/UserGuide/images/apg_rpg_shared_preload_pglogical.png)

1. Busque el parámetro `rds.logical_replication` y configúrelo en `1` para activar la replicación lógica.

1. Reinicie la instancia de base de datos de RDS para PostgreSQL para que surtan efecto los cambios. 

1. Cuando la instancia esté disponible, puede usar `psql` (o pgAdmin) para conectarse a la instancia de base de datos de RDS para PostgreSQL. 

   ```
   psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1. Para comprobar que pglogical esté inicializado, ejecute el siguiente comando.

   ```
   SHOW shared_preload_libraries;
   shared_preload_libraries 
   --------------------------
   rdsutils,pglogical
   (1 row)
   ```

1. Compruebe la configuración que permite la descodificación lógica, de la siguiente manera.

   ```
   SHOW wal_level;
   wal_level
   -----------
    logical
   (1 row)
   ```

1. Cree la extensión de la siguiente manera.

   ```
   CREATE EXTENSION pglogical;
   EXTENSION CREATED
   ```

1. Seleccione **Save changes (Guardar cambios)**.

1. Abra la consola de Amazon RDS en [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

1. Elija instancia de base de datos de RDS for PostgreSQL en la lista de bases de datos para seleccionarla y, a continuación, elija **Reboot** (Reiniciar) en el menú Actions (Acciones).

## AWS CLI
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.CLI"></a>

**Para configurar la extensión pglogical**

Para configurar pglogical mediante la AWS CLI, llame a la operación [modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html) 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 AWS CLI para añadir `pglogical` al parámetro `shared_preload_libraries`.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=shared_preload_libraries,ParameterValue=pglogical,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. Utilice el siguiente comando AWS CLI para configurar `rds.logical_replication` en `1` y activar la función de descodificación lógica para la Instancia de base de datos RDS para PostgreSQL.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=rds.logical_replication,ParameterValue=1,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. Utilice el siguiente comando AWS CLI para reiniciar la instancia de base de datos de RDS para PostgreSQL para que se inicialice la biblioteca de pglogical.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. Cuando la instancia esté disponible, use `psql` para conectarse a la instancia de base de datos de RDS para PostgreSQL. 

   ```
   psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1. Cree la extensión de la siguiente manera.

   ```
   CREATE EXTENSION pglogical;
   EXTENSION CREATED
   ```

1. Reinicie la instancia de base de datos de RDS for PostgreSQL mediante el siguiente comando AWS CLI.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

# Configuración de la replicación lógica para la instancia de base de datos de RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.setup-replication"></a>

En el siguiente procedimiento, se muestra cómo iniciar la replicación lógica entre dos instancias de base de datos de RDS para PostgreSQL. En los pasos, se asume que tanto el origen (publicador) como el destino (suscriptor) tienen la extensión `pglogical` configurada como se detalla en [Configuración de la extensión pglogical](Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.md). 

**nota**  
El `node_name` de un nodo de suscriptor no puede empezar por `rds`.

**Para crear el nodo publicador y definir las tablas que se van a replicar**

En estos pasos se asume que la instancia de base de datos de RDS para PostgreSQL tiene una base de datos que tiene una o más tablas que desea replicar en otro nodo. Debe volver a crear la estructura de tablas del publicador en el suscriptor, así que primero debe obtener la estructura de la tabla si es necesario. Para ello, utilice el metacomando de `psql` `\d tablename` y, a continuación, cree la misma tabla en la instancia del suscriptor. El siguiente procedimiento crea una tabla de ejemplo en el publicador (origen) con fines de demostración.

1. Utilice `psql` para conectarse a la instancia que tiene la tabla que desea usar como origen para los suscriptores. 

   ```
   psql --host=source-instance.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

   Si no dispone de una tabla existente que desee replicar, puede crear una tabla de ejemplo de la siguiente manera.

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

      ```
      CREATE TABLE docs_lab_table (a int PRIMARY KEY);
      ```

   1. Rellene la tabla con los datos generados mediante la siguiente instrucción SQL.

      ```
      INSERT INTO docs_lab_table VALUES (generate_series(1,5000));
      INSERT 0 5000
      ```

   1. Compruebe que los datos existen en la tabla mediante la siguiente instrucción SQL.

      ```
      SELECT count(*) FROM docs_lab_table;
      ```

1. Identifique esta instancia de base de datos de RDS para PostgreSQL como nodo publicador de la siguiente manera.

   ```
   SELECT pglogical.create_node(
       node_name := 'docs_lab_provider',
       dsn := 'host=source-instance.aws-region.rds.amazonaws.com port=5432 dbname=labdb');
    create_node
   -------------
      3410995529
   (1 row)
   ```

1. Añada la tabla que desea replicar al conjunto de replicación predeterminado. Para obtener más información sobre los conjuntos de replicación, consulte [Replication sets](https://github.com/2ndQuadrant/pglogical/tree/REL2_x_STABLE/docs#replication-sets) (Conjuntos de replicación) en la documentación de pglogical. 

   ```
   SELECT pglogical.replication_set_add_table('default', 'docs_lab_table', 'true', NULL, NULL);
    replication_set_add_table
     ---------------------------
     t
     (1 row)
   ```

Se ha completado la configuración del nodo publicador. Ahora puede configurar el nodo suscriptor para recibir las actualizaciones del publicador.

**Para configurar el nodo suscriptor y crear una suscripción para recibir actualizaciones**

En estos pasos se asume que la instancia de base de datos de RDS para PostgreSQL se ha configurado con la extensión `pglogical`. Para obtener más información, consulte [Configuración de la extensión pglogical](Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.md). 

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

   ```
   psql --host=target-instance.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1. En , la instancia de base de datos de RDS para PostgreSQL del suscriptor, cree la misma tabla que existe en el publicador. En este ejemplo, la tabla es `docs_lab_table`. Puede crear la tabla tal y como se indica a continuación.

   ```
   CREATE TABLE docs_lab_table (a int PRIMARY KEY);
   ```

1. Compruebe que esta tabla esté vacía.

   ```
   SELECT count(*) FROM docs_lab_table;
    count
   -------
     0
   (1 row)
   ```

1. Identifique esta instancia de base de datos de RDS para PostgreSQL como nodo suscriptor de la siguiente manera.

   ```
   SELECT pglogical.create_node(
       node_name := 'docs_lab_target',
       dsn := 'host=target-instance.aws-region.rds.amazonaws.com port=5432 sslmode=require dbname=labdb user=postgres password=********');
    create_node
   -------------
      2182738256
   (1 row)
   ```

1. Cree la suscripción. 

   ```
   SELECT pglogical.create_subscription(
      subscription_name := 'docs_lab_subscription',
      provider_dsn := 'host=source-instance.aws-region.rds.amazonaws.com port=5432 sslmode=require dbname=labdb user=postgres password=*******',
      replication_sets := ARRAY['default'],
      synchronize_data := true,
      forward_origins := '{}' );  
    create_subscription
   ---------------------
   1038357190
   (1 row)
   ```

   Al completar este paso, los datos de la tabla del publicador se crean en la tabla del suscriptor. Para comprobar que ha ocurrido esto, utilice la siguiente consulta SQL.

   ```
   SELECT count(*) FROM docs_lab_table;
    count
   -------
     5000
   (1 row)
   ```

A partir de este momento, los cambios realizados en la tabla del publicador se replicarán en la tabla del suscriptor.

# Restablecimiento de la replicación lógica después de una actualización principal
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.recover-replication-after-upgrade"></a>

Para poder realizar una actualización de una versión principal de un instancia de base de datos de RDS para PostgreSQL que se haya configurado como nodo publicador para la replicación lógica, debe eliminar todas las ranuras de replicación, incluso las que no estén activas. Se recomienda desviar temporalmente las transacciones de la base de datos del nodo publicador, eliminar las ranuras de replicación, actualizar la instancia de base de datos de RDS para PostgreSQL y, a continuación, restablecer y reiniciar la replicación.

Las ranuras de replicación se alojan únicamente en el nodo publicador. El nodo suscriptor de RDS para PostgreSQL en un escenario de replicación lógica no tiene espacios que eliminar, pero no se puede actualizar a una versión principal mientras esté designado como nodo suscriptor con una suscripción al publicador. Antes de actualizar el nodo suscriptor de RDS para PostgreSQL, elimine la suscripción y el nodo. Para obtener más información, consulte [Administración de ranuras de replicación lógica para RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.pglogical.handle-slots.md).  

## Determinación de que la replicación lógica se ha interrumpido
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.recover-replication-after-upgrade.identifying-the-issue"></a>

Puede determinar que el proceso de replicación se ha interrumpido consultando el nodo publicador o el nodo suscriptor de la siguiente manera.

**Para comprobar el nodo publicador**
+ Utilice `psql` para conectarse al nodo publicador y, a continuación, consulte la función `pg_replication_slots`. Anote el valor de la columna activa. Normalmente, esto devolverá `t` (true) y mostrará que la replicación está activa. Si la consulta devuelve `f` (false), indica que la replicación en el suscriptor se ha detenido. 

  ```
  SELECT slot_name,plugin,slot_type,active FROM pg_replication_slots;
                      slot_name              |      plugin      | slot_type | active
  -------------------------------------------+------------------+-----------+--------
   pgl_labdb_docs_labcb4fa94_docs_lab3de412c | pglogical_output | logical   | f
  (1 row)
  ```

**Para comprobar el nodo suscriptor**

En el nodo suscriptor, puede comprobar el estado de la replicación de tres maneras diferentes.
+ Revise los registros de PostgreSQL en el nodo suscriptor para encontrar los mensajes de error. El registro identifica el error con mensajes que incluyen el código de salida 1, como se muestra a continuación.

  ```
  2022-07-06 16:17:03 UTC::@:[7361]:LOG: background worker "pglogical apply 16404:2880255011" (PID 14610) exited with exit code 1
  2022-07-06 16:19:44 UTC::@:[7361]:LOG: background worker "pglogical apply 16404:2880255011" (PID 21783) exited with exit code 1
  ```
+ Consulte la función `pg_replication_origin`. Conéctese a la base de datos en el nodo suscriptor mediante `psql` y consulte la función `pg_replication_origin` de la siguiente manera.

  ```
  SELECT * FROM pg_replication_origin;
   roident | roname
  ---------+--------
  (0 rows)
  ```

  Un conjunto de resultados vacío significa que la replicación se ha interrumpido. Debería ver una salida como la siguiente.

  ```
     roident |                       roname
    ---------+----------------------------------------------------
           1 | pgl_labdb_docs_labcb4fa94_docs_lab3de412c
    (1 row)
  ```
+ Consulte la función `pglogical.show_subscription_status` tal y como se muestra en el siguiente ejemplo.

  ```
  SELECT subscription_name,status,slot_name FROM pglogical.show_subscription_status();
       subscription_name | status |              slot_name
  ---====----------------+--------+-------------------------------------
   docs_lab_subscription | down   | pgl_labdb_docs_labcb4fa94_docs_lab3de412c
  (1 row)
  ```

  Este resultado muestra que la replicación se ha interrumpido. Su estado es `down`. Normalmente, la salida muestra el estado como `replicating`.

Si el proceso de replicación lógica se ha interrumpido, puede restablecerla siguiendo estos pasos.

**Para restablecer la replicación lógica entre los nodos publicador y suscriptor**

Para restablecer la replicación, primero debe desconectar el suscriptor del nodo publicador y, a continuación, restablecer la suscripción, tal como se describe en estos pasos. 

1. Conéctese al nodo suscriptor con `psql` de la siguiente manera.

   ```
   psql --host=222222222222.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1. Desactive la suscripción mediante la función `pglogical.alter_subscription_disable`.

   ```
   SELECT pglogical.alter_subscription_disable('docs_lab_subscription',true);
    alter_subscription_disable
   ----------------------------
    t
   (1 row)
   ```

1. Obtenga el identificador del nodo publicador consultando el `pg_replication_origin` de la siguiente manera.

   ```
   SELECT * FROM pg_replication_origin;
    roident |               roname
   ---------+-------------------------------------
          1 | pgl_labdb_docs_labcb4fa94_docs_lab3de412c
   (1 row)
   ```

1. Utilice la respuesta del paso anterior con el comando `pg_replication_origin_create` para asignar el identificador que podrá utilizar la suscripción cuando se restablezca. 

   ```
   SELECT pg_replication_origin_create('pgl_labdb_docs_labcb4fa94_docs_lab3de412c');
     pg_replication_origin_create
   ------------------------------
                               1
   (1 row)
   ```

1. Para activar la suscripción, introduzca su nombre con un estado de `true`, tal como se muestra en el ejemplo siguiente.

   ```
   SELECT pglogical.alter_subscription_enable('docs_lab_subscription',true);
     alter_subscription_enable
   ---------------------------
    t
   (1 row)
   ```

Compruebe el estado del nodo. Su estado debería ser `replicating`, tal y como se muestra en este ejemplo.

```
SELECT subscription_name,status,slot_name
  FROM pglogical.show_subscription_status();
             subscription_name |   status    |              slot_name
-------------------------------+-------------+-------------------------------------
 docs_lab_subscription         | replicating | pgl_labdb_docs_lab98f517b_docs_lab3de412c
(1 row)
```

Compruebe el estado de la ranura de replicación del suscriptor en el nodo publicador. La columna `active` de la ranura debe devolver `t` (true), lo que indica que se ha restablecido la replicación.

```
SELECT slot_name,plugin,slot_type,active
  FROM pg_replication_slots;
                    slot_name              |      plugin      | slot_type | active
-------------------------------------------+------------------+-----------+--------
 pgl_labdb_docs_lab98f517b_docs_lab3de412c | pglogical_output | logical   | t
(1 row)
```

# Administración de ranuras de replicación lógica para RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.handle-slots"></a>

Para poder realizar una actualización de una versión principal en instancia de base de datos de RDS para PostgreSQL que se utilice como nodo publicador en un escenario de replicación lógica, debe eliminar todas las ranuras de replicación de la instancia. El proceso de comprobación previa de la actualización de la versión principal le indica que la actualización no puede continuar hasta que se eliminen las ranuras disponibles.

Para eliminar ranuras de su instancia de base de datos de RDS para PostgreSQL, primero elimine la suscripción y, a continuación, elimine la ranura. 

Para identificar las ranuras de replicación que se crearon con la extensión `pglogical`, inicie sesión en cada base de datos y obtenga el nombre de los nodos. Al consultar el nodo suscriptor, aparecen los nodos publicador y suscriptor en el resultado, tal como se muestra en este ejemplo. 

```
SELECT * FROM pglogical.node;
node_id   |     node_name
------------+-------------------
 2182738256 | docs_lab_target
 3410995529 | docs_lab_provider
(2 rows)
```

Puede obtener los detalles de la suscripción con la siguiente consulta.

```
SELECT sub_name,sub_slot_name,sub_target
  FROM pglogical.subscription;
 sub_name |         sub_slot_name          | sub_target
----------+--------------------------------+------------
  docs_lab_subscription     | pgl_labdb_docs_labcb4fa94_docs_lab3de412c | 2182738256
(1 row)
```

Ahora puede eliminar la suscripción de la siguiente manera.

```
SELECT pglogical.drop_subscription(subscription_name := 'docs_lab_subscription');
 drop_subscription
-------------------
                 1
(1 row)
```

Después de eliminar la suscripción, puede eliminar el nodo.

```
SELECT pglogical.drop_node(node_name := 'docs-lab-subscriber');
 drop_node
-----------
 t
(1 row)
```

Puede comprobar que el nodo ya no existe de la siguiente manera.

```
SELECT * FROM pglogical.node;
 node_id | node_name
---------+-----------
(0 rows)
```

# Referencia de parámetros para la extensión pglogical
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.reference"></a>

En la tabla verá los parámetros asociados a la extensión `pglogical`. Parámetros como `pglogical.conflict_log_level` y `pglogical.conflict_resolution` se utilizan para gestionar los conflictos de actualización. Pueden surgir conflictos cuando los cambios se realizan localmente en las mismas tablas que están suscritas a los cambios del publicador. Los conflictos también pueden producirse en varios escenarios, como la replicación bidireccional o cuando varios suscriptores replican desde el mismo publicador. Para obtener más información, consulte [PostgreSQL bi-directional replication using pglogical](https://aws.amazon.com/blogs/database/postgresql-bi-directional-replication-using-pglogical/) (Replicación bidireccional de PostgreSQL mediante pglogical). 


| Parámetro | Descripción | 
| --- | --- | 
| pglogical.batch\$1inserts | Inserciones por lotes si es posible. No establecido de manera predeterminada. Se cambia a 1 para activarlo y a 0 para desactivarlo. | 
| pglogical.conflict\$1log\$1level | Establece el nivel de registro utilizado para registrar los conflictos resueltos. Los valores permitidos son debug5, debug4, debug3, debug2, debug1, info, notice, warning, error, log, fatal y panic. | 
| pglogical.conflict\$1resolution | Establece el método que se utilizará para resolver conflictos si es posible resolverlos. Los valores de cadena admitidos son error, apply\$1remote, keep\$1local, last\$1update\$1wins y first\$1update\$1wins. | 
| pglogical.extra\$1connection\$1options | Opciones de conexión a añadir a todas las conexiones de los nodos pares. | 
| pglogical.synchronous\$1commit | valor de confirmación sincrónica específico de pglogical | 
| pglogical.use\$1spi | Utilice la SPI (interfaz de programación de servidores) en lugar de la API de nivel inferior para aplicar los cambios. Se establece en 1 para activarlo y en 0 para desactivarlo. Para obtener más información acerca de la SPI, consulte [Server Programming Interface](https://www.postgresql.org/docs/current/spi.html) (Interfaz de programación de servidores) en la documentación de PostgreSQL.  | 

# Uso de pgactive para admitir la replicación activa-activa
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive"></a>

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, versiones 17.0 y todas las posteriores
+ 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](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-conflicts.md)

**Topics**
+ [Limitaciones de la extensión pgactive](#Appendix.PostgreSQL.CommonDBATasks.pgactive.requirements-limitations)
+ [Inicialización de la capacidad de la extensión pgactive](Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.md)
+ [Configuración de la replicación activa-activa para las instancias de base de datos de RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.pgactive.setup-replication.md)
+ [Medición del retraso de réplica entre miembros de pgactive](Appendix.PostgreSQL.CommonDBATasks.pgactive.replicationlag.md)
+ [Configuración de los ajustes de parámetros para la extensión pgactive](Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.md)
+ [Comprensión de conflictos activo-activo](Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.replication.md)
+ [Descripción del esquema de pgactive](Appendix.PostgreSQL.CommonDBATasks.pgactive.schema.md)
+ [Referencia de funciones de pgactive](pgactive-functions-reference.md)
+ [Gestión de conflictos en la replicación activa-activa](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-conflicts.md)
+ [Gestión de secuencias en la replicación activa-activa](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-sequences.md)

## Limitaciones de la extensión pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.requirements-limitations"></a>
+ 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](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-sequences.md).
+ 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.

# Inicialización de la capacidad de la extensión pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup"></a>

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 Consola de administración de AWS 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](USER_WorkingWithParamGroups.md).

## Consola
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.CON"></a>

**Para inicializar la capacidad de la extensión pgactive**

1. Inicie sesión en la Consola de administración de AWS y abra la consola de Amazon RDS en [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

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

1. 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**. 

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

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

1. Seleccione **Save changes (Guardar cambios)**.

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

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

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

1. 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=postgres --password=PASSWORD --dbname=postgres
   ```

1. 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
   ```

## AWS CLI
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.CLI"></a>

**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](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html) 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
   ```

1. 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
   ```

1. 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=PASSWORD --dbname=postgres
   ```

1. 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
   ```

# Configuración de la replicación activa-activa para las instancias de base de datos de RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.setup-replication"></a>

En el siguiente procedimiento, se muestra cómo iniciar la replicación activo-activo entre dos instancias de base de datos de RDS para PostgreSQL donde `pgactive` esté disponible. 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](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html).

**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 habilitado con la extensión `pgactive`. Para obtener más información, consulte [Inicialización de la capacidad de la extensión pgactive](Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.md). 

**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=postgres --password=PASSWORD --dbname=postgres
   ```

1. Cree una base de datos en la instancia de RDS para PostgreSQL mediante el siguiente comando:

   ```
   postgres=> CREATE DATABASE app;
   ```

1. Cambie la conexión a la nueva base de datos mediante el siguiente comando:

   ```
   \c app
   ```

1. 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);
      ```

   1. 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');
      ```

   1. Compruebe que los datos existen en la tabla mediante la siguiente instrucción SQL.

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

1. Cree la extensión `pgactive` en la base de datos existente.

   ```
   app=> CREATE EXTENSION pgactive;
   ```

1. Para crear e inicializar el grupo pgactive use los siguientes comandos:

   ```
   app=>
   -- connection info for endpoint1
   CREATE SERVER pgactive_server_endpoint1
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint1>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint1
       OPTIONS (user 'postgres', password '<password>');
         -- connection info for endpoint2
   CREATE SERVER pgactive_server_endpoint2
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint2>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint2
       OPTIONS (user 'postgres', password '<password>');
   ```

   Ahora puede inicializar el grupo de replicación y agregar esta primera instancia:

   ```
   SELECT pgactive.pgactive_create_group(
       node_name := 'endpoint1-app',
       node_dsn := 'user_mapping=postgres pgactive_foreign_server=pgactive_server_endpoint1'
   
   );
   ```

   Utilice los siguientes comandos como método alternativo, aunque menos seguro, para crear e inicializar el grupo pgactive:

   ```
   app=> SELECT pgactive.pgactive_create_group(
       node_name := 'node1-app',
       node_dsn := 'dbname=app host=firstinstance.111122223333.aws-region.rds.amazonaws.com user=postgres 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`.

1. 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](Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.md). 

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=postgres --password=PASSWORD --dbname=postgres
   ```

1. 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;
   ```

1. Cambie la conexión a la nueva base de datos mediante el siguiente comando:

   ```
   \c app
   ```

1. Cree la extensión `pgactive` en la base de datos existente.

   ```
   app=> CREATE EXTENSION pgactive;
   ```

1. Una la segunda instancia de base de datos de RDS para PostgreSQL al grupo `pgactive` de una forma más segura mediante los siguientes comandos:

   ```
   -- connection info for endpoint1
   CREATE SERVER pgactive_server_endpoint1
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint1>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint1
       OPTIONS (user 'postgres', password '<password>');
   
   -- connection info for endpoint2
   CREATE SERVER pgactive_server_endpoint2
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint2>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint2
       OPTIONS (user 'postgres', password '<password>');
   ```

   ```
   SELECT pgactive.pgactive_join_group(
       node_name := 'endpoint2-app',
       node_dsn := 'user_mapping=postgres pgactive_foreign_server=pgactive_server_endpoint2',
       join_using_dsn := 'user_mapping=postgres pgactive_foreign_server=pgactive_server_endpoint1'
   );
   ```

   Utilice los siguientes comandos como método alternativo, aunque menos seguro, para unir la segunda instancia de base de datos de RDS para PostgreSQL al grupo `pgactive`

   ```
   app=> SELECT pgactive.pgactive_join_group(
   node_name := 'node2-app',
   node_dsn := 'dbname=app host=secondinstance.111122223333.aws-region.rds.amazonaws.com user=postgres 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`.

1. 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.

1. 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
   ```

1. Ejecute el siguiente comando para insertar nuevos valores:

   ```
   app=> INSERT INTO inventory.products (id, product_name) VALUES (4, 'lotion');
   ```

1. 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']);
   ```

1. 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);
   ```

1. Suelte la extensión con el siguiente comando:

   ```
   app=> DROP EXTENSION pgactive;
   ```

# Medición del retraso de réplica entre miembros de pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.replicationlag"></a>

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.

```
    
app=> SELECT * FROM pgactive.pgactive_get_replication_lag_info();
│-[ RECORD 1 ]--------+---------------------------------------------
│node_name            | node2-app
│node_sysid           | 7481018224801653637
│application_name     | pgactive:7481018224801653637:send
│slot_name            | pgactive_16385_7481018224801653637_0_16385__
│active               | t
│active_pid           | 783486
│pending_wal_decoding | 0
│pending_wal_to_apply | 0
│restart_lsn          | 0/2108150
│confirmed_flush_lsn  | 0/2154690
│sent_lsn             | 0/2154690
│write_lsn            | 0/2154690
│flush_lsn            | 0/2154690
│replay_lsn           | 0/2154690
│-[ RECORD 2 ]--------+---------------------------------------------
│node_name            | node1-app
│node_sysid           | 7481018033434600853
│application_name     | pgactive:7481018033434600853:send
│slot_name            | pgactive_16385_7481018033434600853_0_16385__
│active               | t
│active_pid           | 783488
│pending_wal_decoding | 0
│pending_wal_to_apply | 0
│restart_lsn          | 0/20F5AD0
│confirmed_flush_lsn  | 0/214EF68
│sent_lsn             | 0/214EF68
│write_lsn            | 0/214EF68
│flush_lsn            | 0/214EF68
│replay_lsn           | 0/214EF68
```

Supervise los siguientes diagnósticos como mínimo:

active  
Configure alertas cuando el valor activo sea falso, lo que indica que la ranura no está en uso actualmente (la instancia del suscriptor se ha desconectado del publicador).

pending\$1wal\$1decoding  
En la replicación lógica de PostgreSQL, los archivos WAL se almacenan en formato binario. El publicador debe decodificar estos cambios de WAL y convertirlos en cambios lógicos (como operaciones de inserción, actualización o eliminación).  
La métrica pending\$1wal\$1decoding muestra el número de archivos WAL que esperan que los descodifique el publicador.  
Este número puede aumentar debido a estos factores:  
+ Cuando el suscriptor no esté conectado, el estado activo será falso y pending\$1wal\$1decoding aumentará
+ La ranura está activa, pero el publicador no puede mantenerse al día con el volumen de cambios de WAL

pending\$1wal\$1to\$1apply  
La métrica pending\$1wal\$1apply indica el número de archivos WAL que esperan aplicarse en el suscriptor.  
Varios factores pueden impedir que el suscriptor aplique los cambios y potencialmente causar un escenario de disco lleno:  
+ Diferencias de esquema: por ejemplo, cuando hay cambios en el flujo de WAL de una tabla llamada ejemplo, pero esa tabla no existe en el suscriptor
+ Se actualizaron los valores en las columnas de la clave principal
+ Los índices únicos secundarios pueden provocar divergencias en los datos

# Configuración de los ajustes de parámetros para la extensión pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters"></a>

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

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

Puede configurar la extensión `pgactive` mediante varios parámetros. Estos parámetros se pueden configurar mediante Consola de administración de AWS o la interfaz de la CLI de AWS.

## Parámetros de extensión de pgactive principales
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.mainparams"></a>

La siguiente tabla proporciona una referencia para los principales parámetros de la extensión `pgactive`:


| Parámetro | Unidad | Predeterminado | Descripción | 
| --- | --- | --- | --- | 
| pgactive.conflict\$1logging\$1include\$1tuples | `boolean` | –  | Registra la información completa de la tupla de la extensión `pgactive`.  Es necesario reiniciar el servidor para que se apliquen los cambios.  | 
| pgactive.log\$1conflicts\$1to\$1table | `boolean` | –  | Determina si la extensión `pgactive` registra los conflictos detectados en la tabla `pgactive.pgactive_conflict_history`. Para obtener más información, consulte registro de conflictos.  Es necesario reiniciar el servidor para que se apliquen los cambios.  | 
| pgactive.log\$1conflicts\$1to\$1logfile | `boolean` | –  | Determina si la extensión `pgactive` registra los conflictos detectados en el archivo de registro de PostgreSQL. Para obtener más información, consulte registro de conflictos.  Es necesario reiniciar el servidor para que se apliquen los cambios.  | 
| pgactive.synchronous\$1commit | `boolean` | apagar | Determina el comportamiento de confirmación de los trabajadores de aplicación de pgactive. Cuando está desactivado, los trabajadores de aplicación realizan confirmaciones asíncronas, lo que mejora el rendimiento de PostgreSQL durante las operaciones de aplicación, pero retrasa las confirmaciones de reproducción hacia el nodo ascendente. Establecerlo en `off` siempre es seguro y no provocará pérdidas ni omisiones de transacciones. Esta configuración solo afecta al momento de las descargas a disco en el nodo descendente y cuándo se envían las confirmaciones al nodo ascendente. El sistema retrasa el envío de las confirmaciones de vaciado de reproducción hasta que las confirmaciones se vuelcan al disco mediante operaciones no relacionadas, como puntos de control o trabajos periódicos. Sin embargo, si el nodo ascendente tiene el nodo descendente en `synchronous_standby_names`, establecerlo en `off` hace que las confirmaciones sincrónicas en el nodo ascendente tarden más en informar del éxito al cliente. En este caso, establezca el parámetro en `on`.  Incluso cuando este parámetro se establece en `on` con nodos en `synchronous_standby_names`, pueden producirse conflictos de replicación en las configuraciones activo-activo. Esto se debe a que el sistema carece de bloqueo entre nodos y de gestión global de instantáneas, lo que permite que las transacciones concurrentes en distintos nodos modifiquen la misma tupla. Además, las transacciones solo comienzan a replicarse después de confirmarse en el nodo ascendente. La habilitación de la confirmación sincrónica no transforma la extensión pgactive en un sistema siempre coherente.  | 
| pgactive.temp\$1dump\$1directory | `string` | – | Define la ruta de almacenamiento temporal necesaria para las operaciones de clonación de bases de datos durante la configuración inicial. En este directorio debe poder escribir el usuario de postgres y debe tener suficiente espacio de almacenamiento para contener un volcado completo de la base de datos. El sistema utiliza esta ubicación solo durante la configuración inicial de la base de datos con operaciones de copia lógica. Este parámetro no lo usa `pgactive_init_copy command`. | 
| pgactive.max\$1ddl\$1lock\$1delay | `milliseconds` | `-1` | Especifica el tiempo máximo de espera para el bloqueo de DDL antes de interrumpir por la fuerza las transacciones de escritura simultáneas. El valor predeterminado es `-1`, que adopta el valor establecido en `max_standby_streaming_delay`. Este parámetro acepta unidades de tiempo. Por ejemplo, puede configurarlo en 10 s para 10 segundos. Durante este periodo de espera, el sistema intenta adquirir bloqueos de DDL mientras espera a que las transacciones de escritura en curso se confirmen o se reviertan. Para obtener más información, consulte Bloqueos de DDL. | 
| pgactive.ddl\$1lock\$1timeout | `milliseconds` | `-1` | Especifica cuánto tiempo espera un intento de bloqueo de DDL para obtener el bloqueo. El valor predeterminado es `-1`, que utiliza el valor especificado en lock\$1timeout. Puede configurar este parámetro mediante unidades de tiempo como 10 s para 10 segundos. Este temporizador solo controla el periodo de espera para obtener un bloqueo de DDL. Una vez que el sistema obtiene el bloqueo e inicia la operación de DDL, el temporizador se detiene. Este parámetro no limita la duración total que puede mantenerse un bloqueo de DDL ni el tiempo total de la operación de DDL. Para controlar la duración total de la operación, utilice `statement_timeout` en su lugar. Para obtener más información, consulte Bloqueos de DDL. | 
| pgactive.debug\$1trace\$1ddl\$1locks\$1level | `boolean` | –  | Invalida el nivel de registro de depuración predeterminado para las operaciones de bloqueo de DDL en la extensión `pgactive`. Cuando se configura, esta configuración hace que los mensajes relacionados con el bloqueo de DDL se emitan en el nivel de depuración LOG en lugar de en su nivel predeterminado. Utilice este parámetro para supervisar la actividad de bloqueo de DDL sin activar los niveles de registro detallados `DEBUG1` o `DEBUG2` en todo el servidor.  Niveles de registro disponibles, en orden creciente de detalle: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Para obtener más información acerca de las opciones de supervisión, consulte Supervisión de bloqueos de DDL globales.  Los cambios en esta configuración surten efecto al volver a cargar la configuración. No es necesario reiniciar el servidor.   | 

## Parámetros de extensión de pgactive adicionales
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.addparams"></a>

La siguiente tabla presenta las opciones de configuración interna y las que se utilizan con menos frecuencia disponibles para la extensión `pgactive`.


| Parámetro | Unidad | Predeterminado | Descripción | 
| --- | --- | --- | --- | 
| pgactive.debug\$1apply\$1delay | `integer` | – |  Establece un retraso de aplicación (en milisegundos) para las conexiones configuradas que no tienen un retraso de aplicación explícito en su entrada `pgactive.pgactive_connections`. Este retraso se establece durante la creación o la unión del nodo, y pgactive no reproducirá una transacción en los nodos del mismo nivel hasta que hayan transcurrido al menos el número especificado de milisegundos desde que se confirmó. Se utiliza principalmente para simular redes de alta latencia en entornos de prueba para facilitar la creación de conflictos. Por ejemplo, con un retraso de 500 ms en los nodos A y B, dispone de al menos 500 ms para realizar una inserción conflictiva en el nodo B tras insertar un valor en el nodo A.  Requiere una recarga del servidor o un reinicio de los trabajadores de aplicación para que surta efecto.  | 
| pgactive.connectability\$1check\$1duration | `integer` | –  | Especifica la duración (en segundos) durante la cual un trabajador de base de datos intenta establecer conexiones durante los intentos erróneos. El trabajador realiza un intento de conexión por segundo hasta que tiene éxito o alcanza este valor de tiempo de espera. Esta configuración resulta útil cuando el motor de base de datos se inicia antes de que el trabajador esté preparado para establecer conexiones. | 
| pgactive.skip\$1ddl\$1replication | `boolean` | `on` | Controla cómo se replican o gestionan los cambios de DDL en Amazon RDS con `pgactive` habilitado. Cuando se establece en `on`, el nodo procesa los cambios de DDL como un nodo no pgactive. Los siguientes requisitos se aplican al trabajar con este parámetro: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Puede modificar este parámetro de dos formas con privilegios de superusuario: de forma global o local (nivel de sesión).  Si se cambia este parámetro de forma incorrecta, se pueden interrumpir las configuraciones de replicación.  | 
| pgactive.do\$1not\$1replicate | `boolean` | – | Este parámetro es solo para uso interno. Cuando se establece este parámetro en una transacción, los cambios no se replican en otros nodos del clúster de base de datos.   Si se cambia este parámetro de forma incorrecta, se pueden interrumpir las configuraciones de replicación.  | 
| pgactive.discard\$1mismatched\$1row\$1attributes | `boolean` | –  | Este parámetro está destinado solo a uso especializado. Recomendamos usar este parámetro solo para solucionar problemas de replicación específicos. Utilice este parámetro cuando: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Esta configuración invalida el siguiente mensaje de error y permite que surja una divergencia de datos para permitir que la replicación continúe: `cannot right-pad mismatched attributes; attno %u is missing in local table and remote row has non-null, non-dropped value for this attribute`  Si se cambia este parámetro de forma incorrecta, se pueden interrumpir las configuraciones de replicación.   | 
| pgactive.debug\$1trace\$1replay | `boolean` | – | Cuando se establece en `on`, emite un mensaje de registro para cada acción remota que se aplique posteriormente al proceso de los trabajadores. Los registros incluyen: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Los registros también capturan los comandos de DDL en cola y las tablas descartadas.para> De forma predeterminada, los registros no incluyen el contenido de los campos de fila. Para incluir valores de fila en los registros, debe volver a compilarlos con los siguientes indicadores habilitados: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html)  La habilitación de esta configuración de registro puede afectar al rendimiento. Recomendamos habilitarla solo cuando sea necesario para solucionar problemas. Los cambios en esta configuración surten efecto al volver a cargar la configuración. No es necesario reiniciar el servidor.   | 
| pgactive.extra\$1apply\$1connection\$1options |  | – | Puede configurar los parámetros de conexión para todas las conexiones de nodos del mismo nivel con los nodos de pgactive. Estos parámetros controlan ajustes como keepalive y los modos SSL. De forma predeterminada, pgactive utiliza los siguientes parámetros de conexión: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Para invalidar los parámetros predeterminados, utilice el siguiente comando similar: pgactive.extra\$1apply\$1connection\$1options = 'keepalives=0' Las cadenas de conexión de los nodos individuales tienen prioridad sobre estas configuraciones y sobre las opciones de conexión integradas de pgactive. Para obtener más información acerca de los formatos de cadenas de conexión, consulte [cadenas de conexión libpq](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING). Recomendamos mantener habilitada la configuración predeterminada de keepalive. Desactive keepalive solo si tiene problemas al realizar grandes transacciones a través de redes poco fiables.   Recomendamos mantener habilitada la configuración predeterminada de keepalive. Desactive keepalive solo si tiene problemas al realizar grandes transacciones a través de redes poco fiables. Los cambios en esta configuración surten efecto al volver a cargar la configuración. No es necesario reiniciar el servidor.  | 
| pgactive.init\$1node\$1parallel\$1jobs (int) |  | – | Especifica el número de trabajos paralelos que `pg_dump` y `pg_restore` pueden utilizar durante las uniones de nodos lógicos con la función `pgactive.pgactive_join_group`. Los cambios en esta configuración surten efecto al volver a cargar la configuración. No es necesario reiniciar el servidor. | 
| pgactive.max\$1nodes | `int` | 4 |  Especifica el número máximo de nodos permitidos en un grupo de extensiones de pgactive. El valor predeterminado es 4 nodos. Debe tener en cuenta lo siguiente al configurar el valor de este parámetro: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Puede configurar este parámetro de dos maneras: en el archivo de configuración, mediante el comando `ALTER SYSTEM SET` El valor predeterminado de este parámetro es `4`, lo que significa que puede haber un máximo de 4 nodos permitidos en el grupo de extensiones de `pgactive` en cualquier momento.  El cambio surtirá efecto después de reiniciar el servidor.  | 
| pgactive.permit\$1node\$1identifier\$1getter\$1function\$1creation | `boolean` | – | Este parámetro está destinado solo a uso interno. Cuando está habilitada, la extensión `pgactive` permite la creación de la función de obtención del identificador de nodo de pgactive. | 

# Comprensión de conflictos activo-activo
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.replication"></a>

Cuando se utiliza pgactive en el modo activo-activo, escribir en las mismas tablas desde varios nodos puede crear conflictos de datos. Aunque algunos sistemas de agrupación en clústeres utilizan bloqueos distribuidos para evitar el acceso simultáneo, pgactive adopta un enfoque optimista que se adapta mejor a las aplicaciones distribuidas geográficamente.

Algunos sistemas de agrupación en clústeres de bases de datos impiden el acceso simultáneo a los datos mediante el uso de bloqueos distribuidos. Aunque este enfoque funciona cuando los servidores están muy cerca, no admite aplicaciones distribuidas geográficamente porque requiere una latencia extremadamente baja para lograr un buen rendimiento. En lugar de utilizar bloqueos distribuidos (un enfoque pesimista), la extensión pgactive utiliza un enfoque optimista. Esto significa que:
+ Ayuda a evitar conflictos cuando es posible.
+ Permite que se produzcan determinados tipos de conflictos.
+ Proporciona resolución de conflictos cuando se producen conflictos.

Este enfoque le proporciona más flexibilidad a la hora de crear aplicaciones distribuidas.

## Cómo se producen los conflictos
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.howconflicts"></a>

Los conflictos entre nodos surgen de secuencias de eventos que no podrían ocurrir si todas las transacciones implicadas se produjeran simultáneamente en el mismo nodo. Como los nodos solo intercambian cambios una vez confirmadas las transacciones, cada transacción es válida individualmente en el nodo en el que se ha confirmado, pero no lo sería si se ejecutara en otro nodo que haya realizado otras tareas mientras tanto. Dado que la aplicación de pgactive básicamente reproduce la transacción en los demás nodos, la operación de reproducción puede producir un error si hay un conflicto entre una transacción que se está aplicando y una transacción que se ha confirmado en el nodo receptor.

 La razón por la que la mayoría de los conflictos no se producen cuando todas las transacciones se ejecutan en un único nodo es que PostgreSQL cuenta con mecanismos de comunicación entre transacciones para evitarlos, entre los que se incluyen:
+ Índices UNIQUE
+ SEQUENCE
+ Bloqueo de filas y relaciones
+ Seguimiento de dependencias SERIALIZABLE

Todos estos mecanismos son formas de comunicarse entre transacciones para evitar problemas de concurrencia no deseados

pgactive logra una baja latencia y maneja bien las particiones de la red porque no utiliza un administrador de transacciones distribuido o un administrador de bloqueos. Sin embargo, esto significa que las transacciones en diferentes nodos se ejecutan completamente aisladas unas de otras. Aunque el aislamiento suele mejorar la coherencia de la base de datos, en este caso es necesario reducir el aislamiento para evitar conflictos.

## Tipos de conflictos
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflicttypes"></a>

Los conflictos que se pueden producir son:

**Topics**
+ [Conflictos de PRIMARY KEY o UNIQUE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict1)
+ [Conflictos INSERT/INSERT](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict2)
+ [INSERT que infringen múltiples restricciones UNIQUE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict3)
+ [Conflictos UPDATE/UPDATE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict4)
+ [Conflictos UPDATE en la PRIMARY KEY](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict5)
+ [UPDATE que infringen varias restricciones UNIQUE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict6)
+ [Conflictos UPDATE/DELETE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict7)
+ [Conflictos INSERT/UPDATE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict8)
+ [Conflictos DELETE/DELETE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict9)
+ [Conflictos de restricciones de clave externa](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict10)
+ [Conflictos de restricciones de exclusión](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict11)
+ [Conflictos de datos globales](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict12)
+ [Conflictos de bloqueo y anulaciones de bloqueo](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict13)
+ [Conflictos divergentes](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14)

### Conflictos de PRIMARY KEY o UNIQUE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict1"></a>

Los conflictos de filas se producen cuando varias operaciones intentan modificar la misma clave de fila de formas que no son posibles en un solo nodo. Estos conflictos representan el tipo más común de conflictos de datos.

pgactive resuelve los conflictos detectados mediante el manejo de last-update-wins o el gestor de conflictos personalizado.

Los conflictos de filas incluyen:
+ INSERT frente a INSERT
+ INSERT frente a UPDATE
+ UPDATE frente a DELETE
+ INSERT frente a DELETE
+ DELETE frente a DELETE
+ INSERT frente a DELETE

### Conflictos INSERT/INSERT
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict2"></a>

El conflicto más común se produce cuando los INSERT en dos nodos diferentes crean una tupla con los mismos valores de PRIMARY KEY (o valores de restricción UNIQUE idénticos cuando no existe ninguna PRIMARY KEY).

pgactivelink resuelve los conflictos de INSERT utilizando la marca temporal del host de origen para conservar la tupla más reciente. Puede invalidar este comportamiento predeterminado con el controlador de conflictos personalizado. Aunque este proceso no requiere ninguna acción especial del administrador, tenga en cuenta que pgactivelink descarta una de las operaciones INSERT en todos los nodos. No se produce una fusión automática de datos a menos que el controlador personalizado la implemente.

pgactivelink solo puede resolver conflictos que impliquen una única violación de restricción. Si un INSERT infringe varias restricciones UNIQUE, debe implementar estrategias adicionales de resolución de conflictos.

### INSERT que infringen múltiples restricciones UNIQUE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict3"></a>

Un conflicto INSERT/INSERT puede infringir varias restricciones UNIQUE, incluida la PRIMARY KEY. pgactivelink solo puede gestionar conflictos que impliquen una única restricción UNIQUE. Cuando los conflictos infringen varias restricciones UNIQUE, el trabajador de aplicación produce un error y devuelve el siguiente error:

`multiple unique constraints violated by remotely INSERTed tuple.`

En versiones anteriores, esta situación generaba un error de "conflicto de unicidad divergente" en su lugar. 

Para resolver estos conflictos, debe tomar medidas manuales. O bien DELETE las tuplas locales en conflicto o UPDATE las mismas para eliminar los conflictos con la nueva tupla remota. Tenga en cuenta que puede que tenga que abordar varias tuplas conflictivas. Actualmente, pgactivelink no proporciona ninguna funcionalidad integrada para ignorar, descartar o fusionar las tuplas que infringen múltiples restricciones únicas.

**nota**  
Para obtener más información, consulte UPDATE que infringen varias restricciones UNIQUE.

### Conflictos UPDATE/UPDATE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict4"></a>

Este conflicto se produce cuando dos nodos modifican simultáneamente la misma tupla sin cambiar su PRIMARY KEY. pgactivelink resuelve estos conflictos mediante la lógica last-update-wins o el controlador de conflictos personalizado, si está definido. Una PRIMARY KEY es esencial para la coincidencia de tuplas y la resolución de conflictos. En el caso de las tablas sin una PRIMARY KEY, pgactivelink rechaza las operaciones UPDATE con el siguiente error:

`Cannot run UPDATE or DELETE on table (tablename) because it does not have a primary key.`

### Conflictos UPDATE en la PRIMARY KEY
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict5"></a>

Pgactive tiene limitaciones a la hora de gestionar las actualizaciones de PRIMARY KEY. Aunque puede realizar la operación UPDATE en una PRIMARY KEY, pgactive no puede resolver automáticamente los conflictos utilizando la lógica last-update-wins para estas operaciones. Debe asegurarse de que las actualizaciones de la PRIMARY KEY no entren en conflicto con los valores existentes. Si se producen conflictos durante las actualizaciones de PRIMARY KEY, se convierten en conflictos divergentes que requieren su intervención manual. Para obtener más información acerca de cómo manejar estas situaciones, consulte [Conflictos divergentes](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14).

### UPDATE que infringen varias restricciones UNIQUE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict6"></a>

pgactivelink no puede aplicar la resolución de conflictos last-update-wins cuando una UPDATE entrante infringe varias restricciones UNIQUE o valores de PRIMARY KEY. Este comportamiento es similar a las operaciones INSERT con múltiples infracciones de restricciones. Estas situaciones crean conflictos divergentes que requieren su intervención manual. Para obtener más información, consulte [Conflictos divergentes](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14).

### Conflictos UPDATE/DELETE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict7"></a>

Estos conflictos se producen cuando un nodo realiza una UPDATE en una fila mientras que otro nodo la DELETE simultáneamente. En este caso, se produce un conflicto UPDATE/DELETE durante la reproducción. La solución consiste en descartar cualquier UPDATE que llegue después de una DELETE, a menos que el gestor de conflictos personalizado especifique lo contrario.

pgactivelink requiere una PRIMARY KEY para hacer coincidir las tuplas y resolver los conflictos. Para las tablas sin una PRIMARY KEY, rechaza las operaciones DELETE con el siguiente error:

`Cannot run UPDATE or DELETE on table (tablename) because it does not have a primary key.`

**nota**  
pgactivelink no puede distinguir entre los conflictos de UPDATE/DELETE e INSERT/UPDATE. En ambos casos, una UPDATE afecta a una fila que no existe. Debido a la replicación asíncrona y a la falta de orden de reproducción entre los nodos, pgactivelink no puede determinar si la UPDATE es para una fila nueva (aún no se ha recibido INSERT) o para una fila eliminada. En ambos casos, pgactivelink descarta la UPDATE.

### Conflictos INSERT/UPDATE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict8"></a>

Este conflicto se puede producir en entornos de varios nodos. Ocurre cuando un nodo INSERT una fila, un segundo nodo la UPDATE y un tercer nodo recibe la UPDATE antes que el INSERT original. De forma predeterminada, pgactivelink resuelve estos conflictos descartando la UPDATE, a menos que el desencadenador de conflictos personalizado especifique lo contrario. Tenga en cuenta que este método de resolución puede provocar incoherencias en los datos entre los nodos. Para obtener más información acerca de escenarios similares y su manejo, consulte [Conflictos UPDATE/DELETE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict7).

### Conflictos DELETE/DELETE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict9"></a>

Este conflicto se produce cuando dos nodos diferentes eliminan simultáneamente la misma tupla. pgactivelink considera que estos conflictos son inofensivos porque ambas operaciones DELETE tienen el mismo resultado final. En este escenario, pgactivelink ignora de forma segura una de las operaciones DELETE sin afectar a la coherencia de datos. 

### Conflictos de restricciones de clave externa
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict10"></a>

Las restricciones de FOREIGN KEY pueden provocar conflictos al aplicar transacciones remotas a los datos locales existentes. Estos conflictos suelen producirse cuando las transacciones se aplican en una secuencia diferente a su orden lógico en los nodos de origen.

De forma predeterminada, pgactive aplica los cambios con session\$1replication\$1role como `replica`, lo que evita las comprobaciones de claves externas durante la replicación. En las configuraciones activo-activo, esto puede provocar infracciones de claves externas. La mayoría de las infracciones son temporales y se resuelven una vez que la replicación se pone al día. Sin embargo, pueden producirse claves externas huérfanas porque pgactive no admite el bloqueo de filas entre nodos.

Este comportamiento es inherente a los sistemas activo-activo asíncronos tolerantes a las particiones. Por ejemplo, el nodo A puede insertar una nueva fila secundaria mientras que el nodo B elimina simultáneamente su fila principal. El sistema no puede impedir este tipo de modificación concurrente entre nodos.

Para minimizar los conflictos de claves externas, recomendamos lo siguiente:
+ Limitar las relaciones de claves externas a entidades estrechamente relacionadas.
+ Modificar las entidades relacionadas desde un solo nodo cuando sea posible.
+ Elegir entidades que rara vez requieran modificación.
+ Implementar un control de concurrencia en el nivel de aplicación para las modificaciones.

### Conflictos de restricciones de exclusión
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict11"></a>

 pgactive link no admite restricciones de exclusión y restringe su creación.

**nota**  
Si convierte una base de datos independiente existente en una base de datos de pgactivelink, elimine manualmente todas las restricciones de exclusión.

En un sistema asíncrono distribuido, no es posible garantizar que ningún conjunto de filas infrinja la restricción. Esto se debe a que todas las transacciones en los distintos nodos están completamente aisladas. Las restricciones de exclusión pueden provocar bloqueos de reproducción, donde la reproducción no puede avanzar de un nodo a otro debido a infracciones de las restricciones de exclusión.

Si obliga a pgactive Link a crear una restricción de exclusión o si no elimina las existentes al convertir una base de datos independiente en pgactive Link, es probable que la replicación se interrumpa. Para restaurar el progreso de la replicación, elimine o modifique las tuplas locales que entren en conflicto con una tupla remota entrante para poder aplicar la transacción remota.

### Conflictos de datos globales
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict12"></a>

Cuando se utiliza pgactivelink, se pueden producir conflictos cuando los nodos tienen diferentes datos globales de todo el sistema PostgreSQL, como los roles. Estos conflictos pueden provocar que las operaciones (principalmente DDL) se ejecuten correctamente en un nodo, pero que no se apliquen a otros nodos.

Si un usuario existe en un nodo pero no en otro, pueden producirse problemas de replicación:
+ Node1 tiene un nombre de usuario `fred`, pero este usuario no existe en Node2
+ Cuando `fred` crea una tabla en Node1, la tabla se replica con `fred` como el propietario
+ Cuando este comando de DDL se aplica al Node2, se produce un error porque el usuario `fred` no existe
+ Este error genera un ERROR en los registros de PostgreSQL en Node2 e incrementa el contador `pgactive.pgactive_stats.nr_rollbacks`

**Solución:** cree el usuario `fred` en Node2. El usuario no necesita permisos idénticos, sino que debe existir en ambos nodos.

Si existe una tabla en un nodo pero no en otro, las operaciones de modificación de datos producirán un error:
+ Node1 tiene una tabla llamada `foo` que no existe en Node2
+ Cualquier operación de DML en la tabla `foo` en el Node1 producirá un error cuando se replique en Node2

**Solución:** cree la tabla `foo` en el Node2 con la misma estructura.

**nota**  
Actualmente, pgactivelink no replica los comandos CREATE USER ni las operaciones de DDL. La replicación de DDL está prevista para una versión futura.

### Conflictos de bloqueo y anulaciones de bloqueo
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict13"></a>

Como los procesos de aplicación de pgactive funcionan como sesiones de usuario normales, siguen las reglas estándar de bloqueo de filas y tablas. Esto puede provocar que los procesos de aplicación de pgactivelink esperen por bloqueos mantenidos por transacciones de usuarios o por otros procesos de aplicación.

Los siguientes tipos de bloqueos pueden afectar a los procesos de aplicación:
+ Bloqueo explícito en el nivel de tabla (LOCK TABLE...) por sesiones de usuario
+ Bloqueo explícito en el nivel de fila (SELECT ... FOR UPDATE/FOR SHARE) por sesiones de usuario
+ Bloqueo desde claves foráneas
+ Bloqueo implícito debido a UPDATE, INSERT o DELETE de filas, ya sea por actividad local o aplicación desde otros servidores

Los bloqueos pueden ocurrir entre:
+ Un proceso de aplicación de pgactivelink y una transacción de usuario
+ Dos procesos de aplicación

Cuando se producen bloqueos, el detector de bloqueos de PostgreSQL finaliza una de las transacciones problemáticas. Si se termina el proceso del trabajador de aplicación de pgactivelink, este reintenta automáticamente y normalmente tiene éxito.

**nota**  
Estos problemas son temporales y generalmente no requieren la intervención del administrador. Si un proceso de aplicación está bloqueado durante un periodo prolongado por un bloqueo en una sesión de usuario inactiva, puede terminar la sesión de usuario para reanudar la replicación. Esta situación es similar a cuando un usuario mantiene un bloqueo prolongado que afecta a la sesión de otro usuario.
Para identificar los retrasos en la reproducción relacionados con el bloqueo, habilite la instalación `log_lock_waits` en PostgreSQL.

### Conflictos divergentes
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14"></a>

Los conflictos divergentes se producen cuando los datos que deberían ser idénticos en todos los nodos difieren inesperadamente. Aunque estos conflictos no se deberían producir, no todos se pueden prevenir de forma fiable con la implementación actual.

**nota**  
 La modificación de PRIMARY KEY de una fila puede provocar conflictos divergentes si otro nodo cambia la clave de la misma fila antes de que todos los nodos procesen el cambio. Evite cambiar las claves principales o restrinja los cambios a un nodo designado. Para obtener más información, consulte [Conflictos UPDATE en la PRIMARY KEY](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict5).

Los conflictos divergentes relacionados con los datos de las filas suelen requerir la intervención del administrador. Para resolver estos conflictos, debe ajustar manualmente los datos de un nodo para que coincidan con otro mientras desactiva temporalmente la replicación mediante `pgactive.pgactive_do_not_replicate`. Estos conflictos no se deberían producir cuando se utiliza pgactive tal como se ha documentado y se evitan las configuraciones o funciones marcadas como inseguras.

 Como administrador, debe resolver estos conflictos manualmente. En función del tipo de conflicto, necesitará utilizar opciones avanzadas como `pgactive.pgactive_do_not_replicate`. Use estas opciones con precaución, ya que un uso incorrecto puede empeorar la situación. Debido a la variedad de posibles conflictos, no podemos proporcionar instrucciones de resolución universales.

Los conflictos divergentes se producen cuando los datos que deberían ser idénticos en diferentes nodos difieren inesperadamente. Aunque estos conflictos no deberían producirse, no todos se pueden prevenir de forma fiable con la implementación actual.

## Evitar o tolerar los conflictos
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.avoidconflicts"></a>

 En la mayoría de los casos, puede utilizar un diseño de aplicación adecuado para evitar conflictos o hacer que la aplicación tolere los conflictos.

 Los conflictos solo se producen cuando se realizan operaciones simultáneas en varios nodos. Para evitar conflictos:
+ Escriba solo en un nodo
+ Escriba en subconjuntos de bases de datos independientes en cada nodo (por ejemplo, asigne a cada nodo un esquema independiente)

Para conflictos entre INSERT e INSERT, utilice secuencias globales para evitar conflictos por completo.

 Si los conflictos no son aceptables para su caso de uso, considere implementar el bloqueo distribuido a nivel de aplicación. A menudo, el mejor enfoque es diseñar la aplicación para que funcione con los mecanismos de resolución de conflictos de pgactive en lugar de intentar prevenir todos los conflictos. Para obtener más información, consulte [Tipos de conflictos](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflicttypes). 

## Registro de conflictos
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflictlogging"></a>

pgactivelink registra los incidentes de conflicto en la tabla `pgactive.pgactive_conflict_history` para ayudarle a diagnosticar y gestionar los conflictos activo-activo. El registro de conflictos en esta tabla solo se produce cuando se establece `pgactive.log_conflicts_to_table` en verdadero. La extensión pgactive también registra los conflictos en el archivo de registro de PostgreSQL cuando log\$1min\$1messages se establece en `LOG` o `lower`, independientemente de la configuración de `pgactive.log_conflicts_to_table`.

 Utilice la tabla del historial de conflictos para:
+ Medir la frecuencia con la que la aplicación crea conflictos
+ Identificar dónde se producen los conflictos
+ Mejorar la aplicación para reducir las tasas de conflictos
+ Detectar casos en los que las resoluciones de conflictos no producen los resultados deseados
+ Determinar dónde necesita desencadenantes de conflictos definidos por el usuario o cambios en el diseño de la aplicación

 Para los conflictos de filas, puede registrar opcionalmente los valores de las filas. Esto se controla mediante la configuración de `pgactive.log_conflicts_to_table`. Tenga en cuenta que:
+ Esta es una opción global para toda la base de datos
+ No hay ningún control por tabla sobre el registro de valores de fila
+ No se aplican límites a los números de campo, los elementos de matriz o las longitudes de los campos
+ Puede que no sea recomendable activar esta característica si trabaja con filas de varios megabytes que podrían desencadenar conflictos

 Como la tabla del historial de conflictos contiene datos de todas las tablas de la base de datos (cada una con posibles esquemas diferentes), los valores de las filas registradas se almacenan como campos JSON. El JSON se crea mediante `row_to_json`, de forma similar a llamarlo directamente desde SQL. PostgreSQL no proporciona una función `json_to_row`, por lo que necesitará código específico de tabla (en PL/pgSQL, PL/Python, PL/Perl, etc.) para reconstruir una tupla de tipo compuesto a partir del JSON registrado.

**nota**  
La compatibilidad para conflictos definidos por el usuario está planificada como una característica de extensión futura.

# Descripción del esquema de pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.schema"></a>

El esquema de pgactive administra la replicación activo-activo en RDS para PostgreSQL. Este esquema contiene tablas que almacenan información sobre la configuración y el estado de la replicación.

**nota**  
El esquema de pgactive está en evolución y está sujeto a cambios. No modifique los datos de estas tablas directamente.

Las tablas de claves del esquema de pgactive incluyen:
+ `pgactive_nodes`: almacena información sobre los nodos del grupo de replicación activo-activo.
+ `pgactive_connections`: almacena los detalles de conexión de cada nodo.

## pgactive\$1nodes
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.schema.nodes"></a>

pgactive\$1nodes almacena información sobre los nodos que participan en el grupo de replicación activo-activo. 


| Columna | Tipo | Collation (Intercalación) | Nullable | Predeterminado | 
| --- | --- | --- | --- | --- | 
| node\$1sysid | text | – | not null | – | 
| node\$1timeline | oid | – | not null | – | 
| node\$1dboid | oid | – | not null | – | 
| node\$1status | char | – | not null | – | 
| node\$1name | text | – | not null | – | 
| node\$1dsn | text | – | not null | – | 
| node\$1init\$1from\$1dsn | text | – | not null | – | 
| node\$1read\$1only | valor booleano | – | – | false | 
| node\$1seq\$1id | smallint | – | not null | – | 

**node\$1sysid**  
ID único para un nodo, generado durante `pgactive_create_group` o `pgactive_join_group`

**node\$1status**  
Preparación del nodo:  
+ **b**: configuración inicial
+ **i**: inicio
+ **c**: recuperación
+ **o**: creación de ranuras de salida
+ **r**: listo
+ **k**: interrumpido
Esta columna no indica si un nodo está conectado o desconectado.

**node\$1name**  
Nombre de nodo único proporcionado por el usuario.

**node\$1dsn**  
Cadena de conexión o nombre de mapeo de usuario

**node\$1init\$1from\$1dsn**  
DSN a partir del cual se creó este nodo.

## pgactive\$1connection
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.schema.connection"></a>

pgactive\$1connections almacena los detalles de conexión de cada nodo.


| Columna | Tipo | Collation (Intercalación) | Nullable | Predeterminado | 
| --- | --- | --- | --- | --- | 
| conn\$1sysid | text | none | not null | none | 
| conn\$1timeline | oid | none | not null | none | 
| conn\$1dboid | oid | none | not null | none | 
| conn\$1dsn | text | none | not null | none | 
| conn\$1apply\$1delay | entero | none | none | none | 
| conn\$1replication\$1sets | text | none | none | none | 

conn\$1sysid  
Identificador de nodo del nodo al que hace referencia esta entrada.

conn\$1dsn  
Igual que pgactive.pgactive\$1nodes `node_dsn`.

conn\$1apply\$1delay  
Si se establece, milisegundos que hay que esperar antes de aplicar cada transacción desde el nodo remoto. Principalmente para depurar. Si es nulo, se aplica el valor predeterminado global.

## Uso de conjuntos de replicación
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.replication"></a>

Los conjuntos de replicación determinan qué tablas incluir o excluir de las operaciones de replicación. De forma predeterminada, todas las tablas se replican a menos que especifique lo contrario mediante las siguientes funciones:
+ `pgactive_exclude_table_replication_set()`: excluye las tablas especificadas de la replicación
+ `pgactive_include_table_replication_set()`: incluye las tablas especificadas en la replicación

**nota**  
Antes de configurar los conjuntos de replicación, tenga en cuenta lo siguiente:  
Puede configurar la inclusión o exclusión de tablas solo después de ejecutar `pgactive_create_group()` pero antes de `pgactive_join_group()`.
Después de usar `pgactive_exclude_table_replication_set()`, no puede usar `pgactive_include_table_replication_set()`.
Después de usar `pgactive_include_table_replication_set()`, no puede usar `pgactive_exclude_table_replication_set()`.

El sistema gestiona las tablas recién creadas de forma diferente en función de la configuración inicial:
+ Si excluyó las tablas: todas las tablas nuevas que se creen después de `pgactive_join_group()` se incluyen automáticamente en la replicación
+ Si incluyó las tablas: todas las tablas nuevas que se creen después de `pgactive_join_group()` se excluyen automáticamente de la replicación.

Para ver la configuración del conjunto de réplicas de una tabla específica, utilice la función `pgactive.pgactive_get_table_replication_sets()`.

# Referencia de funciones de pgactive
<a name="pgactive-functions-reference"></a>

A continuación, puede encontrar una lista de funciones de pgactive con sus parámetros, valores de devolución y notas prácticas de uso para ayudarle a utilizarlas de forma eficaz:

## get\$1last\$1applied\$1xact\$1info
<a name="get-last-applied-xact-info"></a>

Recupera la información de la última transacción aplicada a un nodo específico.

**Arguments**  
+ sysid (texto): OID de línea temporal
+ dboid (OID)

**Tipo de devolución**  
Hace lo siguiente:  
+ last\$1applied\$1xact\$1id (OID)
+ last\$1applied\$1xact\$1committs (marca temporal con zona horaria)
+ last\$1applied\$1xact\$1at (marca temporal con zona horaria)

**Notas de uso**  
Use esta función para recuperar la información de la última transacción aplicada a un nodo específico.

## pgactive\$1apply\$1pause
<a name="pgactive-apply-pause"></a>

Pausa el proceso de aplicación de la replicación.

**Arguments**  
Ninguno

**Tipo de devolución**  
booleano

**Notas de uso**  
Llame a esta función para pausar el proceso de aplicación de la replicación.

## pgactive\$1apply\$1resume
<a name="pgactive-apply-resume"></a>

Reanuda el proceso de aplicación de la replicación.

**Arguments**  
Ninguno

**Tipo de devolución**  
void

**Notas de uso**  
Llame a esta función para reanudar el proceso de aplicación de la replicación.

## pgactive\$1is\$1apply\$1paused
<a name="pgactive-is-apply-paused"></a>

Comprueba si la aplicación de la replicación está actualmente en pausa.

**Arguments**  
Ninguno

**Tipo de devolución**  
booleano

**Notas de uso**  
Use esta función para comprobar si la aplicación de la replicación está actualmente en pausa.

## pgactive\$1create\$1group
<a name="pgactive-create-group"></a>

Crea un grupo pgactive convirtiendo una base de datos independiente en el nodo inicial.



**Arguments**  
+ node\$1name (texto)
+ node\$1dsn (texto)
+ apply\$1delay integer DEFAULT NULL::integer - replication\$1sets text[] DEFAULT ARRAY[‘default’::text]

**Tipo de devolución**  
void

**Notas de uso**  
Crea un grupo pgactive convirtiendo una base de datos independiente en el nodo inicial. La función realiza comprobaciones de integridad antes de transformar el nodo en un nodo de pgactive. Antes de usar esta función, asegúrese de que el clúster de PostgreSQL tenga suficientes `max_worker_processes` disponibles para admitir los trabajadores en segundo plano de pgactive.

## pgactive\$1detach\$1nodes
<a name="pgactive-detach-nodes"></a>

Elimina los nodos especificados del grupo pgactive.

**Arguments**  
+ p\$1nodes (text[])

**Tipo de devolución**  
void

**Notas de uso**  
Use esta función para eliminar los nodos especificados del grupo pgactive.

## pgactive\$1exclude\$1table\$1replication\$1set
<a name="pgactive-exclude-table-replication-set"></a>

Excluye una tabla específica de la replicación.

**Arguments**  
+ p\$1relation (regclass)

**Tipo de devolución**  
void

**Notas de uso**  
Utilice esta función para excluir una tabla específica de la replicación.

## pgactive\$1get\$1replication\$1lag\$1info
<a name="pgactive-get-replication-lag-info"></a>

Recupera información detallada sobre el retraso de la replicación, incluidos los detalles del nodo, el estado de WAL y los valores de LSN.

**Arguments**  
Ninguno

**Tipo de devolución**  
SETOF record - node\$1name text - node\$1sysid text - application\$1name text - slot\$1name text - active boolean - active\$1pid integer - pending\$1wal\$1decoding bigint - Tamaño aproximado de WAL en bytes que se decodificará en el nodo emisor - pending\$1wal\$1to\$1apply bigint - Tamaño aproximado del WAL en bytes que se aplicará en el nodo receptor - restart\$1lsn pg\$1lsn - confirmed\$1flush\$1lsn pg\$1lsn - sent\$1lsn pg\$1lsn - write\$1lsn pg\$1lsn - flush\$1lsn pg\$1lsn - replay\$1lsn pg\$1lsn

**Notas de uso**  
Llame a esta función para recuperar información sobre el retraso de la replicación, incluidos los detalles del nodo, el estado de WAL y los valores de LSN.

## pgactive\$1get\$1stats
<a name="pgactive-get-stats"></a>

Recupera las estadísticas de replicación de pgactive.

**Arguments**  
Ninguno

**Tipo de devolución**  
SETOF record - rep\$1node\$1id oid - rilocalid oid - riremoteid text - nr\$1commit bigint - nr\$1rollback bigint - nr\$1insert bigint - nr\$1insert\$1conflict bigint - nr\$1update bigint - nr\$1update\$1conflict bigint - nr\$1delete bigint - nr\$1delete\$1conflict bigint - nr\$1disconnect bigint

**Notas de uso**  
Utilice esta función para recuperar las estadísticas de replicación de pgactive.

## pgactive\$1get\$1table\$1replication\$1sets
<a name="pgactive-get-table-replication-sets"></a>

Obtiene la configuración del conjunto de replicación de una relación específica.

**Arguments**  
+ relación (regclass)

**Tipo de devolución**  
Registro SETOF

**Notas de uso**  
Llame a esta función para obtener la configuración del conjunto de replicación de una relación específica.

## pgactive\$1include\$1table\$1replication\$1set
<a name="pgactive-include-table-replication-set"></a>

Incluye una tabla específica en la replicación.

**Arguments**  
+ p\$1relation (regclass)

**Tipo de devolución**  
void

**Notas de uso**  
Utilice esta función para incluir una tabla específica en la replicación.

## pgactive\$1join\$1group
<a name="pgactive-join-group"></a>

Agrega un nodo a un grupo pgactive existente.

**Arguments**  
+ node\$1name (texto)
+ node\$1dsn (texto)
+ join\$1using\$1dsn (texto)
+ apply\$1delay (entero, opcional)
+ replication\$1sets (text[], predeterminado: ['default'])
+ bypass\$1collation\$1check (booleano, predeterminado: falso)
+ bypass\$1node\$1identifier\$1creation (booleano, predeterminado: falso)
+ bypass\$1user\$1tables\$1check (booleano, predeterminado: falso)

**Tipo de devolución**  
void

**Notas de uso**  
Llame a esta función para agregar un nodo a un grupo pgactive existente. Asegúrese de que el clúster de PostgreSQL tenga suficientes max\$1worker\$1processes para los trabajadores en segundo plano de pgactive.

## pgactive\$1remove
<a name="pgactive-remove"></a>

Elimina todos los componentes de pgactive del nodo local.

**Arguments**  
+ force (booleano, predeterminado: falso)

**Tipo de devolución**  
void

**Notas de uso**  
Llame a esta función para eliminar todos los componentes de pgactive del nodo local.

## pgactive\$1snowflake\$1id\$1nextval
<a name="pgactive-snowflake-id-nextval"></a>

Genera valores de secuencia únicos específicos del nodo.

**Arguments**  
+ regclass

**Tipo de devolución**  
bigint

**Notas de uso**  
Utilice esta función para generar valores de secuencia únicos específicos del nodo.

## pgactive\$1update\$1node\$1conninfo
<a name="pgactive-update-node-conninfo"></a>

Actualiza la información de conexión de un nodo de pgactive.

**Arguments**  
+ node\$1name\$1to\$1update (texto)
+ node\$1dsn\$1to\$1update (texto)

**Tipo de devolución**  
void

**Notas de uso**  
Use esta función para actualizar la información de conexión de un nodo de pgactive.

## pgactive\$1wait\$1for\$1node\$1ready
<a name="pgactive-wait-for-node-ready"></a>

Supervisa el progreso de las operaciones de creación o unión de grupos.

**Arguments**  
+ timeout (entero, predeterminado: 0)
+ progress\$1interval (entero, predeterminado: 60)

**Tipo de devolución**  
void

**Notas de uso**  
Llame a esta función para supervisar el progreso de las operaciones de creación o unión de grupos.

# Gestión de conflictos en la replicación activa-activa
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-conflicts"></a>

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\$1cron de PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL_pg_cron.html).

# Gestión de secuencias en la replicación activa-activa
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-sequences"></a>

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.

```
app=> CREATE TABLE gstest (
      id bigint primary key,
      parrot text
    );
```

```
app=>CREATE SEQUENCE gstest_id_seq OWNED BY gstest.id;
```

```
app=> 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);
```

```
app=> CREATE SEQUENCE some_seq INCREMENT 100 OWNED BY some_table.generated_value;
```

```
app=> 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.

```
app=>
-- On node 1
SELECT setval('some_seq', 1);

-- On node 2
SELECT setval('some_seq', 2);
```

# Reducción de la sobrecarga en tablas e índices con la extensión pg\$1repack
<a name="Appendix.PostgreSQL.CommonDBATasks.pg_repack"></a>

Puede usar la extensión `pg_repack` para eliminar el sobredimensionamiento de las tablas y los índices como alternativa a `VACUUM FULL`. Esta extensión es compatible con RDS para las versiones 9.6.3 y superiores de PostgreSQL. Para obtener más información acerca de la extensión `pg_repack` y el reempaquetado de tablas completo, consulte la [documentación del proyecto de GitHub](https://reorg.github.io/pg_repack/).

A diferencia de lo que ocurre con `VACUUM FULL`, la extensión `pg_repack` requiere un bloqueo exclusivo (AccessExclusiveLock) por un breve período de tiempo durante la operación de reconstrucción de la tabla en los siguientes casos:
+ Creación inicial de la tabla de registro: se crea una tabla de registro para registrar los cambios que se producen durante la copia inicial de los datos, como se muestra en el siguiente ejemplo: 

  ```
  postgres=>\dt+ repack.log_*
  List of relations
  -[ RECORD 1 ]-+----------
  Schema        | repack
  Name          | log_16490
  Type          | table
  Owner         | postgres
  Persistence   | permanent
  Access method | heap
  Size          | 65 MB
  Description   |
  ```
+ Fase final de intercambio y eliminación.

Para el resto de la operación de reconstrucción, solo se necesita un bloqueo `ACCESS SHARE` en la tabla original para copiar sus filas a la nueva tabla. Esto ayuda a que las operaciones INSERT, UPDATE y DELETE continúen como de costumbre.

## Recomendaciones
<a name="Appendix.PostgreSQL.CommonDBATasks.pg_repack.Recommen"></a>

Las siguientes recomendaciones se aplican al eliminar el sobredimensionamiento de las tablas e índices mediante la extensión `pg_repack`:
+ Realice el reempaquetado fuera del horario laboral o durante un período de mantenimiento para minimizar su impacto en el rendimiento de otras actividades de la base de datos.
+ Monitorice de cerca las sesiones de bloqueo durante la actividad de reconstrucción y asegúrese de que no haya ninguna actividad en la tabla original que pueda bloquear `pg_repack`, especialmente durante la fase final de intercambio y eliminación, cuando es necesario bloquear exclusivamente la tabla original. Para obtener más información, consulte [Identificar qué bloquea una consulta](https://repost.aws/knowledge-center/rds-aurora-postgresql-query-blocked). 

  Si ve una sesión que bloquee, puede finalizarla mediante el siguiente comando tras estudiarla detenidamente. Esto ayuda a continuar con `pg_repack` para terminar la reconstrucción:

  ```
  SELECT pg_terminate_backend(pid);
  ```
+ Al aplicar los cambios acumulados de la tabla de registro `pg_repack's` en sistemas con una tasa de transacciones muy alta, es posible que el proceso de solicitud no pueda mantener la tasa de cambios. En esos casos, `pg_repack` no podría completar el proceso de aplicación. Para obtener más información, consulte [Monitorización de la nueva tabla durante el reempaquetado](#Appendix.PostgreSQL.CommonDBATasks.pg_repack.Monitoring). Si los índices están muy sobredimensionados, una solución alternativa es volver a empaquetar únicamente los índices. Esto también ayuda a que los ciclos de limpieza de índices de VACUUM finalicen más rápido.

  Puede omitir la fase de limpieza de índices mediante el VACUUM manual de la versión 12 de PostgreSQL, y se omite automáticamente durante el autovacuum de emergencia de la versión 14 de PostgreSQL. Esto ayuda a que VACUUM se complete más rápido sin eliminar el sobredimensionamiento del índice y solo está diseñado para situaciones de emergencia, como evitar que el VACUUM se acumule. Para obtener más información, consulte [Evitar la sobrecarga en los índices](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.diag-table-ind-bloat.html#AuroraPostgreSQL.diag-table-ind-bloat.AvoidinginIndexes) en la Guía del usuario de Amazon Aurora.

## Requisitos previos
<a name="Appendix.PostgreSQL.CommonDBATasks.pg_repack.Prereq"></a>
+ La tabla debe tener una restricción de PRIMARY KEY o una UNIQUE que no sea null.
+ La versión de la extensión debe ser la misma tanto para el cliente como para el servidor.
+ Asegúrese de que la instancia de RDS tenga más `FreeStorageSpace` que el tamaño total de la tabla sin la sobrecarga. Como ejemplo, considere el tamaño total de la tabla, incluidos el TOAST y los índices, como de 2 TB, y el tamaño total de la tabla como 1 TB. El `FreeStorageSpace` requerido debe ser superior al valor devuelto por el siguiente cálculo:

   `2TB (Table size)` - `1TB (Table bloat)` = `1TB`

  Puede utilizar la siguiente consulta para comprobar el tamaño total de la tabla y utilizar `pgstattuple` para derivar la sobrecarga. Para obtener más información, consulte [Diagnóstico de sobrecarga de tablas e índices](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.diag-table-ind-bloat.html) en la Guía del usuario de Amazon Aurora. 

  ```
  SELECT pg_size_pretty(pg_total_relation_size('table_name')) AS total_table_size;
  ```

  Este espacio se recupera una vez finalizada la actividad. 
+ Asegúrese de que la instancia de RDS tenga suficiente capacidad de procesamiento y E/S para gestionar la operación de reempaquetado. Podría considerar la posibilidad de escalar verticalmente la clase de instancia para lograr un equilibrio óptimo del rendimiento. 

**Para usar la extensión `pg_repack`**

1. Instale la extensión `pg_repack` en la instancia de base de datos de RDS for PostgreSQL con el siguiente comando.

   ```
   CREATE EXTENSION pg_repack;
   ```

1. Ejecute los siguientes comandos para conceder acceso de escritura a las tablas de registro temporales creadas por `pg_repack`.

   ```
   ALTER DEFAULT PRIVILEGES IN SCHEMA repack GRANT INSERT ON TABLES TO PUBLIC;
   ALTER DEFAULT PRIVILEGES IN SCHEMA repack GRANT USAGE, SELECT ON SEQUENCES TO PUBLIC;
   ```

1. Conéctese a la base de datos mediante la utilidad de cliente `pg_repack`. Utilice una cuenta que tenga privilegios `rds_superuser`. Por ejemplo, suponga que ese rol `rds_test` tiene privilegios `rds_superuser`. La siguiente sintaxis realiza `pg_repack` para tablas completas, incluidos todos los índices de tablas de la base de datos `postgres`.

   ```
   pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test -k postgres
   ```
**nota**  
Debe conectarse usando la opción -k. La opción -a no se admite.

   La respuesta del cliente `pg_repack` proporciona información relativa a las tablas de la instancia de base de datos que se han vuelto a empaquetar.

   ```
   INFO: repacking table "pgbench_tellers"
   INFO: repacking table "pgbench_accounts"
   INFO: repacking table "pgbench_branches"
   ```

1. La siguiente sintaxis vuelve a empaquetar una sola tabla `orders`, incluidos los índices de la base de datos `postgres`.

   ```
   pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test --table orders -k postgres
   ```

   La siguiente sintaxis reempaqueta solo los índices de la tabla `orders` de la base de datos `postgres`.

   ```
   pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test --table orders --only-indexes -k postgres
   ```

## Monitorización de la nueva tabla durante el reempaquetado
<a name="Appendix.PostgreSQL.CommonDBATasks.pg_repack.Monitoring"></a>
+ El tamaño de la base de datos se incrementa en función del tamaño total de la tabla, menos la sobrecarga, hasta la fase de intercambio y eliminación del reempaquetado. Puede monitorizar la tasa de crecimiento del tamaño de la base de datos, calcular la velocidad de reempaquetado y estimar aproximadamente el tiempo que se tarda en completar la transferencia inicial de datos.

  Como ejemplo, considere que el tamaño total de la tabla es de 2 TB, el tamaño de la base de datos es de 4 TB y la sobrecarga total de la tabla es de 1 TB. El valor del tamaño total de la base de datos devuelto por el cálculo al final de la operación de reempaquetado es el siguiente:

   `2TB (Table size)` \$1 `4 TB (Database size)` - `1TB (Table bloat)` = `5TB`

  Puede estimar aproximadamente la velocidad de la operación de reempaquetado muestreando la tasa de crecimiento en bytes entre dos puntos en el tiempo. Si la tasa de crecimiento es de 1 GB por minuto, la operación inicial de creación de la tabla puede tardar 1000 minutos o 16,6 horas aproximadamente en completarse. Además de la construcción inicial de la tabla, `pg_repack` también necesita aplicar los cambios acumulados. El tiempo que tarda depende del ritmo de aplicación de los cambios continuos más los acumulados.
**nota**  
Puede usar la extensión `pgstattuple` para calcular la sobrecarga en la tabla. Para obtener más información, consulte [pgstattuple](https://www.postgresql.org/docs/current/pgstattuple.html).
+ El número de filas de la tabla de registro `pg_repack's`, según el esquema de reempaquetado, representa el volumen de cambios pendientes de aplicarse a la nueva tabla tras la carga inicial.

  Puede consultar la tabla de registro `pg_repack's` en `pg_stat_all_tables` para supervisar los cambios aplicados a la nueva tabla. `pg_stat_all_tables.n_live_tup` indica el número de registros pendientes de ser aplicados a la nueva tabla. Para obtener más información, consulte [pg\$1stat\$1all\$1tables](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW). 

  ```
  postgres=>SELECT relname,n_live_tup FROM pg_stat_all_tables WHERE schemaname = 'repack' AND relname ILIKE '%log%';
          
  -[ RECORD 1 ]---------
  relname    | log_16490
  n_live_tup | 2000000
  ```
+ Puede utilizar la extensión `pg_stat_statements` para determinar el tiempo que tarda cada paso de la operación de reempaquetado. Esto es útil para prepararse para aplicar la misma operación de reempaque en un entorno de producción. Puede ajustar la cláusula `LIMIT` para ampliar aún más la salida.

  ```
  postgres=>SELECT
       SUBSTR(query, 1, 100) query,
       round((round(total_exec_time::numeric, 6) / 1000 / 60),4) total_exec_time_in_minutes
   FROM
       pg_stat_statements
   WHERE
       query ILIKE '%repack%'
   ORDER BY
       total_exec_time DESC LIMIT 5;
          
   query                                                                 | total_exec_time_in_minutes
  -----------------------------------------------------------------------+----------------------------
   CREATE UNIQUE INDEX index_16493 ON repack.table_16490 USING btree (a) |                     6.8627
   INSERT INTO repack.table_16490 SELECT a FROM ONLY public.t1           |                     6.4150
   SELECT repack.repack_apply($1, $2, $3, $4, $5, $6)                    |                     0.5395
   SELECT repack.repack_drop($1, $2)                                     |                     0.0004
   SELECT repack.repack_swap($1)                                         |                     0.0004
  (5 rows)
  ```

El reempaquetado es una operación completamente fuera de lugar, por lo que la tabla original no se ve afectada y no prevemos ningún problema inesperado que requiera la recuperación de la tabla original. Si el reempaquetado falla inesperadamente, debe inspeccionar la causa del error y resolverlo.

Una vez resuelto el problema, coloque y vuelva a crear la extensión `pg_repack` en la base de datos en la que se encuentre la tabla y vuelva a intentar el paso `pg_repack`. Además, la disponibilidad de los recursos de computación y la accesibilidad simultánea de la tabla desempeñan un papel crucial a la hora de completar a tiempo la operación de reempaquetado.

# Actualización y uso de la extensión PLV8
<a name="PostgreSQL.Concepts.General.UpgradingPLv8"></a>

PLV8 es una extensión de lenguaje Javascript de confianza para PostgreSQL Puede usarlo para procedimientos almacenados, desencadenadores y otro código de procedimiento que se puede llamar desde SQL. Esta extensión de lenguaje es compatible con todas las versiones actuales de PostgreSQL. 

Si utiliza [PLV8](https://plv8.github.io/) y actualiza PostgreSQL a una nueva versión de PLV8, inmediatamente aprovecha la nueva extensión. Lleve a cabo los siguientes pasos para sincronizar los metadatos del catálogo con la nueva versión de PLV8. Estos pasos son opcionales, pero recomendamos que los complete para evitar advertencias de discrepancia de metadatos.

El proceso de actualización elimina todas las funciones PLV8 existentes. Por lo tanto, le recomendamos que cree una instantánea de su instancia de base de datos de RDS for PostgreSQL antes de la actualización. Para obtener más información, consulte [Creación de una instantánea de base de datos para una instancia de base de datos single-AZ para Amazon RDS](USER_CreateSnapshot.md).

**importante**  
A partir de la versión 18 de PostgreSQL, Amazon RDS para PostgreSQL dejará de utilizar las extensiones `plcoffee` y `plls` de PostgreSQL. Le recomendamos que deje de usar Coffeescript y LiveScript en sus aplicaciones para asegurarse de tener una ruta de actualización para futuras actualizaciones de las versiones del motor.

**Para sincronizar los metadatos del catálogo con una nueva versión de PLV8**

1. Verifique que necesita realizar la actualización. Para ello, ejecute el siguiente comando mientras está conectado a la instancia.

   ```
   SELECT * FROM pg_available_extensions WHERE name IN ('plv8','plls','plcoffee');
   ```

   Si los resultados contienen valores de una versión instalada con un número inferior a la versión predeterminada, continúe con este procedimiento para actualizar las extensiones. Por ejemplo, el siguiente conjunto de resultados indica que debería actualizar.

   ```
   name    | default_version | installed_version |                     comment
   --------+-----------------+-------------------+--------------------------------------------------
   plls    | 2.1.0           | 1.5.3             | PL/LiveScript (v8) trusted procedural language
   plcoffee| 2.1.0           | 1.5.3             | PL/CoffeeScript (v8) trusted procedural language
   plv8    | 2.1.0           | 1.5.3             | PL/JavaScript (v8) trusted procedural language
   (3 rows)
   ```

1. Cree una instantánea de la instancia de base de datos de RDS for PostgreSQL si aún no lo ha hecho. Puede continuar con los pasos siguientes mientras se crea la instantánea. 

1. Obtenga un recuento del número de funciones de PLV8 de su instancia de base de datos para que pueda validar que se aplican todas después de la actualización. Por ejemplo, la siguiente consulta SQL devuelve el número de funciones escritas en plv8, plcoffee y plls.

   ```
   SELECT proname, nspname, lanname 
   FROM pg_proc p, pg_language l, pg_namespace n
   WHERE p.prolang = l.oid
   AND n.oid = p.pronamespace
   AND lanname IN ('plv8','plcoffee','plls');
   ```

1. Use pg\$1dump para crear un archivo de volcado solo de esquema. Por ejemplo, cree un archivo en el equipo cliente en el directorio `/tmp`.

   ```
   ./pg_dump -Fc --schema-only -U master postgres >/tmp/test.dmp
   ```

   En este ejemplo se utilizan las siguientes opciones: 
   + `-Fc`: formato personalizado
   + --schema-only: vuelca solo los comandos necesarios para crear el esquema (funciones en este caso)
   + `-U`: el nombre de usuario maestro de RDS
   + `database`: el nombre de la base de datos para nuestra instancia de base de datos

   Para obtener más información sobre pg\$1dump, consulte [pg\$1dump](https://www.postgresql.org/docs/current/static/app-pgdump.html ) en la documentación de PostgreSQL.

1. Extraiga la instrucción DDL "CREATE FUNCTION" que se encuentra en el archivo de volcado. El siguiente ejemplo utiliza el comando `grep` para extraer la instrucción DDL que crea las funciones y guardarlas en un archivo. Se utiliza en los pasos posteriores para volver a crear las funciones. 

   ```
   ./pg_restore -l /tmp/test.dmp | grep FUNCTION > /tmp/function_list
   ```

   Para obtener más información sobre pg\$1restore, consulte [pg\$1restore](https://www.postgresql.org/docs/current/static/app-pgrestore.html) en la documentación de PostgreSQL. 

1. Borre las funciones y las extensiones. El siguiente ejemplo elimina cualquier objeto basado en PLV8. La opción cascade garantiza que se borren los dependientes.

   ```
   DROP EXTENSION plv8 CASCADE;
   ```

   Si su instancia de PostgreSQL contiene objetos basados en plcoffee o plls, repita este paso para dichas extensiones.

1. Cree las extensiones. El siguiente ejemplo crea las extensiones plv8, plcoffee y plls.

   ```
   CREATE EXTENSION plv8;
   CREATE EXTENSION plcoffee;
   CREATE EXTENSION plls;
   ```

1. Cree las funciones con el archivo de volcado y el archivo "driver".

   El siguiente ejemplo recrea las funciones que extrajo anteriormente.

   ```
   ./pg_restore -U master -d postgres -Fc -L /tmp/function_list /tmp/test.dmp
   ```

1. Verifique que todas las funciones se recrean con la siguiente consulta. 

   ```
   SELECT * FROM pg_available_extensions WHERE name IN ('plv8','plls','plcoffee'); 
   ```

   La versión 2 de PLV8 agrega la siguiente fila adicional a su conjunto de resultados:

   ```
       proname    |  nspname   | lanname
   ---------------+------------+----------
    plv8_version  | pg_catalog | plv8
   ```

# Uso de PL/Rust para escribir funciones de PostgreSQL en lenguaje Rust
<a name="PostgreSQL.Concepts.General.Using.PL_Rust"></a>

PL/Rust es una extensión del lenguaje Rust de confianza para PostgreSQL. Puede usarlo para procedimientos almacenados, funciones y otro código de procedimiento que se pueda llamar desde SQL. La extensión de lenguaje PL/Rust está disponible en las siguientes versiones:
+ RDS para PostgreSQL 17.1 y otras versiones 17 posteriores
+ RDS para PostgreSQL 16.1 y versiones 16 posteriores
+ RDS para PostgreSQL, 15.2-R2 y versiones 15 posteriores
+ RDS para PostgreSQL, 14.9 y versiones 14 posteriores
+ RDS para PostgreSQL, 13.12 y versiones 13 posteriores

Para obtener más información, consulte [PL/Rust](https://github.com/tcdi/plrust#readme) en GitHub.

**Topics**
+ [Configuración de PL/Rust](#PL_Rust-setting-up)
+ [Creación de funciones con PL/Rust](#PL_Rust-create-function)
+ [Uso de cajas con PL/Rust](#PL_Rust-crates)
+ [Limitaciones de PL/Rust](#PL_Rust-limitations)

## Configuración de PL/Rust
<a name="PL_Rust-setting-up"></a>

Para instalar la extensión plrust en la instancia de base de datos, agregue plrust al parámetro `shared_preload_libraries` en el grupo de parámetros de base de datos asociado con la instancia de base de datos. Con la extensión plrust instalada, puede crear funciones. 

Para modificar el parámetro `shared_preload_libraries`, la instancia de base de datos debe asociarse al grupo de parámetros 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](USER_WorkingWithParamGroups.md).

Puede instalar la extensión plrust mediante la Consola de administración de AWS o la AWS CLI.

En los pasos siguientes se supone que la instancia de base de datos está asociada a un grupo de parámetros de base de datos personalizado.

### Consola
<a name="PL_Rust-setting-up.CON"></a>

**Instalar la extensión plrust en el parámetro `shared_preload_libraries`**

Realice los siguientes pasos con una cuenta que sea miembro del grupo `rds_superuser` (rol).

1. Inicie sesión en la Consola de administración de AWS y abra la consola de Amazon RDS en [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

1. En el panel de navegación, elija **Databases** (Bases de datos).

1. Elija el nombre de la instancia de base de datos para ver los detalles.

1. Abra la pestaña **Configuración** de la instancia de base de datos y busque el enlace del grupo de parámetros de instancias de base de datos.

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

1. En el campo de búsqueda **Parámetros**, escriba `shared_pre` para buscar el parámetro `shared_preload_libraries`.

1. Seleccione **Edit parameters** (Editar parámetros) para acceder a los valores de las propiedades.

1. Añada plrust a la lista en el campo **Valores**. Utilice una coma para separar los elementos de la lista de valores.

1. Reinicie la instancia de base de datos para que los cambios en el parámetro `shared_preload_libraries` surtan efecto. El reinicio inicial puede requerir tiempo adicional para completarse.

1. Cuando la instancia esté disponible, compruebe si se ha inicializado plrust. Use `psql` para conectarse a la instancia de base de datos y ejecute el siguiente comando.

   ```
   SHOW shared_preload_libraries;
   ```

   El resultado debería tener un aspecto similar al siguiente:

   ```
   shared_preload_libraries 
   --------------------------
   rdsutils,plrust
   (1 row)
   ```

### AWS CLI
<a name="PL_Rust-setting-up-CLI"></a>

**Instale la extensión plrust en el parámetro shared\$1preload\$1libraries.**

Realice los siguientes pasos con una cuenta que sea miembro del grupo `rds_superuser` (rol).

1. Use el comando [modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html) de AWS CLI para añadir plrust al parámetro `shared_preload_libraries`.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=shared_preload_libraries,ParameterValue=plrust,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. Use el comando [reboot-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/reboot-db-instance) de AWS CLI para reiniciar la instancia de base de datos e inicializar la biblioteca plrust. El reinicio inicial puede requerir tiempo adicional para completarse.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. Cuando la instancia esté disponible, compruebe si se ha inicializado plrust. Use `psql` para conectarse a la instancia de base de datos y ejecute el siguiente comando.

   ```
   SHOW shared_preload_libraries;
   ```

   El resultado debería tener un aspecto similar al siguiente:

   ```
   shared_preload_libraries
   --------------------------
   rdsutils,plrust
   (1 row)
   ```

## Creación de funciones con PL/Rust
<a name="PL_Rust-create-function"></a>

PL/Rust compilará la función como biblioteca dinámica, la cargará y la ejecutará.

La siguiente función de Rust filtra los múltiplos de una matriz.

```
postgres=> CREATE LANGUAGE plrust;
CREATE EXTENSION
```

```
CREATE OR REPLACE FUNCTION filter_multiples(a BIGINT[], multiple BIGINT) RETURNS BIGINT[]
    IMMUTABLE STRICT
    LANGUAGE PLRUST AS
$$
    Ok(Some(a.into_iter().filter(|x| x.unwrap() % multiple != 0).collect()))
$$;
        
WITH gen_values AS (
SELECT ARRAY(SELECT * FROM generate_series(1,100)) as arr)
SELECT filter_multiples(arr, 3)
from gen_values;
```

## Uso de cajas con PL/Rust
<a name="PL_Rust-crates"></a>

En RDS para PostgreSQL versiones 16.3-R2 y posteriores, 15.7-R2 y versiones 15 posteriores, 14.12-R2 y versiones 14 posteriores y 13.15-R2 y versiones 13 y posteriores, PL/Rust admite cajas adicionales:
+ `url` 
+ `regex` 
+ `serde` 
+ `serde_json` 

En RDS para PostgreSQL versiones 15.5-R2 y posteriores, 14.10-R2 y versiones 14 posteriores y 13.13-R2 y versiones 13 posteriores, PL/Rust admite dos cajas adicionales:
+ `croaring-rs` 
+ `num-bigint` 

A partir de las versiones 15.4, 14.9 y 13.12 de Amazon RDS para PostgreSQL, PL/Rust admite las siguientes cajas:
+ `aes` 
+ `ctr` 
+ `rand` 

Estas cajas solo admiten las funciones predeterminadas. Es posible que las nuevas versiones de RDS para PostgreSQL contengan versiones actualizadas de las cajas y que las versiones anteriores de las cajas ya no sean compatibles.

Siga las prácticas recomendadas para realizar una actualización de una versión principal y comprobar si las funciones de PL/Rust son compatibles con la nueva versión principal. Para obtener más información, consulte el blog [Best practices for upgrading Amazon RDS to major and minor versions of PostgreSQL](https://aws.amazon.com/blogs/database/best-practices-for-upgrading-amazon-rds-to-major-and-minor-versions-of-postgresql/) y [Actualización del motor de base de datos de PostgreSQL para Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.PostgreSQL.html) en la Guía del usuario de Amazon RDS. 

Encontrará ejemplos del uso de dependencias al crear una función de PL/Rust en [Use dependencies](https://tcdi.github.io/plrust/use-plrust.html#use-dependencies).

## Limitaciones de PL/Rust
<a name="PL_Rust-limitations"></a>

De forma predeterminada, los usuarios de bases de datos no pueden usar PL/Rust. Para proporcionar acceso a PL/Rust, conéctese como usuario con el privilegio rds\$1superuser y ejecute el siguiente comando:

```
postgres=> GRANT USAGE ON LANGUAGE PLRUST TO user;
```

# Administración de datos espaciales con la extensión PostGIS
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS"></a>

PostGIS es una extensión de PostgreSQL para almacenar y administrar información espacial. Para obtener más información sobre PostGIS, consulte [PostGIS.net](https://postgis.net/). 

A partir de la versión 10.5, PostgreSQL admite la biblioteca libprotobuf 1.3.0 utilizada por PostGIS para trabajar con datos de teselas vectoriales de Mapbox.

La configuración de la extensión PostGIS requiere privilegios de `rds_superuser`. Le recomendamos que cree un usuario (rol) para administrar instalar la extensión PostGIS y los datos espaciales. La extensión PostGIS y sus componentes relacionados añaden miles de funciones a PostgreSQL. Considere la posibilidad de crear la extensión PostGIS en su propio esquema si eso tiene sentido para su caso de uso. En el ejemplo siguiente, se muestra cómo instalar la extensión en su propia base de datos, pero esto no es obligatorio.

**Topics**
+ [Paso 1: cree un usuario (rol) para administrar la extensión PostGIS](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Connect)
+ [Paso 2: cargue las extensiones PostGIS](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.LoadExtensions)
+ [Paso 3: transferir la propiedad de los esquemas de extensión](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferOwnership)
+ [Paso 4: transferir la propiedad de las tablas de PostGIS](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferObjects)
+ [Paso 5: pruebe las extensiones](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Test)
+ [Paso 6: Actualice la extensión de PostGIS](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Update)
+ [Versiones de extensión de PostGIS](#CHAP_PostgreSQL.Extensions.PostGIS)
+ [Actualización de PostGIS 2 a PostGIS 3](#PostgreSQL.Extensions.PostGIS.versions.upgrading.2-to-3)

## Paso 1: cree un usuario (rol) para administrar la extensión PostGIS
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.Connect"></a>

En primer lugar, conéctese a una instancia de base de datos de RDS para PostgreSQL como usuario con privilegios `rds_superuser`. Si mantuvo el nombre predeterminado al configurar la instancia, conéctese como `postgres`. 

```
psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
```

Cree un rol independiente (usuario) para administrar la extensión PostGIS.

```
postgres=>  CREATE ROLE gis_admin LOGIN PASSWORD 'change_me';
CREATE ROLE
```

Conceda los privilegios `rds_superuser` de este rol para permitir que el rol instale la extensión.

```
postgres=> GRANT rds_superuser TO gis_admin;
GRANT
```

Cree una base de datos para utilizarla para sus artefactos de PostGIS. Este paso es opcional. O puede crear un esquema en la base de datos de usuarios para las extensiones de PostGIS, pero esto tampoco es obligatorio.

```
postgres=> CREATE DATABASE lab_gis;
CREATE DATABASE
```

Conceda todos los privilegios `gis_admin` en la base de datos `lab_gis`.

```
postgres=> GRANT ALL PRIVILEGES ON DATABASE lab_gis TO gis_admin;
GRANT
```

Salga de la sesión y vuelva a conectarse a una instancia de base de datos de RDS para PostgreSQL como `gis_admin`.

```
postgres=> psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=gis_admin --password --dbname=lab_gis
Password for user gis_admin:...
lab_gis=>
```

Continúe configurando la extensión tal y como se detalla en los pasos siguientes.

## Paso 2: cargue las extensiones PostGIS
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.LoadExtensions"></a>

La extensión de PostGIS incluye varias extensiones relacionadas que funcionan juntas para proporcionar funcionalidad geoespacial. Dependiendo de su caso de uso, es posible que no necesite todas las extensiones creadas en este paso. 

Utilice instrucciones `CREATE EXTENSION` para cargar las extensiones de PostGIS. 

```
CREATE EXTENSION postgis;
CREATE EXTENSION
CREATE EXTENSION postgis_raster;
CREATE EXTENSION
CREATE EXTENSION fuzzystrmatch;
CREATE EXTENSION
CREATE EXTENSION postgis_tiger_geocoder;
CREATE EXTENSION
CREATE EXTENSION postgis_topology;
CREATE EXTENSION
CREATE EXTENSION address_standardizer_data_us;
CREATE EXTENSION
```

Para verificar los resultados, puede ejecutar la consulta SQL que se muestra en el siguiente ejemplo, que enumera las extensiones y sus propietarios. 

```
SELECT n.nspname AS "Name",
  pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner"
  FROM pg_catalog.pg_namespace n
  WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'
  ORDER BY 1;
List of schemas
     Name     |   Owner
--------------+-----------
 public       | postgres
 tiger        | rdsadmin
 tiger_data   | rdsadmin
 topology     | rdsadmin
(4 rows)
```

## Paso 3: transferir la propiedad de los esquemas de extensión
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferOwnership"></a>

Use las declaraciones de ALTER SCHEMA para transferir la propiedad de los esquemas al rol `gis_admin`.

```
ALTER SCHEMA tiger OWNER TO gis_admin;
ALTER SCHEMA
ALTER SCHEMA tiger_data OWNER TO gis_admin; 
ALTER SCHEMA
ALTER SCHEMA topology OWNER TO gis_admin;
ALTER SCHEMA
```

Si desea confirmar el cambio de propiedad, ejecute la siguiente consulta SQL. O bien, puede utilizar el metacomando `\dn` de la línea de comandos psql. 

```
SELECT n.nspname AS "Name",
  pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner"
  FROM pg_catalog.pg_namespace n
  WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'
  ORDER BY 1;

       List of schemas
     Name     |     Owner
--------------+---------------
 public       | postgres
 tiger        | gis_admin
 tiger_data   | gis_admin
 topology     | gis_admin
(4 rows)
```

## Paso 4: transferir la propiedad de las tablas de PostGIS
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferObjects"></a>

**nota**  
No cambie la propiedad de las funciones de PostGIS. Para que PostGIS funcione correctamente y reciba actualizaciones, estas funciones deben retener la propiedad original. Para obtener más información sobre los permisos de PostGIS, consulte [PostgreSQL Security](https://postgis.net/workshops/postgis-intro/security.html).

Use la siguiente función para transferir la propiedad de las tablas de PostGIS al rol `gis_admin`. Ejecute la siguiente declaración desde el símbolo del sistema psql para crear la función.

```
CREATE FUNCTION exec(text) returns text language plpgsql volatile AS $f$ BEGIN EXECUTE $1; RETURN $1; END; $f$;
CREATE FUNCTION
```

A continuación, ejecute la siguiente consulta para ejecutar la función `exec` que, a su vez, ejecuta las instrucciones y altera los permisos.

```
SELECT exec('ALTER TABLE ' || quote_ident(s.nspname) || '.' || quote_ident(s.relname) || ' OWNER TO gis_admin;')
  FROM (
    SELECT nspname, relname
    FROM pg_class c JOIN pg_namespace n ON (c.relnamespace = n.oid) 
    WHERE nspname in ('tiger','topology') AND
    relkind IN ('r','S','v') ORDER BY relkind = 'S')
s;
```

## Paso 5: pruebe las extensiones
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.Test"></a>

Para evitar tener que especificar el nombre del esquema, añada el esquema `tiger` a la ruta de búsqueda usando el siguiente comando.

```
SET search_path=public,tiger;
SET
```

Pruebe el esquema `tiger` usando la siguiente instrucción SELECT.

```
SELECT address, streetname, streettypeabbrev, zip
 FROM normalize_address('1 Devonshire Place, Boston, MA 02109') AS na;
address | streetname | streettypeabbrev |  zip
---------+------------+------------------+-------
       1 | Devonshire | Pl               | 02109
(1 row)
```

Para obtener más información sobre esta extensión, consulte [Tiger Geocoder](https://postgis.net/docs/Extras.html#Tiger_Geocoder) en la documentación de PostGIS. 

Pruebe el acceso al esquema `topology` usando la siguiente instrucción `SELECT`. Esto llama a la función `createtopology` para registrar un nuevo objeto de topología (my\$1new\$1topo) con el identificador de referencia espacial especificado (26986) y la tolerancia predeterminada (0,5). Para obtener más información, visite [CreateTopology](https://postgis.net/docs/CreateTopology.html) en la documentación de PostgreSQL. 

```
SELECT topology.createtopology('my_new_topo',26986,0.5);
 createtopology
----------------
              1
(1 row)
```

## Paso 6: Actualice la extensión de PostGIS
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.Update"></a>

Cada nueva versión de PostgreSQL admite una o más versiones de la extensión de PostGIS compatibles con esa versión. La actualización del motor de PostgreSQL a una nueva versión no actualiza automáticamente la extensión de PostGIS. Antes de actualizar el motor de PostgreSQL, normalmente se actualiza PostGIS a la versión más reciente disponible para la versión actual de PostgreSQL. Para obtener más información, consulte [Versiones de extensión PostGIS](#CHAP_PostgreSQL.Extensions.PostGIS). 

Después de actualizar el motor de PostgreSQL, vuelva a actualizar la extensión de PostGIS a la versión compatible con la versión del motor de PostgreSQL recién actualizada. Para obtener más información sobre la actualización del motor PostgreSQL, consulte [Realización de una actualización de la versión principal de RDS para PostgreSQL](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Process.md). 

Puede comprobar si hay disponibles actualizaciones de la versión de la extensión PostGIS en su instancia de base de datos de RDS para PostgreSQL en cualquier momento. Para ello, ejecute el siguiente comando. Esta función está disponible con PostGIS 2.5.0 y versiones posteriores.

```
SELECT postGIS_extensions_upgrade();
```

Si su aplicación no es compatible con la última versión de PostGIS, puede instalar una versión anterior de PostGIS que esté disponible en su versión principal de la siguiente manera.

```
CREATE EXTENSION postgis VERSION "2.5.5";
```

Si desea actualizar a una versión específica de PostGIS desde una versión anterior, también puede utilizar el siguiente comando.

```
ALTER EXTENSION postgis UPDATE TO "2.5.5";
```

Dependiendo de la versión desde la que se actualice, es posible que tenga que volver a utilizar esta función. El resultado de la primera ejecución de la función determina si se necesita una función de actualización adicional. Por ejemplo, eso es lo que ocurre para la actualización de PostGIS 2 a PostGIS 3. Para obtener más información, consulte [Actualización de PostGIS 2 a PostGIS 3](#PostgreSQL.Extensions.PostGIS.versions.upgrading.2-to-3).

Si actualizó esta extensión para prepararse para una actualización de la versión principal del motor de PostgreSQL, puede continuar con otras tareas preliminares. Para obtener más información, consulte [Realización de una actualización de la versión principal de RDS para PostgreSQL](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Process.md). 

## Versiones de extensión PostGIS
<a name="CHAP_PostgreSQL.Extensions.PostGIS"></a>

Le recomendamos que instale las versiones de todas las extensiones, como PostGIS, como se indica en [Versiones de extensión para Amazon RDS para PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html) en las *Notas de la versión de Amazon RDS para PostgreSQL* Para obtener una lista de las versiones que están disponibles en su versión, utilice el siguiente comando.

```
SELECT * FROM pg_available_extension_versions WHERE name='postgis';
```

Puede encontrar información sobre la versión en las siguientes secciones de las *Notas de la versión de Amazon RDS para PostgreSQL*:
+ [ Extensiones de PostgreSQL versión 16 admitidas en Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-16x)
+ [ Extensiones de PostgreSQL versión 15 admitidas en Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-15x)
+ [ Extensiones de PostgreSQL 14 admitidas en Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-14x)
+ [ Extensiones de PostgreSQL 13 admitidas en Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-13x)
+ [ Extensiones de PostgreSQL 12 admitidas en Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-12x)
+ [ Extensiones de PostgreSQL 11 admitidas en Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-11x)
+ [ Extensiones de PostgreSQL 10 admitidas en Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-101x)
+ [ Extensiones de PostgreSQL 9.6.x admitidas en Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-96x)

## Actualización de PostGIS 2 a PostGIS 3
<a name="PostgreSQL.Extensions.PostGIS.versions.upgrading.2-to-3"></a>

A partir de la versión 3.0, la funcionalidad de trama de PostGIS es una extensión separada, `postgis_raster`. Esta extensión tiene su propia ruta de instalación y actualización. Esto elimina del núcleo docenas de funciones, tipos de datos y otros artefactos necesarios para el procesamiento de imágenes de trama desde la extensión `postgis` principal. Esto significa que si su caso de uso no requiere procesamiento de tramas, no es necesario que instale la extensión `postgis_raster`.

En el siguiente ejemplo de actualización, el primer comando de actualización extrae la funcionalidad de trama en la extensión `postgis_raster`. Luego, se requiere un segundo comando de actualización para actualizar `postgis_raster` a la nueva versión.

**Para actualizar de PostGIS 2 a PostGIS 3**

1. Identifique la versión predeterminada de PostGIS que está disponible para la versión de PostgreSQL en su Instancia de base de datos RDS para PostgreSQL. Para ello, ejecute la siguiente consulta.

   ```
   SELECT * FROM pg_available_extensions
       WHERE default_version > installed_version;
     name   | default_version | installed_version |                          comment
   ---------+-----------------+-------------------+------------------------------------------------------------
    postgis | 3.1.4           | 2.3.7             | PostGIS geometry and geography spatial types and functions
   (1 row)
   ```

1. Identifique las versiones de PostGIS instaladas en cada base de datos en la instancia de base de datos de RDS para PostgreSQL. En otras palabras, consulte la base de datos de cada usuario de la siguiente manera.

   ```
   SELECT
       e.extname AS "Name",
       e.extversion AS "Version",
       n.nspname AS "Schema",
       c.description AS "Description"
   FROM
       pg_catalog.pg_extension e
       LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace
       LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid
       AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass
   WHERE
       e.extname LIKE '%postgis%'
   ORDER BY
       1;
     Name   | Version | Schema |                             Description
   ---------+---------+--------+---------------------------------------------------------------------
    postgis | 2.3.7   | public | PostGIS geometry, geography, and raster spatial types and functions
   (1 row)
   ```

   Esta falta de correspondencia entre la versión predeterminada (PostGIS 3.1.4) y la versión instalada (PostGIS 2.3.7) significa que debe actualizar la extensión de PostGIS.

   ```
   ALTER EXTENSION postgis UPDATE;
   ALTER EXTENSION
   WARNING: unpackaging raster
   WARNING: PostGIS Raster functionality has been unpackaged
   ```

1. Ejecute la siguiente consulta para comprobar que la funcionalidad ráster ahora está en su propio paquete.

   ```
   SELECT
       probin,
       count(*)
   FROM
       pg_proc
   WHERE
       probin LIKE '%postgis%'
   GROUP BY
       probin;
             probin          | count
   --------------------------+-------
    $libdir/rtpostgis-2.3    | 107
    $libdir/postgis-3        | 487
   (2 rows)
   ```

   El resultado muestra que aún hay una diferencia entre las versiones. Las funciones de PostGIS son de la versión 3 (postgis-3), mientras que las funciones ráster (rtpostgis) son de la versión 2 (rtpostgis-2.3). Para completar la actualización, vuelva a ejecutar el comando de actualización, como se indica a continuación.

   ```
   postgres=> SELECT postgis_extensions_upgrade();
   ```

   Puede ignorar los mensajes de advertencia sin problemas. Vuelva a ejecutar la siguiente consulta para comprobar que la actualización se ha completado. La actualización se completa cuando en PostGIS y en todas las extensiones relacionadas deja de aparecer una marca que indica que deben actualizarse. 

   ```
   SELECT postgis_full_version();
   ```

1. Utilice la siguiente consulta para ver el proceso de actualización completado y las extensiones empaquetadas por separado, y compruebe que las versiones coinciden. 

   ```
   SELECT
       e.extname AS "Name",
       e.extversion AS "Version",
       n.nspname AS "Schema",
       c.description AS "Description"
   FROM
       pg_catalog.pg_extension e
       LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace
       LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid
           AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass
   WHERE
       e.extname LIKE '%postgis%'
   ORDER BY
       1;
         Name      | Version | Schema |                             Description
   ----------------+---------+--------+---------------------------------------------------------------------
    postgis        | 3.1.5   | public | PostGIS geometry, geography, and raster spatial types and functions
    postgis_raster | 3.1.5   | public | PostGIS raster types and functions
   (2 rows)
   ```

   El resultado muestra que la extensión de PostGIS 2 se ha actualizado a PostGIS 3 y que ambas, `postgis`y la extensión `postgis_raster` ya separada, son de la versión 3.1.5.

Una vez completada esta actualización, si no tiene pensado usar la funcionalidad de trama, puede eliminar la extensión de la siguiente manera.

```
DROP EXTENSION postgis_raster;
```