

# Uso de autovacuum de PostgreSQL en Amazon RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum"></a>

Le recomendamos que use la característica autovacuum para mantener en buen estado su instancia de base de datos de PostgreSQL. Autovacuum automatiza el comienzo de los comandos VACUUM y ANALYZE. Comprueba las tablas con una gran cantidad de tuplas insertadas, actualizadas o eliminadas. Después de esta verificación, recupera el almacenamiento mediante la eliminación de datos obsoletos o tuplas de la base de datos de PostgreSQL.

De forma predeterminada, autovacuum está activado para las instancias de base de datos de RDS para PostgreSQL que crea por medio de cualquiera de los grupos de parámetros de base de datos de PostgreSQL predeterminados. Otros parámetros de configuración asociados con la característica autovacuum también se establecen de forma predeterminada. Debido a que estos valores predeterminados son algo genéricos, puede beneficiarse de ajustar algunos de los parámetros asociados con la característica autovacuum para su carga de trabajo específica. 

A continuación, puede encontrar más información sobre autovacuum y cómo ajustar algunos de sus parámetros en la instancia de base de datos de RDS para PostgreSQL. Para obtener información más específica, consulte [Prácticas recomendadas para trabajar con PostgreSQL](CHAP_BestPractices.md#CHAP_BestPractices.PostgreSQL).

**Topics**
+ [Asignación de memoria para autovacuum](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.WorkMemory)
+ [Reducción de la probabilidad de reinicio del identificador de transacción](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming)
+ [Determinar si las tablas de una base de datos necesitan vacío](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.NeedVacuuming.md)
+ [Determinar qué tablas cumplen actualmente los requisitos de autovacuum](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.EligibleTables.md)
+ [Determinar si autovacuum se está ejecutando actualmente y durante cuánto tiempo](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AutovacuumRunning.md)
+ [Realización de una inmovilización de vacío manual](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze.md)
+ [Reindexar una tabla cuando autovacuum se está ejecutando](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Reindexing.md)
+ [Administración de autovacuum con índices de gran tamaño](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.md)
+ [Otros parámetros que afectan a autovacuum](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.OtherParms.md)
+ [Establecimiento de parámetros autovacuum de nivel de tabla](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.TableParameters.md)
+ [Registro de actividades de autovacuum y vacuum](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Logging.md)
+ [Comportamiento de autovacuum con bases de datos no válidas](appendix.postgresql.commondbatasks.autovacuumbehavior.md)
+ [Identificación y resolución de los bloqueadores de vaciado intensivo en RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.md)

## Asignación de memoria para autovacuum
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.WorkMemory"></a>

Uno de los parámetros más importantes que afectan al desempeño de autovacuum es el parámetro [https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM). En las versiones 14 y anteriores de RDS para PostgreSQL, el parámetro `autovacuum_work_mem` se establece en -1, lo que indica que en su lugar se utiliza la configuración de `maintenance_work_mem`. En todas las demás versiones, `autovacuum_work_mem` se determina mediante GREATEST(\$1DBInstanceClassMemory/32768\$1, 65536).

Las operaciones de limpieza manual siempre utilizan la configuración de `maintenance_work_mem`, con la configuración predeterminada de GREATEST (\$1DBInstanceClassMemory/63963136\$11024\$1, 65536), y también se puede ajustar en la sesión mediante el comando `SET` para operaciones manuales de `VACUUM` más específicas.

`autovacuum_work_mem` determina que la memoria de autovacuum conserve los identificadores de tuplas inactivas (`pg_stat_all_tables.n_dead_tup`) para los índices de limpieza.

Cuando realice los cálculos para determinar el valor del parámetro `autovacuum_work_mem`, tenga en cuenta lo siguiente:
+ Si define el parámetro en un valor demasiado bajo, el proceso de limpieza puede tener que examinar la tabla varias veces para completar su trabajo. Esta variedad de análisis puede tener un impacto negativo en el rendimiento. Para instancias mayores, configurar `maintenance_work_mem` o `autovacuum_work_mem` a 1 GB como mínimo puede mejorar el rendimiento de las tablas de limpieza con un número elevado de tuplas inactivas. Sin embargo, en las versiones 16 y anteriores de PostgreSQL, el uso de memoria de la operación de limpieza está limitado a 1 GB, que es suficiente para procesar aproximadamente 179 millones de tuplas inactivas de una sola pasada. Si una tabla tiene más tuplas inactivas que las indicadas, la operación de limpieza tendrá que realizar varias pasadas por los índices de la tabla, lo que aumentará considerablemente el tiempo necesario. A partir de la versión 17 de PostgreSQL, no hay un límite de 1 GB y autovacuum puede procesar más de 179 millones de tuplas mediante árboles radix.

  Un identificador de tupla tiene un tamaño de 6 bytes. Con el fin de calcular la memoria necesaria para limpiar un índice de una tabla, realice una consulta a `pg_stat_all_tables.n_dead_tup` para buscar el número de tuplas inactivas y, a continuación, multiplique este número por 6 para determinar la memoria necesaria para limpiar el índice de una sola pasada. Puede utilizar la siguiente consulta:

  ```
  SELECT
      relname AS table_name,
      n_dead_tup,
      pg_size_pretty(n_dead_tup * 6) AS estimated_memory
  FROM
      pg_stat_all_tables
  WHERE
      relname = 'name_of_the_table';
  ```
+ El parámetro `autovacuum_work_mem` funciona en combinación con el parámetro `autovacuum_max_workers`. Cada empleado de `autovacuum_max_workers` puede utilizar la memoria que asigne. Si tiene demasiadas tablas pequeñas, asigne más `autovacuum_max_workers` y menos `autovacuum_work_mem`. Si tiene tablas grandes (de 100 GB o más), asigne más memoria y menos procesos de trabajo. Debe tener suficiente memoria asignada para que funcione en la tabla más grande. Por lo tanto, asegúrese de que la combinación de procesos de trabajo y memoria sea igual a la memoria total que desea asignar.

## Reducción de la probabilidad de reinicio del identificador de transacción
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming"></a>

En algunos casos, la configuración de grupos de parámetros relacionada con autovacuum puede no ser lo suficientemente agresiva como para evitar el reinicio del identificador de transacción. Para solucionar esto, RDS para PostgreSQL proporciona un mecanismo que adapta los valores de los parámetros de autovacuum automáticamente. *Autovacuum adaptativo* es una característica para RDS para PostgreSQL. Puede encontrar una explicación detallada sobre el [reinicio del identificador de transacción](https://www.postgresql.org/docs/current/static/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND) en la documentación de PostgreSQL. 

Autovacuum adaptativo está activado de forma predeterminada para las instancias de RDS para PostgreSQL con el parámetro dinámico `rds.adaptive_autovacuum` establecido en Activado. Le recomendamos encarecidamente que mantenga esta opción activada. Sin embargo, para apagar el ajuste de parámetros autovacuum adaptativo, establezca el parámetro `rds.adaptive_autovacuum` en 0 u OFF. 

El reinicio de ID de transacción sigue siendo posible incluso cuando Amazon RDS Amazon RDS ajusta los parámetros de autovacuum. Le animamos a implementar una alarma Amazon CloudWatch para el reinicio de identificador de transacción. Para obtener más información, consulte la publicación [Implement an early warning system for transaction ID wraparound in RDS for PostgreSQL](https://aws.amazon.com/blogs/database/implement-an-early-warning-system-for-transaction-id-wraparound-in-amazon-rds-for-postgresql/) (Implementar un sistema de alerta temprana para el ajuste de ID de transacción en RDS for PostgreSQL) en el Blog de Base de datos de AWS.

Con el ajuste de parámetros de autovacuum adaptable activado, Amazon RDS comienza a ajustar los parámetros de autovacuum cuando la métrica de CloudWatch `MaximumUsedTransactionIDs` alcanza el valor del parámetro `autovacuum_freeze_max_age` o 500 000 000, el que sea mayor. 

Amazon RDS continúa ajustando los parámetros para el autovacuum si una tabla continúa tendiendo hacia el ajuste de ID de transacción. Cada uno de estos ajustes dedica más recursos a autovacuum para evitar el reinicio. Amazon RDS actualiza los siguientes parámetros relacionados con autovacuum: 
+ [autovacuum\$1vacuum\$1cost\$1delay](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)
+ [ autovacuum\$1vacuum\$1cost\$1limit](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT)
+  [https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM) 
+  [autovacuum\$1naptime](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-NAPTIME) 

RDS modifica estos parámetros solo si el nuevo valor hace que autovacuum sea más agresivo. Estos parámetros se modifican en la memoria en la instancia de base de datos. Los valores en el grupo de parámetros no han cambiado. Para ver la configuración en memoria actual, utilice el comando de SQL PostgreSQL [SHOW](https://www.postgresql.org/docs/current/sql-show.html) de PostgreSQL. 

Cuando Amazon RDS modifica alguno de estos parámetros de autovacuum, genera un evento para la instancia de base de datos afectada. Este evento se puede ver en la Consola de administración de AWS y a través de la API de Amazon RDS. Una vez que la métrica CloudWatch `MaximumUsedTransactionIDs` vuelve por debajo del límite, Amazon RDS restablece los parámetros relacionados con el autovacuum en la memoria a los valores especificados en el grupo de parámetros. Luego, genera otro evento correspondiente a este cambio.

# Determinar si las tablas de una base de datos necesitan vacío
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.NeedVacuuming"></a>

Puede utilizar la siguiente consulta para mostrar el número de transacciones descongeladas en una base de datos. La columna `datfrozenxid` de una fila `pg_database` de una base de datos es un límite inferior en los identificadores de transacción normales que aparecen en esa base de datos. Esta columna es el mínimo de los valores `relfrozenxid` por tabla dentro de la base de datos. 

```
SELECT datname, age(datfrozenxid) FROM pg_database ORDER BY age(datfrozenxid) desc limit 20;
```

Por ejemplo, los resultados de ejecutar la consulta anterior podrían ser los siguientes.

```
datname    | age
mydb       | 1771757888
template0  | 1721757888
template1  | 1721757888
rdsadmin   | 1694008527
postgres   | 1693881061
(5 rows)
```

Cuando la antigüedad de una base de datos llega a los dos mil millones de identificadores de transacción, se produce el reinicio de los TransactionID (XID) y la base de datos cambia al modo de solo lectura. Puede usar esta consulta para generar una métrica y ejecutarla varias veces al día. De manera predeterminada, autovacuum está configurado para mantener la antigüedad de las transacciones en un máximo de 200,000,000 ([https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE)).

Una estrategia de monitorización de muestra podría ser la siguiente:
+ Establezca el valor `autovacuum_freeze_max_age` en 200 millones de transacciones.
+ Si una tabla llega a 500 millones de transacciones descongeladas, se dispara una alarma de gravedad baja. No es un valor disparatado, pero podría indicar que autovacuum no puede mantener el ritmo.
+ Si una tabla llega a mil millones, se debe interpretar como una alarma para adoptar medidas. En general, conviene mantener las antigüedades más cerca de `autovacuum_freeze_max_age` por motivos de rendimiento. Le recomendamos que investigue utilizando las recomendaciones que siguen.
+ Si una tabla llega a 1500 millones de transacciones sin vaciar, se dispara una alarma de gravedad alta. En función de la velocidad con la que la base de datos use los identificadores de transacción, esta alarma puede indicar que el sistema está agotando el tiempo para ejecutar autovacuum. En ese caso, le recomendamos una solución inmediata.

Si una tabla supera constantemente estos límites, modifique aún más sus parámetros de autovacuum. De manera predeterminada, usar VACUUM manualmente (que tiene deshabilitados los retardos basados en el costo) es un procedimiento más agresivo que usar el autovacuum predeterminado, pero es también más intrusivo para el sistema en su conjunto.

Le recomendamos lo siguiente:
+ Esté atento y active un mecanismo de supervisión para que esté al tanto de la antigüedad de sus transacciones.

  A fin de obtener información acerca de la creación de un proceso que advierta sobre el reinicio del ID de transacción, consulte la publicación de blog de la base de datos de AWS sobre la [implementación de un sistema de advertencia temprana para el reinicio de un ID de transacción en Amazon RDS for PostgreSQL](https://aws.amazon.com/blogs/database/implement-an-early-warning-system-for-transaction-id-wraparound-in-amazon-rds-for-postgresql/).
+ Para las tablas con más actividad, lleve a cabo una inmovilización manual de vacío con regularidad durante una ventana de mantenimiento además de confiar en autovacuum. Para obtener información acerca de la ejecución de una inmovilización de vacío manual, consulte [Realización de una inmovilización de vacío manual](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze.md).

# Determinar qué tablas cumplen actualmente los requisitos de autovacuum
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.EligibleTables"></a>

A menudo, hay una o dos tablas que necesitan vacío. Autovacuum se dirige siempre a las tablas cuyo valor `relfrozenxid` sea superior al número de transacciones en `autovacuum_freeze_max_age`. De lo contrario, si el número de tuplas obsoletas desde el último VACUUM supera el límite de vacío, la tabla se vacía.

El [umbral de autovacuum](https://www.postgresql.org/docs/current/static/routine-vacuuming.html#AUTOVACUUM) se define como:

```
Vacuum-threshold = vacuum-base-threshold + vacuum-scale-factor * number-of-tuples
```

donde el `vacuum base threshold` es `autovacuum_vacuum_threshold`, el `vacuum scale factor` es `autovacuum_vacuum_scale_factor` y el `number of tuples` es `pg_class.reltuples`.

Mientras está conectado a la base de datos, ejecute la siguiente consulta para ver una lista de tablas que autovacuum considera aptas para el vacío.

```
WITH vbt AS (SELECT setting AS autovacuum_vacuum_threshold FROM 
pg_settings WHERE name = 'autovacuum_vacuum_threshold'),
vsf AS (SELECT setting AS autovacuum_vacuum_scale_factor FROM 
pg_settings WHERE name = 'autovacuum_vacuum_scale_factor'), 
fma AS (SELECT setting AS autovacuum_freeze_max_age FROM pg_settings WHERE name = 'autovacuum_freeze_max_age'),
sto AS (select opt_oid, split_part(setting, '=', 1) as param,
split_part(setting, '=', 2) as value from (select oid opt_oid, unnest(reloptions) setting from pg_class) opt)
SELECT '"'||ns.nspname||'"."'||c.relname||'"' as relation,
pg_size_pretty(pg_table_size(c.oid)) as table_size,
age(relfrozenxid) as xid_age,
coalesce(cfma.value::float, autovacuum_freeze_max_age::float) autovacuum_freeze_max_age,
(coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) +
coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * c.reltuples)
AS autovacuum_vacuum_tuples, n_dead_tup as dead_tuples FROM
pg_class c join pg_namespace ns on ns.oid = c.relnamespace 
join pg_stat_all_tables stat on stat.relid = c.oid join vbt on (1=1) join vsf on (1=1) join fma on (1=1)
left join sto cvbt on cvbt.param = 'autovacuum_vacuum_threshold' and c.oid = cvbt.opt_oid 
left join sto cvsf on cvsf.param = 'autovacuum_vacuum_scale_factor' and c.oid = cvsf.opt_oid
left join sto cfma on cfma.param = 'autovacuum_freeze_max_age' and c.oid = cfma.opt_oid
WHERE c.relkind = 'r' and nspname <> 'pg_catalog'
AND (age(relfrozenxid) >= coalesce(cfma.value::float, autovacuum_freeze_max_age::float)
OR coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) + 
coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * 
c.reltuples <= n_dead_tup)
ORDER BY age(relfrozenxid) DESC LIMIT 50;
```

# Determinar si autovacuum se está ejecutando actualmente y durante cuánto tiempo
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AutovacuumRunning"></a>

Si necesita aspirar manualmente una tabla, asegúrese de determinar si el autovacuum se está ejecutando actualmente. Si es así, es posible que deba ajustar los parámetros para que funcione de manera más eficiente o desactivar el autovacuum temporalmente para que pueda ejecutar manualmente VACUUM.

Use la siguiente consulta para determinar si se está ejecutando autovacuum, cuánto tiempo lleva en ejecución y si se encuentra en espera en otra sesión. 

```
SELECT datname, usename, pid, state, wait_event, current_timestamp - xact_start AS xact_runtime, query
FROM pg_stat_activity 
WHERE upper(query) LIKE '%VACUUM%' 
ORDER BY xact_start;
```

Después de ejecutar la consulta, debería ver un resultado similar al siguiente.

```
 datname | usename  |  pid  | state  | wait_event |      xact_runtime       | query  
 --------+----------+-------+--------+------------+-------------------------+--------------------------------------------------------------------------------------------------------
 mydb    | rdsadmin | 16473 | active |            | 33 days 16:32:11.600656 | autovacuum: VACUUM ANALYZE public.mytable1 (to prevent wraparound)
 mydb    | rdsadmin | 22553 | active |            | 14 days 09:15:34.073141 | autovacuum: VACUUM ANALYZE public.mytable2 (to prevent wraparound)
 mydb    | rdsadmin | 41909 | active |            | 3 days 02:43:54.203349  | autovacuum: VACUUM ANALYZE public.mytable3
 mydb    | rdsadmin |   618 | active |            | 00:00:00                | SELECT datname, usename, pid, state, wait_event, current_timestamp - xact_start AS xact_runtime, query+
         |          |       |        |            |                         | FROM pg_stat_activity                                                                                 +
         |          |       |        |            |                         | WHERE query like '%VACUUM%'                                                                           +
         |          |       |        |            |                         | ORDER BY xact_start;                                                                                  +
```

Existen varios problemas que pueden provocar una sesión de autovaccum de larga duración (es decir, que tarde varios días). El problema más común es que el valor del parámetro [https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) sea demasiado bajo para el tamaño de la tabla o la velocidad de las actualizaciones. 

Le recomendamos que utilice la siguiente fórmula para establecer el valor del parámetro `maintenance_work_mem`.

```
GREATEST({DBInstanceClassMemory/63963136*1024},65536)
```

Las sesiones de autovacuum con una duración corta también pueden indicar problemas:
+ Pueden indicar que no hay un número de `autovacuum_max_workers` suficientemente alto para la carga de trabajo. En ese caso, tendrá que especificar el número de procesos de trabajo.
+ Puede indicar que hay una corrupción de índice (autovacuum falla y se reinicia en la misma relación pero no avanza). En este caso, ejecute un manual `vacuum freeze verbose table` para ver la causa exacta. 

# Realización de una inmovilización de vacío manual
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze"></a>

Puede ocurrir que desee realizar una operación de vacío manual en una tabla que ya tenga un proceso de vacío en ejecución. Esto resulta útil si se ha identificado una tabla con una antigüedad cercana a dos mil millones de transacciones (o por encima del umbral que esté monitorizando).

Los siguientes pasos son pautas, con varias variaciones en el proceso. Por ejemplo, durante las pruebas, suponga que descubre que el parámetro [https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) se definió en un valor demasiado bajo y que tiene que adoptar medidas de forma inmediata en una tabla. Sin embargo, quizás no desea rebotar la instancia en ese momento. Con las consultas de las secciones anteriores, puede determinar qué tabla está causando el problema y comprobar que hay una sesión de autovacuum que lleva mucho tiempo en ejecución. Sabe que tiene que cambiar el ajuste del parámetro `maintenance_work_mem`, pero también tiene que adoptar medidas de inmediato y aplicar el vacío en la tabla afectada. El siguiente procedimiento muestra qué hacer en esa situación.

**Para realizar manualmente una inmovilización de vacío**

1. Abra dos sesiones en la base de datos que contiene la tabla en la que desea ejecutar el vacío. Para la segunda sesión, use "screen" u otra utilidad que mantenga la sesión activa si se interrumpe la conexión.

1. En la sesión uno, obtenga el ID de proceso (PID) de la sesión de autovacuum que se ejecuta en la tabla. 

   Ejecute la siguiente consulta para obtener el PID de la sesión de autovacuum.

   ```
   SELECT datname, usename, pid, current_timestamp - xact_start 
   AS xact_runtime, query
   FROM pg_stat_activity WHERE upper(query) LIKE '%VACUUM%' ORDER BY 
   xact_start;
   ```

1. En la sesión dos, calcule la cantidad de memoria que necesitará para esta operación. En este ejemplo, determinamos que podemos permitirnos usar un máximo de 2 GB de memoria para esta operación y, por tanto, definimos [https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) en 2 GB para la sesión actual.

   ```
   SET maintenance_work_mem='2 GB';
   SET
   ```

1. En la sesión dos, ejecute el comando `vacuum freeze verbose` para la tabla. El ajuste de informe detallado resulta útil porque, aunque PostgreSQL no ofrece actualmente un informe de progreso para esto, se puede ver la actividad.

   ```
   \timing on
   Timing is on.
   vacuum freeze verbose pgbench_branches;
   ```

   ```
   INFO:  vacuuming "public.pgbench_branches"
   INFO:  index "pgbench_branches_pkey" now contains 50 row versions in 2 pages
   DETAIL:  0 index row versions were removed.
   0 index pages have been deleted, 0 are currently reusable.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   INFO:  index "pgbench_branches_test_index" now contains 50 row versions in 2 pages
   DETAIL:  0 index row versions were removed.
   0 index pages have been deleted, 0 are currently reusable.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   INFO:  "pgbench_branches": found 0 removable, 50 nonremovable row versions 
        in 43 out of 43 pages
   DETAIL:  0 dead row versions cannot be removed yet.
   There were 9347 unused item pointers.
   0 pages are entirely empty.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   VACUUM
   Time: 2.765 ms
   ```

1. En la sesión uno, si la limpieza automática bloqueaba la sesión de vacío, `pg_stat_activity` muestra que la espera es `T` para la sesión de vacío. En este caso, finalice el proceso de limpieza automática de la siguiente manera.

   ```
   SELECT pg_terminate_backend('the_pid'); 
   ```
**nota**  
Algunas versiones anteriores de Amazon RDS no pueden finalizar un proceso de limpieza automática mediante el comando anterior y producen el siguiente error: `ERROR: 42501: must be a superuser to terminate superuser process LOCATION: pg_terminate_backend, signalfuncs.c:227`. 

   En este punto, comienza la sesión. La limpieza automática se reinicia inmediatamente, ya que esta tabla es probablemente la que ocupa una posición más alta en la lista de trabajo. 

1. Inicie el comando `vacuum freeze verbose` en la sesión dos y luego finalice el proceso de autovacuum en la sesión uno.

# Reindexar una tabla cuando autovacuum se está ejecutando
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Reindexing"></a>

Si un índice se ha dañado, autovacuum seguirá procesando la tabla y generará errores. Si intenta realizar un vacío manual en esta situación, recibirá un mensaje de error como el siguiente.

```
postgres=>  vacuum freeze pgbench_branches;
ERROR: index "pgbench_branches_test_index" contains unexpected 
   zero page at block 30521
HINT: Please REINDEX it.
```

Cuando el índice está dañado y autovacuum intenta ejecutarse en la tabla, se enfrenta a una sesión de autovacuum que ya se está ejecutando. Cuando ejecuta un comando [REINDEX](https://www.postgresql.org/docs/current/static/sql-reindex.html), elimina un bloqueo exclusivo en la tabla. Las operaciones de escritura están bloqueadas y también las operaciones de lectura que usan ese índice específico.

**Para reindexar una tabla cuando autovacuum se está ejecutando en ella**

1. Abra dos sesiones en la base de datos que contiene la tabla que desea vaciar. Para la segunda sesión, use "screen" u otra utilidad que mantenga la sesión activa si se interrumpe la conexión.

1. En la sesión uno, obtenga el PID de la sesión de autovacuum que se ejecuta en la tabla.

   Ejecute la siguiente consulta para obtener el PID de la sesión de autovacuum.

   ```
   SELECT datname, usename, pid, current_timestamp - xact_start 
   AS xact_runtime, query
   FROM pg_stat_activity WHERE upper(query) like '%VACUUM%' ORDER BY 
   xact_start;
   ```

1. En la sesión dos, ejecute el comando reindex.

   ```
   \timing on
   Timing is on.
   reindex index pgbench_branches_test_index;
   REINDEX
     Time: 9.966 ms
   ```

1. En la sesión uno, si autovacuum estaba bloqueando, verá en `pg_stat_activity` que la espera es “T” para su sesión de vacío. En este caso, terminará el proceso de autovacuum. 

   ```
   SELECT pg_terminate_backend('the_pid');
   ```

   En este punto, comienza la sesión. Es importante tener en cuenta que autovacuum se reiniciará inmediatamente, ya que esta tabla es probablemente la que ocupa una posición más alta en su lista de trabajo. 

1. Inicie el comando en la sesión dos y termine a continuación el proceso de autovacuum de la sesión 1.

# Administración de autovacuum con índices de gran tamaño
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes"></a>

Como parte de su funcionamiento, *autovacuum* realiza varias [fases de vaciado](https://www.postgresql.org/docs/current/progress-reporting.html#VACUUM-PHASES) mientras se ejecuta en una tabla. Antes de limpiar la tabla, primero se vacían todos sus índices. Al eliminar varios índices de gran tamaño, esta fase consume una cantidad importante de tiempo y recursos. Por lo tanto, como práctica recomendada, asegúrese de controlar el número de índices de una tabla y eliminar los no utilizados.

Para este proceso, compruebe primero el tamaño general del índice. A continuación, determine si hay índices que es posible que no se utilicen y que se puedan eliminar, tal y como se muestra en los siguientes ejemplos.

**Para comprobar el tamaño de la tabla y sus índices**

```
postgres=> select pg_size_pretty(pg_relation_size('pgbench_accounts'));
pg_size_pretty
6404 MB
(1 row)
```

```
postgres=> select pg_size_pretty(pg_indexes_size('pgbench_accounts'));
pg_size_pretty
11 GB
(1 row)
```

En este ejemplo, el tamaño de los índices es mayor que el de la tabla. Esta diferencia puede provocar problemas de rendimiento, ya que los índices están sobrecargados o no se utilizan, lo que afecta a las operaciones de autovacuum y de inserción.

**Para comprobar si hay índices no utilizados**

En la vista [https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ALL-INDEXES-VIEW](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ALL-INDEXES-VIEW), puede comprobar la frecuencia con la que se utiliza un índice con la columna `idx_scan`. En el siguiente ejemplo, los índices no utilizados tienen el valor `0` en `idx_scan`.

```
postgres=> select * from pg_stat_user_indexes where relname = 'pgbench_accounts' order by idx_scan desc;
    
relid  | indexrelid | schemaname | relname          | indexrelname          | idx_scan | idx_tup_read | idx_tup_fetch
-------+------------+------------+------------------+-----------------------+----------+--------------+---------------
16433  | 16454      | public     | pgbench_accounts | index_f               | 6        | 6            | 0
16433  | 16450      | public     | pgbench_accounts | index_b               | 3        | 199999       | 0
16433  | 16447      | public     | pgbench_accounts | pgbench_accounts_pkey | 0        | 0            | 0
16433  | 16452      | public     | pgbench_accounts | index_d               | 0        | 0            | 0
16433  | 16453      | public     | pgbench_accounts | index_e               | 0        | 0            | 0
16433  | 16451      | public     | pgbench_accounts | index_c               | 0        | 0            | 0
16433  | 16449      | public     | pgbench_accounts | index_a               | 0        | 0            | 0
(7 rows)
```

```
postgres=> select schemaname, relname, indexrelname, idx_scan from pg_stat_user_indexes where relname = 'pgbench_accounts' order by idx_scan desc;
    
schemaname  | relname          | indexrelname          | idx_scan
------------+------------------+-----------------------+----------
public      | pgbench_accounts | index_f               | 6
public      | pgbench_accounts | index_b               | 3
public      | pgbench_accounts | pgbench_accounts_pkey | 0
public      | pgbench_accounts | index_d               | 0
public      | pgbench_accounts | index_e               | 0
public      | pgbench_accounts | index_c               | 0
public      | pgbench_accounts | index_a               | 0
(7 rows)
```

**nota**  
Estas estadísticas son incrementales desde el momento en que se restablecen las estadísticas. Supongamos que tiene un índice que solo se usa al final de un trimestre empresarial o solo para un informe específico. Es posible que este índice no se haya utilizado desde que se restablecieron las estadísticas. Para obtener más información, consulte [Statistics Functions](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-STATS-FUNCTIONS) (Funciones de estadísticas). Los índices que se utilizan para garantizar la exclusividad no se analizan y no se deben identificar como índices no utilizados. Para identificar los índices no utilizados, debe tener un conocimiento profundo de la aplicación y sus consultas.

Para comprobar cuándo se restablecieron por última vez las estadísticas de una base de datos, utilice [ https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW]( https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW)

```
postgres=> select datname, stats_reset from pg_stat_database where datname = 'postgres';
    
datname   | stats_reset
----------+-------------------------------
postgres  | 2022-11-17 08:58:11.427224+00
(1 row)
```

## Vaciado de una tabla lo más rápido posible
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.Executing"></a>

**RDS para PostgreSQL 12 y versiones posteriores**

Si tiene demasiados índices en una tabla grande, la instancia de base de datos podría estar a punto de reiniciar el identificador de transacción (XID), que es cuando el contador de XID vuelve a ponerse en cero. Si esta casilla no se marca, esta situación podría provocar la pérdida de datos. Sin embargo, puede vaciar rápidamente la tabla sin limpiar los índices. En RDS para PostgreSQL 12 y versiones posteriores, puede usar VACUUM con la cláusula [https://www.postgresql.org/docs/current/sql-vacuum.html](https://www.postgresql.org/docs/current/sql-vacuum.html).

```
postgres=> VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) pgbench_accounts;
        
INFO: vacuuming "public.pgbench_accounts"
INFO: table "pgbench_accounts": found 0 removable, 8 nonremovable row versions in 1 out of 819673 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 7517
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.01 s, system: 0.00 s, elapsed: 0.01 s.
```

Si ya se está ejecutando una sesión de autovacuum, debe finalizarla para iniciar VACUUM manualmente. Para obtener información acerca de la ejecución de una inmovilización de vacío manual, consulte [Realización de una inmovilización de vacío manual](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze.md).

**nota**  
Omitir la limpieza de índices con regularidad causa una sobrecarga de los índices, lo que degrada el rendimiento del análisis. El índice retiene las filas inactivas y la tabla retiene los punteros de línea inactivos. Como resultado, `pg_stat_all_tables.n_dead_tup` aumenta hasta que se ejecuta el vaciado automático o una operación VACUUM manual con limpieza de índices. Como práctica recomendada, use este procedimiento solo para impedir que el identificador se reinicie.

**RDS para PostgreSQL 11 y versiones anteriores**

Sin embargo, en RDS para PostgreSQL 11 y versiones anteriores, la única forma de hacer que el vacío se realice más rápidamente es reducir el número de índices de una tabla. La eliminación de un índice puede afectar a los planes de consulta. Le recomendamos que primero borre los índices no utilizados y, a continuación, los índices cuando el reinicio de XID sea inminente. Una vez finalizado el proceso de vaciado, puede volver a crear estos índices.

# Otros parámetros que afectan a autovacuum
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.OtherParms"></a>

La siguiente consulta mostrará los valores de algunos de los parámetros que afectan directamente a autovacuum y a su comportamiento. Los [parámetros de autovacuum](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html) se describen en detalle en la documentación de PostgreSQL.

```
SELECT name, setting, unit, short_desc
FROM pg_settings
WHERE name IN (
'autovacuum_max_workers',
'autovacuum_analyze_scale_factor',
'autovacuum_naptime',
'autovacuum_analyze_threshold',
'autovacuum_analyze_scale_factor',
'autovacuum_vacuum_threshold',
'autovacuum_vacuum_scale_factor',
'autovacuum_vacuum_threshold',
'autovacuum_vacuum_cost_delay',
'autovacuum_vacuum_cost_limit',
'vacuum_cost_limit',
'autovacuum_freeze_max_age',
'maintenance_work_mem',
'vacuum_freeze_min_age');
```

Aunque todos estos parámetros afectan a autovacuum, estos son algunos de los más importantes:
+ [maintenance\$1work\$1mem](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE_WORK_MEM)
+ [autovacuum\$1freeze\$1max\$1age](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE)
+ [autovacuum\$1max\$1workers](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-MAX-WORKERS)
+ [autovacuum\$1vacuum\$1cost\$1delay](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)
+ [autovacuum\$1vacuum\$1cost\$1limit](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT)

# Establecimiento de parámetros autovacuum de nivel de tabla
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.TableParameters"></a>

Los [parámetros de almacenamiento](https://www.postgresql.org/docs/current/static/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS) relacionados con autovacuum se pueden definir en el nivel de tabla, algo que puede resultar mejor que alterar el comportamiento de toda la base de datos. Para las tablas grandes, podría ser necesario definir unos ajustes agresivos, y es posible que no sea deseable que autovacuum se comporte de esa forma para todas las tablas.

La siguiente consulta mostrará qué tablas tienen habilitadas actualmente las opciones de nivel de tabla.

```
SELECT relname, reloptions
FROM pg_class
WHERE reloptions IS NOT null;
```

Un ejemplo en el que esto puede resultar útil es el de las tablas que son mucho más grandes que el resto de las tablas. Supongamos que dispone de una tabla de 300 GB y otras 30 tablas inferior a 1 GB. En ese caso, podría definir algunos parámetros concretos para la tabla grande con el fin de evitar alterar el comportamiento de todo el sistema.

```
ALTER TABLE mytable set (autovacuum_vacuum_cost_delay=0);
```

Al hacer esto, desactiva el retraso de autovacuum basado en costos para esta tabla a expensas de un mayor uso de recursos en su sistema. Normalmente, autovacuum hace una pausa por `autovacuum_vacuum_cost_delay` cada vez que se alcanza `autovacuum_cost_limit`. En la documentación de PostgreSQL, puede obtener información detallada relativa al [vacío basado en el costo](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST).

# Registro de actividades de autovacuum y vacuum
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Logging"></a>

La información sobre las actividades de autovacuum se envía a `postgresql.log` basado en el nivel especificado en el parámetro `rds.force_autovacuum_logging_level`. Los siguientes son los valores permitidos para este parámetro y las versiones de PostgreSQL para las que ese valor es la configuración predeterminada:
+ `disabled` (PostgreSQL 10, PostgreSQL 9.6)
+ `debug5`, `debug4`, `debug3`, `debug2`, `debug1`
+ `info` (PostgreSQL 12, PostgreSQL 11)
+ `notice`
+ `warning` (PostgreSQL 13 y versiones posteriores)
+ `error`, registro, `fatal`, `panic`

`rds.force_autovacuum_logging_level` funciona con el parámetro `log_autovacuum_min_duration`. El valor del parámetro `log_autovacuum_min_duration` es el límite (en milisegundos) por encima del cual se registran las acciones de autovacuum. Una configuración de `-1` no registra nada, mientras que una configuración de 0 registra todas las acciones. Al igual que con `rds.force_autovacuum_logging_level`, los valores predeterminados para `log_autovacuum_min_duration` dependen de la versión, como se indica a continuación: 
+ `10000 ms`: PostgreSQL 14, PostgreSQL 13, PostgreSQL 12 y PostgreSQL 11 
+ `(empty)`: no hay valor predeterminado para PostgreSQL 10 y PostgreSQL 9.6

Es recomendable que defina `rds.force_autovacuum_logging_level` como `WARNING`. También recomendamos configurar `log_autovacuum_min_duration` a un valor de 1000 a 5000. Una configuración de 5000 registra la actividad que tarda más de 5000 milisegundos. Cualquier configuración que no sea -1 también registra mensajes si la acción de autovaccum se omite debido a un bloqueo en conflicto o relaciones eliminadas al mismo tiempo. Para más información, visite [Automatic Vacuuming](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html) (Vacío automático) en la documentación de PostgreSQL. 

Para solucionar problemas, puede cambiar el parámetro `rds.force_autovacuum_logging_level` a uno de los niveles de depuración, desde `debug1` hasta `debug5` para obtener la información más detallada. Le recomendamos que utilice la configuración de depuración durante periodos cortos y solo con el objetivo de solucionar problemas. Para más información, visite [When to log](https://www.postgresql.org/docs/current/static/runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHEN) (Cuándo registrarse) en la documentación de PostgreSQL. 

**nota**  
PostgreSQL permite a la cuenta `rds_superuser` consultar sesiones de autovacuum en `pg_stat_activity`. Por ejemplo, podrá identificar y finalizar una sesión de autovacuum que bloquea la ejecución de un comando o que hace que se ejecute más despacio que un comando de vacío emitido manualmente.

# Comportamiento de autovacuum con bases de datos no válidas
<a name="appendix.postgresql.commondbatasks.autovacuumbehavior"></a>

 Se introduce un nuevo valor `-2` en la columna `datconnlimit` del catálogo `pg_database` para indicar que las bases de datos interrumpidas en mitad de la operación DROP DATABASE no son válidas. 

 Este nuevo valor está disponible en las siguientes versiones de RDS para PostgreSQL: 
+ Versión 15.4 y todas las versiones posteriores
+ Versión 14.9 y posteriores
+ Versión 13.12 y posteriores
+ Versión 12.16 y posteriores
+ Versión 11.21 y posteriores

Las bases de datos no válidas no afectan a la capacidad de autovacuum de bloquear la funcionalidad de las bases de datos válidas. Autovacuum ignora las bases de datos no válidas. Por lo tanto, las operaciones vacuum habituales seguirán funcionando de forma adecuada y eficiente en todas las bases de datos válidas de su entorno de PostgreSQL.

**Topics**
+ [Supervisión del ID de transacción](#appendix.postgresql.commondbatasks.autovacuum.monitorxid)
+ [Ajustes en la consulta de supervisión](#appendix.postgresql.commondbatasks.autovacuum.monitoradjust)
+ [Resolución de problemas relacionados con bases de datos no válidas](#appendix.postgresql.commondbatasks.autovacuum.connissue)

## Supervisión del ID de transacción
<a name="appendix.postgresql.commondbatasks.autovacuum.monitorxid"></a>

 La función `age(datfrozenxid)` se suele utilizar para supervisar la antigüedad del ID de transacción (XID) de las bases de datos a fin de evitar que este se reinicie. 

 Como las bases de datos no válidas se excluyen del autovacuum, su contador de ID de transacción (XID) puede alcanzar el valor máximo de `2 billion`, reiniciarse en `- 2 billion` y continuar este ciclo indefinidamente. Una consulta típica para supervisar el reinicio del ID de transacción podría ser así: 

```
SELECT max(age(datfrozenxid)) FROM pg_database;
```

Sin embargo, al introducir el valor -2 para `datconnlimit`, las bases de datos no válidas pueden sesgar los resultados de esta consulta. Como estas bases de datos no son válidas y no deberían formar parte de las comprobaciones de mantenimiento periódicas, pueden provocar falsos positivos y dar la impresión de que `age(datfrozenxid)` es mayor de lo que realmente es.

## Ajustes en la consulta de supervisión
<a name="appendix.postgresql.commondbatasks.autovacuum.monitoradjust"></a>

 Para garantizar una supervisión precisa, debe ajustar la consulta de supervisión a fin de excluir las bases de datos no válidas. Siga esta consulta recomendada: 

```
SELECT
    max(age(datfrozenxid))
FROM
    pg_database
WHERE
    datconnlimit <> -2;
```

Esta consulta garantiza que solo se tengan en cuenta las bases de datos válidas en el cálculo de `age(datfrozenxid)`, lo que aporta información fiable sobre la antigüedad del ID de transacción en todo el entorno de PostgreSQL.

## Resolución de problemas relacionados con bases de datos no válidas
<a name="appendix.postgresql.commondbatasks.autovacuum.connissue"></a>

 Al intentar conectarse a una base de datos no válida, es posible que vea un mensaje de error similar al siguiente: 

```
postgres=> \c db1
connection to server at "mydb.xxxxxxxxxx.us-west-2.rds.amazonaws.com" (xx.xx.xx.xxx), port xxxx failed: FATAL:  cannot connect to invalid database "db1"
HINT:  Use DROP DATABASE to drop invalid databases.
Previous connection kept
```

 Además, si el parámetro `log_min_messages` tiene un valor igual o superior a `DEBUG2`, es posible que vea que las siguientes entradas de registro muestran que el proceso de autovacuum omite la base de datos no válida: 

```
       
2024-07-30 05:59:00 UTC::@:[32000]:DEBUG:  autovacuum: skipping invalid database "db6"
2024-07-30 05:59:00 UTC::@:[32000]:DEBUG:  autovacuum: skipping invalid database "db1"
```

Para resolver el problema, siga la `HINT` proporcionada durante el intento de conexión. Conéctese a cualquier base de datos válida mediante su cuenta maestra de RDS o una cuenta de base de datos con el rol `rds_superuser` y elimine las bases de datos no válidas.

```
SELECT
    'DROP DATABASE ' || quote_ident(datname) || ';'
FROM
    pg_database
WHERE
    datconnlimit = -2 \gexec
```

# Identificación y resolución de los bloqueadores de vaciado intensivo en RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring"></a>

En PostgreSQL, la limpieza es fundamental para garantizar el buen estado de la base de datos, ya que recupera espacio de almacenamiento y evita problemas relacionados con los [identificadores de transacciones](https://www.postgresql.org/docs/current/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND). Sin embargo, hay situaciones que pueden impedir que el vaciado funcione como es debido, lo que puede mermar el rendimiento, provocar una sobrecarga de almacenamiento e incluso afectar a la disponibilidad de la instancia de base de datos debido a la superposición de ID de transacción. Por lo tanto, identificar y resolver estos problemas es esencial para lograr un rendimiento y una disponibilidad óptimos de la base de datos. Consulte [Understanding autovacuum in Amazon RDS for PostgreSQL environments](https://aws.amazon.com/blogs/database/understanding-autovacuum-in-amazon-rds-for-postgresql-environments/) si desea conocer mejor la limpieza automática.

La función `postgres_get_av_diag()` ayuda a identificar los problemas que impiden o retrasan el avance de la limpieza agresiva. Se proporcionan sugerencias, entre otras, comandos para resolver el problema si es identificable o indicaciones para realizar diagnósticos adicionales cuando no se puede identificar el problema. Los bloqueadores de limpieza agresiva aparecen cuando su antigüedad supera el umbral de [vacío automático adaptativo](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming) establecido por RDS, que es de 500 millones de identificadores de transacciones.

**Qué antigüedad tiene el identificador de la transacción?**

La función `age()` de identificadores de transacción calcula el número de transacciones que se han producido desde el identificador de transacción descongelado más antiguo de una base de datos (`pg_database.datfrozenxid`) o tabla (`pg_class.relfrozenxid`). Este valor indica la actividad de la base de datos desde la última operación de limpieza agresiva y resalta la carga de trabajo probable para los próximos procesos de LIMPIEZA. 

**Qué es una limpieza agresiva?**

Una operación de LIMPIEZA agresiva lleva a cabo un escaneo exhaustivo de todas las páginas de una tabla, incluidas las que normalmente se omiten durante las limpiezas normales. Este análisis exhaustivo tiene como objetivo congelar los ID de transacción que se acercan a su antigüedad máxima, evitando de forma eficaz una situación conocida como [superposición de identificadores de transacción](https://www.postgresql.org/docs/current/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND).

Para que `postgres_get_av_diag()` pueda detectar bloqueadores, el bloqueador debe haber realizado al menos 500 millones de transacciones.

**Topics**
+ [Instalación de herramientas de supervisión y diagnóstico de autovacuum en RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Installation.md)
+ [Funciones de postgres\$1get\$1av\$1diag() en RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Functions.md)
+ [Resolución de bloqueadores de vaciado identificables en RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md)
+ [Resolución de bloqueadores de vaciado no identificables en RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Unidentifiable_blockers.md)
+ [Resolución de problemas de rendimiento de vaciado en RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Performance.md)
+ [Explicación de los mensajes de tipo NOTICE en RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE.md)

# Instalación de herramientas de supervisión y diagnóstico de autovacuum en RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Installation"></a>

La función `postgres_get_av_diag()` está disponible actualmente en las siguientes versiones de RDS para PostgreSQL:
+ Versión 17.2 y otras versiones 17 superiores
+ Versión 16.7 y otras versiones 16 superiores
+ Versión 15.11 y otras versiones 15 superiores
+ Versión 14.16 y otras versiones 14 superiores
+ Versión 13.19 y otras versiones 13 superiores

 Para utilizar `postgres_get_av_diag()`, cree la extensión `rds_tools`.

```
postgres=> CREATE EXTENSION rds_tools ;
CREATE EXTENSION
```

Compruebe que la extensión esté instalada.

```
postgres=> \dx rds_tools
             List of installed extensions
   Name    | Version |  Schema   |                    Description
 ----------+---------+-----------+----------------------------------------------------------
 rds_tools |   1.8   | rds_tools | miscellaneous administrative functions for RDS PostgreSQL
 1 row
```

Compruebe que la función se haya creado.

```
postgres=> SELECT
    proname function_name,
    pronamespace::regnamespace function_schema,
    proowner::regrole function_owner
FROM
    pg_proc
WHERE
    proname = 'postgres_get_av_diag';
    function_name     | function_schema | function_owner
----------------------+-----------------+----------------
 postgres_get_av_diag | rds_tools       | rds_superuser
(1 row)
```

# Funciones de postgres\$1get\$1av\$1diag() en RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Functions"></a>

La función `postgres_get_av_diag()` recupera información de diagnóstico sobre los procesos de autovacuum que se bloquean o se retrasan en una base de datos de RDS para PostgreSQL. La consulta debe ejecutarse en la base de datos con el ID de transacción más antiguo para obtener resultados precisos. Para obtener más información sobre el uso de la base de datos con el ID de transacción más antiguo, consulte [Not connected to the database with the age of oldest transaction ID](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE.md)

```
SELECT
    blocker,
    DATABASE,
    blocker_identifier,
    wait_event,
    TO_CHAR(autovacuum_lagging_by, 'FM9,999,999,999') AS autovacuum_lagging_by,
    suggestion,
    suggested_action
FROM (
    SELECT
        *
    FROM
        rds_tools.postgres_get_av_diag ()
    ORDER BY
        autovacuum_lagging_by DESC) q;
```

La función `postgres_get_av_diag()` devuelve una tabla con la siguiente información:

**blocker**  
Especifica la categoría de actividad de la base de datos que bloquea el vaciado.  
+ [Instrucción activa](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Active_statement)
+ [Inactividad en la transacción](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Idle_in_transaction)
+ [Transacción preparada](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Prepared_transaction)
+ [Ranura de replicación lógica](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Logical_replication_slot)
+ [Réplica de lectura con ranura de replicación física](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas)
+ [Réplica de lectura con replicación de streaming](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas)
+ [Tablas temporales](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Temporary_tables)

**database**  
Especifica el nombre de la base de datos, si está disponible y es compatible. Esta es la base de datos en la que la actividad está en curso y bloquea o bloqueará el autovacuum. Esta es la base de datos a la que debe conectarse y sobre la que debe actuar.

**blocker\$1identifier**  
Especifica el identificador de la actividad que bloquea o bloqueará el autovacuum. El identificador puede ser un ID de proceso junto con una instrucción SQL, una transacción preparada, una dirección IP de una réplica de lectura y el nombre de la ranura de replicación, ya sea lógica o física.

**wait\$1event**  
Especifica el [evento de espera](PostgreSQL.Tuning.md) de la sesión de bloqueo y se aplica a los siguientes bloqueadores:  
+ Instrucción activa
+ Inactividad en la transacción

**autovacum\$1lagging\$1by**  
Especifica el número de transacciones que tiene pendiente el autovacuum según sus trabajos por realizar y por categoría.

**suggestion**  
Especifica sugerencias para resolver el bloqueo. Estas instrucciones incluyen el nombre de la base de datos en la que existe la actividad, cuando proceda, el ID de proceso (PID) de la sesión, cuando proceda, y la acción que se debe realizar.

**suggested\$1action**  
Sugiere la acción que se debe llevar a cabo para resolver el bloqueo.

# Resolución de bloqueadores de vaciado identificables en RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers"></a>

Autovacuum lleva a cabo vaciados de forma intensiva y reduce la antigüedad de los ID de transacción hasta situarlos por debajo del umbral especificado por el parámetro `autovacuum_freeze_max_age` de la instancia de RDS. Esta antigüedad se puede consultar mediante la métrica `MaximumUsedTransactionIDs` de Amazon CloudWatch.

Para encontrar la configuración de `autovacuum_freeze_max_age` (que tiene un valor predeterminado de 200 millones de ID de transacción) para una instancia de Amazon RDS, puede utilizar la siguiente consulta:

```
SELECT
    TO_CHAR(setting::bigint, 'FM9,999,999,999') autovacuum_freeze_max_age
FROM
    pg_settings
WHERE
    name = 'autovacuum_freeze_max_age';
```

Tenga en cuenta que `postgres_get_av_diag()` solo comprueba si hay bloqueadores de vaciado intensivo cuando la antigüedad supera el umbral de [autovacuum adaptativo](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming) de Amazon RDS de 500 millones de ID de transacción. Para que `postgres_get_av_diag()` detecte los bloqueadores, el bloqueador debe tener al menos 500 millones de transacciones de antigüedad.

La función `postgres_get_av_diag()` identifica los siguientes tipos de bloqueadores:

**Topics**
+ [Instrucción activa](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Active_statement)
+ [Inactividad en la transacción](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Idle_in_transaction)
+ [Transacción preparada](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Prepared_transaction)
+ [Ranura de replicación lógica](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Logical_replication_slot)
+ [Réplicas de lectura](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas)
+ [Tablas temporales](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Temporary_tables)

## Instrucción activa
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Active_statement"></a>

En PostgreSQL, una instrucción activa es una instrucción SQL que la base de datos está ejecutando actualmente. Incluye consultas, transacciones o cualquier operación en curso. Al realizar la supervisión mediante `pg_stat_activity`, la columna de estado indica que el proceso con el PID correspondiente está activo.

La función `postgres_get_av_diag()` muestra un resultado similar al siguiente cuando identifica una instrucción que resulta ser una instrucción activa.

```
blocker               | Active statement
database              | my_database
blocker_identifier    | SELECT pg_sleep(20000);
wait_event            | Timeout:PgSleep
autovacuum_lagging_by | 568,600,871
suggestion            | Connect to database "my_database", review carefully and you may consider terminating the process using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"SELECT pg_terminate_backend (29621);"}
```

**Acción sugerida**

Siguiendo las instrucciones de la columna `suggestion`, el usuario puede conectarse a la base de datos en la que se encuentra la instrucción activa y, tal como se especifica en la columna `suggested_action`, se recomienda revisar detenidamente la opción de finalizar la sesión. Si la finalización es segura, se puede utilizar la función `pg_terminate_backend()` para finalizar la sesión. Esta acción la puede realizar un administrador (como la cuenta maestra de RDS) o un usuario con el privilegio `pg_terminate_backend()` necesario.

**aviso**  
Al finalizar la sesión, se desharán (`ROLLBACK`) los cambios que haya realizado. En función de sus requisitos, es posible que quiera volver a ejecutar la instrucción. Sin embargo, se recomienda hacerlo únicamente después de que el proceso de autovacuum haya finalizado su operación de vaciado intensivo.

## Inactividad en la transacción
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Idle_in_transaction"></a>

El concepto de inactividad en una instrucción de transacción se refiere a cualquier sesión en la que se haya abierto una transacción explícita (por ejemplo, emitiendo una instrucción `BEGIN`), se haya realizado algún trabajo y se esté esperando a que el cliente pase más trabajo o dé la señal de finalización de la transacción emitiendo una instrucción `COMMIT`, `ROLLBACK` o `END` (lo que daría como resultado un `COMMIT` implícitamente).

La función `postgres_get_av_diag()` muestra un resultado similar al siguiente cuando identifica una instrucción `idle in transaction` como bloqueador.

```
blocker               | idle in transaction
database              | my_database
blocker_identifier    | INSERT INTO tt SELECT * FROM tt;
wait_event            | Client:ClientRead
autovacuum_lagging_by | 1,237,201,759
suggestion            | Connect to database "my_database", review carefully and you may consider terminating the process using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"SELECT pg_terminate_backend (28438);"}
```

**Acción sugerida**

Como se indica en la columna `suggestion`, puede conectarse a la base de datos en la que se encuentra la sesión de inactividad en la transacción y finalizar la sesión mediante la función `pg_terminate_backend()`. El usuario puede ser su usuario administrador (cuenta maestra de RDS) o un usuario con el privilegio `pg_terminate_backend()`.

**aviso**  
Al finalizar la sesión, se desharán (`ROLLBACK`) los cambios que haya realizado. En función de sus requisitos, es posible que quiera volver a ejecutar la instrucción. Sin embargo, se recomienda hacerlo únicamente después de que el proceso de autovacuum haya finalizado su operación de vaciado intensivo.

## Transacción preparada
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Prepared_transaction"></a>

PostgreSQL permite realizar transacciones que forman parte de una estrategia de confirmación de dos fases denominada [transacciones preparadas](https://www.postgresql.org/docs/current/sql-prepare-transaction.html). Se habilitan al establecer el parámetro `max_prepared_transactions` en un valor distinto de cero. Las transacciones preparadas han sido diseñadas para garantizar que una transacción sea duradera y permanezca disponible incluso después de que la base de datos se bloquee, se reinicie o se desconecte del cliente. Al igual que las transacciones normales, se les asigna un identificador de transacción y pueden afectar al autovacuum. Si se deja en un estado preparado, el autovacuum no puede realizar la congelación y podría provocar un reinicio del ID de transacción.

Cuando las transacciones se dejan preparadas indefinidamente sin que las resuelva un administrador de transacciones, se convierten en transacciones preparadas huérfanas. La única forma de solucionar este problema es confirmar o revertir la transacción mediante los comandos `COMMIT PREPARED` o `ROLLBACK PREPARED` respectivamente.

**nota**  
Tenga en cuenta que una copia de seguridad realizada durante una transacción preparada seguirá conteniendo esa transacción después de la restauración. Consulte la siguiente información sobre cómo localizar y cerrar dichas transacciones.

La función `postgres_get_av_diag()` muestra el siguiente resultado cuando identifica un bloqueador que es una transacción preparada.

```
blocker               | Prepared transaction
database              | my_database
blocker_identifier    | myptx
wait_event            | Not applicable
autovacuum_lagging_by | 1,805,802,632
suggestion            | Connect to database "my_database" and consider either COMMIT or ROLLBACK the prepared transaction using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"COMMIT PREPARED 'myptx';",[OR],"ROLLBACK PREPARED 'myptx';"}
```

**Acción sugerida**

Como se menciona en la columna de sugerencias, conéctese a la base de datos en la que se encuentre la transacción preparada. Sobre la base de la columna `suggested_action`, revise detenidamente si desea enviar una instrucción `COMMIT` o `ROLLBACK`, y realizar la acción correspondiente.

Para supervisar las transacciones preparadas en general, PostgreSQL ofrece una vista de catálogo llamada `pg_prepared_xacts`. Puede utilizar la siguiente consulta para buscar transacciones preparadas.

```
SELECT
    gid,
    prepared,
    owner,
    database,
    transaction AS oldest_xmin
FROM
    pg_prepared_xacts
ORDER BY
    age(transaction) DESC;
```

## Ranura de replicación lógica
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Logical_replication_slot"></a>

El propósito de una ranura de replicación es almacenar los cambios no consumidos hasta que se repliquen en un servidor de destino. Para obtener más información, consulte [Logical replication](https://www.postgresql.org/docs/current/logical-replication.html) de PostgreSQL.

Existen dos tipos de ranuras de replicación lógica.

**Ranuras de replicación lógica inactivas**

Cuando finaliza la replicación, los registros de transacciones no consumidas no se pueden eliminar y la ranura de replicación queda inactiva. Aunque un suscriptor no utilice actualmente una ranura de replicación lógica inactiva, esta permanece en el servidor, lo que provoca la retención de los archivos WAL y evita la eliminación de los registros de transacciones antiguos. Esto puede aumentar el uso del disco y, específicamente, impedir que autovacuum limpie las tablas del catálogo interno, ya que el sistema debe evitar que se sobrescriba la información de LSN. Si este problema no se soluciona, puede provocar una sobrecarga del catálogo, una degradación del rendimiento y un mayor riesgo de que se produzcan vaciados previos al reinicio, lo que podría causar tiempo de inactividad en las transacciones.

**Ranuras de replicación lógica activas pero lentas**

A veces, la eliminación de las tuplas inactivas del catálogo se retrasa debido a la degradación del rendimiento de la replicación lógica. Este retraso en la replicación ralentiza la actualización de `catalog_xmin` y puede provocar una sobrecarga del catálogo y un vaciado previo al reinicio.

La función `postgres_get_av_diag()` muestra un resultado similar al siguiente cuando encuentra una ranura de replicación lógica que funciona como bloqueador.

```
blocker               | Logical replication slot
database              | my_database
blocker_identifier    | slot1
wait_event            | Not applicable
autovacuum_lagging_by | 1,940,103,068
suggestion            | Ensure replication is active and resolve any lag for the slot if active. If inactive, consider dropping it using the command in suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"SELECT pg_drop_replication_slot('slot1') FROM pg_replication_slots WHERE active = 'f';"}
```

**Acción sugerida**

Para resolver este problema, compruebe la configuración de la replicación para ver si hay problemas con el esquema o los datos de destino que puedan estar finalizando el proceso de aplicación. Los motivos más comunes son los siguientes: 
+ Columnas faltantes
+ Tipos de datos incompatibles
+ Discrepancia de datos
+ Tabla faltante

Si el problema está relacionado con problemas de infraestructura:
+ Problemas de red: [¿cómo resuelvo los problemas con una base de datos de Amazon RDS en un estado de red incompatible?](https://repost.aws/knowledge-center/rds-incompatible-network)
+ La base de datos o la instancia de base de datos no están disponibles por una de las siguientes razones:
  + La instancia de réplica se ha quedado sin espacio de almacenamiento: consulte qué hacer cuando [las instancias de base de datos de Amazon RDS se quedan sin almacenamiento](https://repost.aws/knowledge-center/rds-out-of-storage) para obtener información sobre cómo añadir almacenamiento.
  + Parámetros incompatibles: revise [¿Cómo puedo corregir una instancia de base de datos de Amazon RDS que está estancada en el estado parámetros incompatibles?](https://repost.aws/knowledge-center/rds-incompatible-parameters) para obtener más información acerca de cómo solucionar este problema.

Si la instancia está fuera de la red de AWS o en AWS EC2, consulte a su administrador sobre cómo resolver los problemas relacionados con la disponibilidad o la infraestructura.

**Eliminación de la ranura inactiva**

**aviso**  
Precaución: Antes de eliminar una ranura de replicación, asegúrese exhaustivamente de que no tenga ninguna replicación en curso, de que esté inactiva y de que se encuentre en un estado irrecuperable. Si se elimina una ranura de forma prematura, se podría interrumpir la replicación o provocar la pérdida de datos.

Después de confirmar que la ranura de replicación ya no es necesaria, elimínela para permitir que el autovacuum continúe. La condición `active = 'f'` garantiza que solo se eliminará una ranura inactiva.

```
SELECT pg_drop_replication_slot('slot1') WHERE active ='f'
```

## Réplicas de lectura
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas"></a>

Cuando la configuración `hot_standby_feedback` está habilitada para las [réplicas de lectura de Amazon RDS](USER_PostgreSQL.Replication.ReadReplicas.md), evita que el autovacuum de la base de datos principal elimine determinadas filas inactivas que podrían seguir necesitando las consultas que se ejecuten en la réplica de lectura. Esto afecta a todos los tipos de réplicas de lectura físicas, incluidas las que se administran con o sin ranuras de replicación. Este comportamiento es necesario porque las consultas que se ejecutan en la réplica en espera requieren que esas filas permanezcan disponibles en el servidor principal, lo que evita cancelaciones y [conflictos de consultas](https://www.postgresql.org/docs/current/hot-standby.html#HOT-STANDBY-CONFLICT).

**Réplica de lectura con ranura de replicación física**  
Las réplicas de lectura con ranuras de replicación físicas mejoran considerablemente la fiabilidad y la estabilidad de la replicación en RDS para PostgreSQL. Estas ranuras garantizan que la base de datos principal conserve los archivos de registro de escritura anticipada esenciales hasta que la réplica los procese, ya que esto mantiene la coherencia de datos incluso durante las interrupciones de la red.

A partir de la versión 14 de RDS para PostgreSQL, todas las réplicas utilizan ranuras de replicación. En las versiones anteriores, solo las réplicas entre regiones utilizaban ranuras de replicación.

La función `postgres_get_av_diag()` muestra un resultado similar al siguiente cuando encuentra una réplica de lectura con una ranura de replicación física como bloqueador.

```
blocker               | Read replica with physical replication slot
database              |
blocker_identifier    | rds_us_west_2_db_xxxxxxxxxxxxxxxxxxxxx
wait_event            | Not applicable
autovacuum_lagging_by | 554,080,689
suggestion            | Run the following query on the replica "rds_us_west_2_db_xxxxxxxxxxxxxxxxxxxx" to find the long running query:                           
                      | SELECT * FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 757989377;                                                       
                      | Review carefully and you may consdier terminating the query on read replica using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.                                 +                      |
suggested_action      | {"SELECT pg_terminate_backend(pid) FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 757989377;","                                                                                 +
                      | [OR]                                                                                                                                                                                                 +
                      | ","Disable hot_standby_feedback","                                                                                                                                                                   +
                      | [OR]                                                                                                                                                                                                 +
                      | ","Delete the read replica if not needed"}
```

**Réplica de lectura con replicación de streaming**  
Amazon RDS permite configurar réplicas de lectura sin una ranura de replicación física en versiones anteriores, hasta la versión 13. Este enfoque reduce la sobrecarga al permitir que el servidor principal recicle los archivos WAL de forma más intensiva, lo que resulta ventajoso en entornos con limitaciones del espacio en disco y en los que se pueda tolerar un ReplicaLag ocasional. Sin embargo, sin no dispone de una ranura, la réplica en espera debe permanecer sincronizada para evitar que se pierdan archivos WAL. Amazon RDS utiliza archivos WAL archivados para ayudar a la réplica a ponerse al día en caso de que se quede atrás, pero este proceso requiere una supervisión exhaustiva y puede resultar lento.

La función `postgres_get_av_diag()` muestra un resultado similar al siguiente cuando encuentra una réplica de lectura de streaming como bloqueador.

```
blocker               | Read replica with streaming replication slot
database              | Not applicable
blocker_identifier    | xx.x.x.xxx/xx
wait_event            | Not applicable
autovacuum_lagging_by | 610,146,760
suggestion            | Run the following query on the replica "xx.x.x.xxx" to find the long running query:                                                                                                                                                         +
                      | SELECT * FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 348319343;                                                                                                                                                     +
                      | Review carefully and you may consdier terminating the query on read replica using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.                                       +
                      |
suggested_action      | {"SELECT pg_terminate_backend(pid) FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 348319343;","                                                                                                                        +
                      | [OR]                                                                                                                                                                                                                                        +
                      | ","Disable hot_standby_feedback","                                                                                                                                                                                                          +
                      | [OR]                                                                                                                                                                                                                                        +
                      | ","Delete the read replica if not needed"}
```

**Acción sugerida**

Como se recomienda en la columna `suggested_action`, revise detenidamente estas opciones para desbloquear el autovacuum.
+ **Finalizar la consulta**: de acuerdo con las instrucciones de la columna de sugerencias, puede conectarse a la réplica de lectura, tal y como se especifica en la columna suggested\$1action. Se recomienda revisar detenidamente la opción para finalizar la sesión. Si la finalización se considera segura, se puede utilizar la función `pg_terminate_backend()` para finalizar la sesión. Esta acción la puede realizar un administrador (como la cuenta maestra de RDS) o un usuario con el privilegio pg\$1terminate\$1backend() necesario.

  Puede ejecutar el siguiente comando SQL en la réplica de lectura para finalizar la consulta que impide que el proceso de vaciado en el principal pueda limpiar las filas antiguas. El valor de `backend_xmin` se indica en la salida de la función:

  ```
  SELECT
      pg_terminate_backend(pid)
  FROM
      pg_catalog.pg_stat_activity
  WHERE
      backend_xmin::text::bigint = backend_xmin;
  ```
+ **Desactivar la retroalimentación de espera activa**: plantéese deshabilitar el parámetro `hot_standby_feedback` si provoca retrasos significativos en el vaciado.

  El parámetro `hot_standby_feedback` permite que una réplica de lectura informe al servidor principal sobre su actividad de consulta, lo que evita que el principal vacíe las tablas o filas que están en uso en la réplica en espera. Si bien esto garantiza la estabilidad de las consultas en la réplica en espera, puede retrasar considerablemente el vaciado en el principal. La desactivación de esta característica permite al servidor principal continuar con el vaciado sin tener que esperar a que la réplica en espera se ponga al día. Sin embargo, esto puede provocar cancelaciones o errores en las consultas en la réplica en espera si intenta acceder a las filas que ha vaciado el principal.
+ **Eliminar la réplica de lectura si no es necesaria**: si la réplica de lectura ya no es necesaria, puede eliminarla. Esto eliminará la sobrecarga de replicación asociada y permitirá que el servidor principal recicle los registros de transacciones sin que la réplica se lo obstaculice.

## Tablas temporales
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Temporary_tables"></a>

Las [tablas temporales](https://www.postgresql.org/docs/current/sql-createtable.html), que se crean con la palabra clave `TEMPORARY`, residen en el esquema temporal (por ejemplo, pg\$1temp\$1xxx) y solo la sesión que las haya creado puede acceder a ellas. Las tablas temporales se eliminan al finalizar la sesión. Sin embargo, estas tablas son invisibles para el proceso de autovacuum de PostgreSQL y la sesión que las haya creado debe vaciarlas manualmente. Intentar vaciar la tabla temporal desde otra sesión no tiene ningún efecto.

En circunstancias poco habituales, puede existir una tabla temporal sin que sea propiedad de una sesión activa. Si la sesión propietaria finaliza inesperadamente debido a un bloqueo grave, un problema de red o un suceso similar, es posible que la tabla temporal no se limpie y quede como una tabla “huérfana”. Cuando el proceso de autovacuum de PostgreSQL detecta una tabla temporal huérfana, registra el siguiente mensaje:

```
LOG: autovacuum: found orphan temp table \"%s\".\"%s\" in database \"%s\"
```

La función `postgres_get_av_diag()` muestra un resultado similar al siguiente cuando identifica una tabla temporal como bloqueador. Para que la función muestre correctamente el resultado relacionado con las tablas temporales, debe ejecutarse en la misma base de datos en la que se encuentren esas tablas.

```
blocker               | Temporary table
database              | my_database
blocker_identifier    | pg_temp_14.ttemp
wait_event            | Not applicable
autovacuum_lagging_by | 1,805,802,632
suggestion            | Connect to database "my_database". Review carefully, you may consider dropping temporary table using command in suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"DROP TABLE ttemp;"}
```

**Acción sugerida**

Siga las instrucciones que aparecen en la columna `suggestion` del resultado para identificar y eliminar la tabla temporal que impide la ejecución del autovacuum. Use el siguiente comando para eliminar la tabla temporal notificada por `postgres_get_av_diag()`. Reemplace el nombre de la tabla en función del resultado proporcionado por la función `postgres_get_av_diag()`.

```
DROP TABLE my_temp_schema.my_temp_table;
```

La siguiente consulta se puede utilizar para identificar tablas temporales:

```
SELECT
    oid,
    relname,
    relnamespace::regnamespace,
    age(relfrozenxid)
FROM
    pg_class
WHERE
relpersistence = 't'
ORDER BY
    age(relfrozenxid) DESC;
```

# Resolución de bloqueadores de vaciado no identificables en RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Unidentifiable_blockers"></a>

En esta sección se analizan otros motivos que pueden impedir que el progreso del vaciado. Actualmente, la función `postgres_get_av_diag()` no puede identificar directamente estos problemas. 

**Topics**
+ [Páginas no válidas](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Invalid_pages)
+ [Incoherencia en los índices](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Index_inconsistency)
+ [Tasa de transacciones excepcionalmente alta](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.High_transaction_rate)

## Páginas no válidas
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Invalid_pages"></a>

Se produce un error de página no válida cuando PostgreSQL detecta una discrepancia en la suma de comprobación de una página al acceder a esa página. El contenido resulta ilegible, lo que impide que autovacuum congele las tuplas. Esto detiene de forma efectiva el proceso de limpieza. El siguiente error está escrito en el registro de PostgreSQL:

```
WARNING:  page verification failed, calculated checksum YYYYY but expected XXXX
ERROR:  invalid page in block ZZZZZ of relation base/XXXXX/XXXXX
CONTEXT:  automatic vacuum of table myschema.mytable
```

**Determinar el tipo de objeto**

```
ERROR: invalid page in block 4305910 of relation base/16403/186752608 
WARNING: page verification failed, calculated checksum 50065 but expected 60033
```

A partir del mensaje de error, la ruta `base/16403/186752608` proporciona la siguiente información:
+ “base” es el nombre del directorio de datos de PostgreSQL.
+ “16403” es el OID de la base de datos, que puede buscar en el catálogo del sistema `pg_database`.
+ “186752608” es el `relfilenode`, que puede utilizar para buscar el nombre del objeto y el esquema en el catálogo del sistema `pg_class`.

Al comprobar el resultado de la siguiente consulta en la base de datos afectada, puede determinar el tipo de objeto. La siguiente consulta recupera información de objeto para el oid: 186752608. Sustituya este OID por el correspondiente para el error que haya encontrado.

```
SELECT
    relname AS object_name,
    relkind AS object_type,
    nspname AS schema_name
FROM
    pg_class c
    JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE
    c.oid = 186752608;
```

Para obtener más información, consulte la documentación de PostgreSQL sobre [https://www.postgresql.org/docs/current/catalog-pg-class.html](https://www.postgresql.org/docs/current/catalog-pg-class.html) para ver todos los tipos de objetos compatibles, indicados en la columna `relkind` de `pg_class`.

**Indicaciones**

La solución más eficaz para este problema depende de la configuración de la instancia específica de Amazon RDS y del tipo de datos afectados por la página incoherente.

**Si el tipo de objeto es un índice:**

Se recomienda volver a crear el índice.
+ **Uso de la opción `CONCURRENTLY`**: antes de la versión 12 de PostgreSQL, la reconstrucción de un índice requería un bloqueo de tabla exclusivo, lo que restringía el acceso a la misma. Con PostgreSQL versión 12 y versiones posteriores, la opción `CONCURRENTLY` permite el bloqueo por filas, lo que mejora significativamente la disponibilidad de la tabla. A continuación, se muestra el comando:

  ```
  REINDEX INDEX ix_name CONCURRENTLY;
  ```

  Si bien `CONCURRENTLY` resulta menos disruptivo, puede ser más lento en tablas de uso intensivo. Si es posible, considere la posibilidad de crear el índice durante los períodos de poco tráfico.

  Para obtener más información, consulte la documentación de PostgreSQL sobre [REINDEX](https://www.postgresql.org/docs/current/sql-reindex.html).
+ **Uso de la opción `INDEX_CLEANUP FALSE`**: si los índices son grandes y se calcula que tardarán mucho en completarse, puede desbloquear el autovacuum ejecutando un `VACUUM FREEZE` manual y excluyendo los índices. Esta funcionalidad está disponible en la versión 12 y posteriores de PostgreSQL. 

  Omitir los índices le permitirá saltarse el proceso de vaciado del índice incoherente y mitigar el problema del reinicio. Sin embargo, esto no resolverá el problema subyacente de la página no válida. Para solucionar por completo el problema de la página no válida y resolverlo, tendrá que volver a crear el índice.

**Si el tipo de objeto es una vista materializada:**

Si se produce un error de página no válida en una vista materializada, inicie sesión en la base de datos afectada y actualícela para resolver la página no válida:

Actualice la vista materializada:

```
REFRESH MATERIALIZED VIEW schema_name.materialized_view_name;
```

Si se produce un error al actualizar, intente volver a crearla:

```
DROP MATERIALIZED VIEW schema_name.materialized_view_name;
CREATE MATERIALIZED VIEW schema_name.materialized_view_name AS query;
```

Al actualizar o volver a crear la vista materializada, se restaura sin que esto afecte a los datos de la tabla subyacente.

**Para todos los demás tipos de objetos:**

Para todos los demás tipos de objetos, puede ponerse en contacto con el servicio de asistencia de AWS.

## Incoherencia en los índices
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Index_inconsistency"></a>

Un índice que no sea coherente desde el punto de vista lógico puede impedir que avance el autovacuum. Los siguientes errores u otros similares se registran durante la fase de vaciado del índice o cuando se accede al índice mediante instrucciones SQL.

```
ERROR: right sibling's left-link doesn't match:block 5 links to 10 instead of expected 2 in index ix_name
```

```
ERROR: failed to re-find parent key in index "XXXXXXXXXX" for deletion target page XXX
CONTEXT:  while vacuuming index index_name of relation schema.table
```

**Indicaciones**

Reconstruya el índice u omita los índices utilizando `INDEX_CLEANUP` con un `VACUUM FREEZE` manual. Para obtener información sobre cómo reconstruir el índice, consulte [Si el tipo de objeto es un índice](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Invalid_pages).
+ **Uso de la opción CONCURRENTLY**: antes de la versión 12 de PostgreSQL, la reconstrucción de un índice requería un bloqueo de tabla exclusivo, lo que restringía el acceso a la misma. Con PostgreSQL versión 12 y versiones posteriores, la opción CONCURRENTLY permite el bloqueo por filas, lo que mejora significativamente la disponibilidad de la tabla. A continuación, se muestra el comando:

  ```
  REINDEX INDEX ix_name CONCURRENTLY;
  ```

  Si bien CONCURRENTLY resulta menos disruptivo, puede ser más lento en tablas de uso intensivo. Si es posible, considere la posibilidad de crear el índice durante los períodos de poco tráfico. Para obtener más información, consulte [REINDEX](https://www.postgresql.org/docs/current/sql-reindex.html) en la documentación de *PostgreSQL*.
+ **Uso de la opción INDEX\$1CLEANUP FALSE**: si los índices son grandes y se calcula que tardarán mucho en completarse, puede desbloquear el autovacuum ejecutando un VACUUM FREEZE manual y excluyendo los índices. Esta funcionalidad está disponible en la versión 12 y posteriores de PostgreSQL.

  Omitir los índices le permitirá saltarse el proceso de vaciado del índice incoherente y mitigar el problema del reinicio. Sin embargo, esto no resolverá el problema subyacente de la página no válida. Para solucionar por completo el problema de la página no válida y resolverlo, tendrá que volver a crear el índice.

## Tasa de transacciones excepcionalmente alta
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.High_transaction_rate"></a>

En PostgreSQL, las tasas de transacción altas pueden afectar significativamente al rendimiento de autovacuum, lo que implica una limpieza más lenta de las tuplas inactivas y a un aumento del riesgo de reiniciar los ID de transacción. Puede supervisar la tasa de transacciones midiendo la diferencia en `max(age(datfrozenxid))` entre dos períodos de tiempo, normalmente por segundo. Además, puede utilizar las siguientes métricas de contador de Información de rendimiento de RDS para medir la tasa de transacciones (la suma de xact\$1commit y xact\$1rollback), que es el número total de transacciones.


|  Contador  |  Tipo  |  Unidad  |  Métrica  | 
| --- | --- | --- | --- | 
|  xact\$1commit  |  Transacciones  |  Confirmaciones por segundo  |  db.Transactions.xact\$1commit  | 
|  xact\$1rollback  |  Transacciones  |  Restauraciones por segundo  |  db.Transactions.xact\$1rollback  | 

Un aumento rápido indica una alta carga de transacciones, lo que puede ser excesivo para autovacuum y provocar sobrecargas, bloqueos y posibles problemas de rendimiento. Esto puede tener un impacto negativo en el proceso de autovacuum de dos maneras:
+ **Actividad de la tabla:** la tabla específica que se está vaciando podría estar registrando un gran volumen de transacciones, lo que provocaría retrasos.
+ **Recursos del sistema:** el sistema en general puede estar sobrecargado, lo que dificulta que autovacuum acceda a los recursos necesarios para funcionar de manera eficiente.

Plantéese las siguientes estrategias para permitir que autovacuum funcione de manera más eficaz y pueda seguir el ritmo de sus tareas:

1. Reduzca la tasa de transacciones si es posible. Plantéese la posibilidad de agrupar o agrupar transacciones similares cuando sea posible.

1. Utilice tablas que se actualicen con frecuencia mediante la operación `VACUUM FREEZE` manual cada noche, semana o quincena durante las horas de menor actividad. 

1. Plantéese la posibilidad de escalar verticalmente su clase de instancia para asignar más recursos del sistema con el fin de administrar el volumen de transacciones elevado y el autovacuum.

# Resolución de problemas de rendimiento de vaciado en RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Performance"></a>

En esta sección se analizan los factores que suelen contribuir a reducir el rendimiento del vaciado y cómo abordar estos problemas.

**Topics**
+ [Vaciado de índices grandes](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Large_indexes)
+ [Demasiadas tablas o bases de datos que vaciar](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Multiple_tables)
+ [Se está ejecutando un vaciado intensivo (para evitar el reinicio)](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Aggressive_vacuum)

## Vaciado de índices grandes
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Large_indexes"></a>

VACUUM funciona a través de fases secuenciales: inicialización, escaneo del montón, vaciado de índices y montón, limpieza de índices, truncamiento del montón y limpieza final. Durante el escaneo del montón, el proceso elimina las páginas, las desfragmenta y las congela. Después de completar el escaneo del montón, VACUUM limpia los índices, se devuelven las páginas vacías al sistema operativo y se realizan tareas de limpieza final, como el vaciado del mapa del espacio libre y la actualización de las estadísticas.

Es posible que sea necesario realizar varias pasadas para el vaciado de índices cuando `maintenance_work_mem` (o `autovacuum_work_mem`) no es suficiente para procesar el índice. En la versión 16 y anteriores de PostgreSQL, un límite de memoria de 1 GB para almacenar los ID de tuplas inactivas a menudo forzaba varias pasadas en índices grandes. PostgreSQL 17 presenta `TidStore`, que asigna memoria de forma dinámica en lugar de utilizar una matriz de asignación única. Esto elimina la restricción de 1 GB, utiliza la memoria de manera más eficiente y reduce la necesidad de realizar varios análisis de índice por cada índice.

Es posible que los índices grandes aún requieran varias pasadas en PostgreSQL 17 si la memoria disponible no puede acomodar todo el procesamiento del índice de una vez. Por lo general, los índices mayores contienen más tuplas inactivas que requieren varias pasadas.

**Detección de operaciones de limpieza lentas**

La función `postgres_get_av_diag()` puede detectar cuando las operaciones de limpieza se ejecutan lentamente debido a memoria insuficiente. Para obtener más información sobre esta función, consulte [Instalación de herramientas de supervisión y diagnóstico de autovacuum en RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Installation.md).

La función `postgres_get_av_diag()` emite los siguientes avisos cuando la memoria disponible no es suficiente para completar la limpieza del índice en una sola pasada.

**`rds_tools` 1.8**

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
```

```
NOTICE: The current setting of autovacuum_work_mem is "XXX" and might not be sufficient. Consider increasing the setting, and if necessary, scaling up the Amazon RDS instance class for more memory. 
        Additionally, review the possibility of manual vacuum with exclusion of indexes using (VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) table_name;).
```

**`rds_tools` 1.9**

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
```

```
NOTICE: The current setting of autovacuum_work_mem is XX might not be sufficient. Consider increasing the setting to XXX, and if necessary, scaling up the RDS instance class for more 
        memory. The suggested value is an estimate based on the current number of dead tuples for the table being vacuumed, which might not fully reflect the latest state. Additionally, review the possibility of manual 
        vacuum with exclusion of indexes using (VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) table_name;). For more information, see 
        [Working with PostgreSQL autovacuum in the Amazon Amazon RDS User Guide](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html)
        .
```

**nota**  
La función `postgres_get_av_diag()` se basa en `pg_stat_all_tables.n_dead_tup` para estimar la cantidad de memoria necesaria para el vaciado de índices.

Cuando la función `postgres_get_av_diag()` identifique una operación de limpieza lenta que requiera múltiples análisis de índice debido a que no hay suficiente `autovacuum_work_mem`, generará el siguiente mensaje:

```
NOTICE: Your vacuum is performing multiple index scans due to insufficient autovacuum_work_mem:XXX for index vacuuming. 
        For more information, see [Working with PostgreSQL autovacuum in the Amazon Amazon RDS User Guide](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html).
```

**Indicaciones**

Puede aplicar las siguientes soluciones alternativas utilizando manualmente `VACUUM FREEZE` para acelerar la congelación de la tabla.

**Aumentar la memoria de vaciado**

Como sugiere la función `postgres_get_av_diag()`, se recomienda aumentar el parámetro `autovacuum_work_mem` para abordar las posibles restricciones de memoria en cada instancia. Aunque `autovacuum_work_mem` es un parámetro dinámico, es importante tener en cuenta que, para que la nueva configuración de memoria surta efecto, el daemon de autovacuum debe reiniciar sus procesos de trabajo. Para lograrlo:

1. Confirme que la nueva configuración esté establecida.

1. Finalice los procesos que actualmente estén ejecutando el autovacuum.

Este enfoque garantiza que la asignación de memoria ajustada se aplique a las nuevas operaciones de autovacuum.

Para obtener resultados más inmediatos, considere la posibilidad de realizar manualmente una operación `VACUUM FREEZE` con una configuración de `maintenance_work_mem` mayor durante la sesión:

```
SET maintenance_work_mem TO '1GB';
VACUUM FREEZE VERBOSE table_name;
```

Si utiliza Amazon RDS y descubre que necesita memoria adicional para poder utilizar valores más altos para `maintenance_work_mem` o `autovacuum_work_mem`, plantéese la posibilidad de actualizar a una clase de instancia con más memoria. Esto puede proporcionarle los recursos necesarios para mejorar las operaciones de vaciado manuales y automáticas, lo que se traduce en una mejora del rendimiento general de vaciado y del de las bases de datos.

**Desactivar INDEX\$1CLEANUP**

El `VACUUM` manual de la versión 12 y posteriores de PostgreSQL permite omitir la fase de limpieza de índices, mientras que el autovacuum de emergencia en la versión 14 y posteriores de PostgreSQL lo hace automáticamente en función del parámetro [https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-VACUUM-FAILSAFE-AGE](https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-VACUUM-FAILSAFE-AGE).

**aviso**  
Omitir la limpieza de índices puede provocar una sobrecarga de índices y perjudicar el rendimiento de las consultas. Para mitigar esta situación, considere la posibilidad de volver a indexar o vaciar los índices afectados durante un período de mantenimiento.

Para obtener más información sobre cómo gestionar índices grandes, consulte la documentación en [Administración de autovacuum con índices de gran tamaño](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.md).

**Vaciado de índices en paralelo**

A partir de PostgreSQL 13, los índices se pueden vaciar y limpiar en paralelo de forma predeterminada utilizando `VACUUM` de forma manual, con un proceso de trabajo de vaciado asignado a cada índice. Sin embargo, para que PostgreSQL determine si una operación de vaciado es apta para su ejecución en paralelo, se deben cumplir criterios específicos:
+ Debe haber al menos dos índices.
+ El parámetro `max_parallel_maintenance_workers` debe estar establecido al menos en 2.
+ El tamaño del índice debe superar el límite `min_parallel_index_scan_size`, que de forma predeterminada es de 512 KB.

Puede ajustar la configuración `max_parallel_maintenance_workers` en función de la cantidad de vCPU disponibles en su instancia de Amazon RDS y la cantidad de índices de la tabla para optimizar el tiempo de respuesta del vaciado.

Para obtener más información, consulte [Parallel vacuuming in Amazon RDS for PostgreSQL and Amazon Aurora PostgreSQL](https://aws.amazon.com/blogs/database/parallel-vacuuming-in-amazon-rds-for-postgresql-and-amazon-aurora-postgresql/).

## Demasiadas tablas o bases de datos que vaciar
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Multiple_tables"></a>

Como se menciona en la documentación de PostgreSQL sobre [el daemon autovacuum](https://www.postgresql.org/docs/current/routine-vacuuming.html#AUTOVACUUM'), este funciona mediante múltiples procesos. Esto incluye un lanzador de autovacuum persistente responsable de iniciar los procesos de trabajo de autovacuum para cada base de datos del sistema. El lanzador programa estos procesos de trabajo para que se inicien aproximadamente cada `autovacuum_naptime` segundos por cada base de datos.

Con “N” bases de datos, un nuevo proceso de trabajo comienza aproximadamente cada [`autovacuum_naptime`/N segundos]. Sin embargo, el número total de procesos de trabajo simultáneos está limitado por la configuración `autovacuum_max_workers`. Si el número de bases de datos o tablas que requieren vaciado supera este límite, la siguiente base de datos o tabla se procesará en cuanto haya un proceso de trabajo disponible.

Cuando muchas tablas o bases de datos grandes requieren un vaciado al mismo tiempo, todos los procesos de trabajo de autovacuum disponibles pueden permanecer ocupados durante un período prolongado, lo que retrasa el mantenimiento de otras tablas y bases de datos. En entornos con altas tasas de transacciones, este cuello de botella puede agravarse rápidamente y provocar posibles problemas de vaciado en su instancia de Amazon RDS.

Cuando `postgres_get_av_diag()` detecta un número elevado de tablas o bases de datos, proporciona la siguiente recomendación:

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
```

```
NOTICE: The current setting of autovacuum_max_workers:3 might not be sufficient. Consider increasing the setting and, if necessary, consider scaling up the Amazon RDS instance class for more workers.
```

**Indicaciones**

**Aumentar autovacuum\$1max\$1workers**

Para agilizar el vaciado, recomendamos ajustar el parámetro `autovacuum_max_workers` para permitir que haya más procesos de trabajo de autovacuum simultáneos. Si persisten los cuellos de botella en el rendimiento, plantéese la posibilidad de escalar verticalmente su instancia de Amazon RDS a una clase con más vCPU, lo que puede mejorar aún más las capacidades de procesamiento en paralelo.

## Se está ejecutando un vaciado intensivo (para evitar el reinicio)
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Aggressive_vacuum"></a>

La antigüedad de la base de datos (MaximumUsedTransactionIDs) en PostgreSQL solo disminuye cuando se completa correctamente un vaciado intensivo (para evitar el reinicio). Hasta que finalice este vaciado, la antigüedad seguirá aumentando en función de la velocidad de transacciones.

La función `postgres_get_av_diag()` genera el `NOTICE` siguiente cuando detecta un vaciado intensivo. Sin embargo, solo activa este resultado después de que el vaciado haya estado activo durante al menos dos minutos.

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound, monitor autovacuum performance.
```

Para obtener más información sobre el vaciado intensivo, consulte [When an aggressive vacuum is already running](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE.md).

Puede comprobar si se está realizando un vaciado intensivo con la siguiente consulta:

```
SELECT
    a.xact_start AS start_time,
    v.datname "database",
    a.query,
    a.wait_event,
    v.pid,
    v.phase,
    v.relid::regclass,
    pg_size_pretty(pg_relation_size(v.relid)) AS heap_size,
    (
        SELECT
            string_agg(pg_size_pretty(pg_relation_size(i.indexrelid)) || ':' || i.indexrelid::regclass || chr(10), ', ')
        FROM
            pg_index i
        WHERE
            i.indrelid = v.relid
    ) AS index_sizes,
    trunc(v.heap_blks_scanned * 100 / NULLIF(v.heap_blks_total, 0)) AS step1_scan_pct,
    v.index_vacuum_count || '/' || (
        SELECT
            count(*)
        FROM
            pg_index i
        WHERE
            i.indrelid = v.relid
    ) AS step2_vacuum_indexes,
    trunc(v.heap_blks_vacuumed * 100 / NULLIF(v.heap_blks_total, 0)) AS step3_vacuum_pct,
    age(CURRENT_TIMESTAMP, a.xact_start) AS total_time_spent_sofar
FROM
    pg_stat_activity a
    INNER JOIN pg_stat_progress_vacuum v ON v.pid = a.pid;
```

Para determinar si se trata de un vaciado intensivo (para evitar el reinicio), compruebe la columna de consulta del resultado. La expresión “para evitar el reinicio” indica que se trata de un vaciado intensivo.

```
query                  | autovacuum: VACUUM public.t3 (to prevent wraparound)
```

Por ejemplo, supongamos que hay un bloqueador en el valor de antigüedad de transacciones de 1000 millones y una tabla que requiere un vaciado intensivo para evitar el reinicio a esa misma antigüedad de transacciones. Además, hay otro bloqueador en el valor de antigüedad de transacciones de 750 millones. Tras superar el bloqueador en el valor de antigüedad de transacciones de 1000 millones, la antigüedad no se reducirá inmediatamente a 750 millones. Seguirá siendo alta hasta que se complete la tabla que necesita el vaciado intensivo o cualquier transacción con una antigüedad superior a los 750 millones. Durante este período, la antigüedad de las transacciones de su clúster de PostgreSQL seguirá aumentando. Una vez que se complete el proceso de vaciado, la antigüedad de las transacciones se reducirá a 750 millones, pero volverá a aumentar de nuevo hasta que se finalice todo el vaciado. Este ciclo continuará mientras se mantengan estas condiciones, hasta que la antigüedad de las transacciones finalmente se reduzca hasta el nivel configurado para su instancia de Amazon RDS, especificado por `autovacuum_freeze_max_age`.

# Explicación de los mensajes de tipo NOTICE en RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE"></a>

 La función `postgres_get_av_diag()` proporciona los siguientes mensajes de tipo NOTICE:

**Cuando la antigüedad aún no ha alcanzado aún el umbral de supervisión**  
El umbral de supervisión para que `postgres_get_av_diag()` identifique los bloqueadores es de 500 millones de transacciones por defecto. Si `postgres_get_av_diag()` genera el siguiente mensaje NOTICE, indica que la antigüedad de la transacción aún no ha alcanzado este umbral.  

```
NOTICE: postgres_get_av_diag() checks for blockers that prevent aggressive vacuums only, it does so only after exceeding dvb_threshold which is 500,000,000 and age of this PostgreSQL cluster is currently at 2.
```

**No está conectado a la base de datos que tenga la antigüedad del ID de transacción más antiguo**  
La función `postgres_get_av_diag()` proporciona el resultado más preciso cuando se conecta a la base de datos con el ID de transacción más antiguo. En su caso, la base de datos con el ID de transacción más antiguo notificada por `postgres_get_av_diag()` será diferente a “my\$1database”. Si no se ha conectado a la base de datos correcta, se generará el siguiente mensaje tipo NOTICE:  

```
NOTICE: You are not connected to the database with the age of oldest transaction ID. Connect to my_database database and run postgres_get_av_diag() for accurate reporting.
```
Conectarse a la base de datos con la antigüedad de transacción más antigua es importante por las siguientes razones:  
+ **Identificar los bloqueadores de tablas temporales:** dado que los metadatos de las tablas temporales son específicos de cada base de datos, normalmente se encuentran en la base de datos en la que se crearon. Sin embargo, si una tabla temporal resulta ser la que más bloquea y reside en la base de datos con la transacción más antigua, esta información podría resultar engañosa. La conexión a la base de datos correcta garantiza la identificación precisa del bloqueador de tablas temporal.
+ **Diagnóstico de vaciados lentos:** los metadatos del índice y la información sobre el recuento de tablas son específicos de la base de datos y son necesarios para diagnosticar los problemas de vaciado lento.

**La base de datos con la transacción más antigua se encuentra en una base de datos rdsadmin o template0**  
En algunos casos, las bases de datos `rdsadmin` o `template0` pueden identificarse como la base de datos con el ID de transacción más antiguo. Si esto ocurre, `postgres_get_av_diag()` emitirá el siguiente mensaje de tipo NOTICE:  

```
NOTICE: The database with the age of oldest transaction ID is rdsadmin or template0, reach out to support if the reported blocker is in rdsadmin or template0.
```
Compruebe que el bloqueador de la lista no se haya originado en ninguna de estas dos bases de datos. Si se notifica que el bloqueador está presente en `rdsadmin` o `template0` de ellas, póngase en contacto con el servicio de asistencia, ya que estas bases de datos no son accesibles para el usuario y requieren intervención.  
Es muy poco probable que las bases de datos `rdsadmin` o `template0` contengan un bloqueador principal.

**Cuando ya está en curso un vaciado intensivo**  
La función `postgres_get_av_diag()` está diseñada para notificar si se está ejecutando un proceso de vaciado intensivo, pero solo activa esta salida después de que el vaciado haya estado activo durante al menos 1 minuto. Este retraso intencionado ayuda a reducir las probabilidades de que se produzcan falsos positivos. Mediante esta espera, la función garantiza que solo se registren los vaciados efectivos y significativos, lo que permite una supervisión más precisa y fiable de la actividad de vaciado.  
La función `postgres_get_av_diag()` genera el siguiente mensaje de tipo NOTICE cuando detecta que se están realizando uno o varios vaciados intensivos.   

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound, monitor autovacuum performance.
```
Como se indica en el mensaje NOTICE, siga supervisando el rendimiento del vaciado. Para obtener más información acerca del vaciado intensivo, consulte [Se está ejecutando un vaciado intensivo (para evitar el reinicio)](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Performance.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Aggressive_vacuum)

**Cuando el vaciado intensivo está apagado**  
La función `postgres_get_av_diag()` genera el siguiente mensaje NOTICE si el autovacuum está deshabilitado en la instancia de la base de datos:  

```
NOTICE: Autovacuum is OFF, we strongly recommend to enable it, no restart is necessary.
```
Autovacuum es una característica fundamental de la instancia de base de datos de RDS para PostgreSQL que garantiza un funcionamiento fluido de la base de datos. Elimina automáticamente las versiones de filas antiguas, recupera espacio de almacenamiento y evita que las tablas se sobrecarguen, lo que ayuda a mantener la eficiencia de las tablas y los índices para lograr un rendimiento óptimo. Además, protege contra el reinicio de los identificadores de transacciones, lo que puede detener las transacciones en su instancia de Amazon RDS. La desactivación del autovacuum puede provocar una disminución a largo plazo del rendimiento y la estabilidad de la base de datos. Le sugerimos que lo mantenga activado todo el tiempo. Para obtener más información, consulte [Descripción de autovacuum en entornos de RDS para PostgreSQL](https://aws.amazon.com/blogs/database/understanding-autovacuum-in-amazon-rds-for-postgresql-environments/).  
La desactivación de autovacuum no detiene los vaciados intensivos. Seguirán produciéndose una vez que las tablas alcancen el umbral de `autovacuum_freeze_max_age`. 

**El número de transacciones pendientes es críticamente bajo**  
La función `postgres_get_av_diag()` genera el siguiente mensaje de tipo NOTICE cuando un vaciado previo al reinicio es inminente. Este mensaje NOTICE se emite cuando su instancia de Amazon RDS está a 100 millones de transacciones de la posibilidad de rechazar nuevas transacciones.  

```
WARNING: Number of transactions remaining is critically low, resolve issues with autovacuum or perform manual VACUUM FREEZE before your instance stops accepting transactions.
```
Es necesario realizar acciones inmediatas para evitar el tiempo de inactividad de la base de datos. Debe supervisar de cerca sus operaciones de vaciado y considerar la posibilidad de iniciar manualmente un `VACUUM FREEZE` en la base de datos afectada para evitar errores en las transacciones.