¿Cómo soluciono los problemas de autovacuum cuando ejecuta el indicador «to prevent wraparound» en bases de datos de Amazon RDS para PostgreSQL o la edición de Aurora compatible con PostgreSQL?
Quiero resolver los problemas de rendimiento cuando autovacuum ejecuta el indicador «to prevent wraparound» en mi base de datos Amazon Relational Database Service (Amazon RDS) para PostgreSQL o la edición de Amazon Aurora compatible con PostgreSQL.
Descripción corta
Al consultar pg_stat_activity, es posible que autovacuum ejecute continuamente el indicador «to prevent wraparound».
Los trabajadores de autovacuum generalmente no bloquean otros comandos. Cuando un proceso intenta adquirir un bloqueo que entra en conflicto con el bloqueo SHARE UPDATE EXCLUSIVE de autovacuum, la adquisición del bloqueo puede interrumpir a autovacuum. Sin embargo, cuando autovacuum se ejecuta para evitar que el ID de la transacción se cierre, el sistema no interrumpe automáticamente el proceso autovacuum.
En los siguientes casos, se puede producir un proceso autovacuum agresivo con el indicador «to prevent wraparound»:
- El valor relfrozenxid de la tabla es mayor que el de las transacciones vacuum_freeze_table_age, por lo que el sistema realiza un vacío agresivo para congelar las tuplas antiguas y avanzar en el campo relfrozenxid.
- Una tabla llega a su autovacuum_freeze_max_age.
Los problemas de rendimiento de la base de datos pueden producirse cuando autovacuum se ejecuta de forma agresiva. Para obtener más información, consulta Automatic vacuuming (Limpieza automática) en el sitio web de PostgreSQL.
Resolución
Cómo determinar si autovacuum está funcionando
Para determinar si autovacuum está funcionando, durante cuánto tiempo se ejecuta o si está esperando, ejecuta la siguiente consulta:
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;
En la siguiente respuesta de ejemplo, el indicador «to prevent wraparound» está activo en mydb para mytable1 y mytable2:
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; +
Autovaccum siempre tiene como objetivo las tablas que tienen un campo relfrozenxid superior al número de transacciones de autovaccum_freeze_max_age.
Identificación de las transacciones descongeladas
Para identificar las transacciones descongeladas en tu base de datos, ejecuta la siguiente consulta:
SELECT datname, age(datfrozenxid) FROM pg_database ORDER BY age(datfrozenxid) desc limit 20;
En la siguiente respuesta de ejemplo, el deamon de autovacuum prioriza la base de datos con un datfrozenxid superior a 200 millones:
datname | age mydb | 1771757888 template0 | 1721757888 template1 | 1721757888 rdsadmin | 1694008527 postgres | 1693881061 (5 rows)
La columna datfrozenxid de la fila pg_database de una base de datos se encuentra al final de los ID de transacción normales de la base de datos. La columna datfrozenxid es el mínimo de los valores relfrozenxid para cada tabla de la base de datos.
Congelación de tablas
Si la tabla está alcanzando el valor máximo de relfrozenxid, realiza un vaciado con congelación en las tablas.
Una vez finalizado el proceso de vaccum con congelación manual, consulta el resultado detallado para determinar si hay bloqueadores, como las ranuras de replicación antiguas y las transacciones que hayas preparado. Si recibes el mensaje "DETAIL: xxx dead row versions cannot be removed yet, oldest xmin: xxx", significa que el vaciado está funcionando pero no puede limpiar las tuplas inactivas.
Para buscar los bloqueadores de vaciado, puedes usar la función postgres_get_av_diag(). Para obtener más información, consulta Identificación y solución de bloqueadores de vaciado intensivo en RDS para PostgreSQL.
Aumento del número de trabajadores de autovacuum y eliminación de los índices que no se usen
Cuando las bases de datos o tablas que requieren un vaciado superan la cuota de autovacuum_max_workers, el motor procesa la siguiente base de datos o tabla solo cuando hay un trabajador disponible. En entornos con altas tasas de transacción, pueden producirse problemas de vaciado total.
Para resolver este problema, aumenta el parámetro autovacuum_max_workers para que haya más trabajadores de autovacuum simultáneos.
Si la tabla tiene índices grandes, se recomienda eliminar los índices que no se usen.
Aumento de la memoria de vaciado
Para asegurarte de que el motor aplica la asignación de memoria ajustada a los procesos nuevos de autovacuum, aumenta el parámetro autovacuum_work_mem.
Para aumentar el parámetro maintenance_work_mem en las operaciones de vaciado manuales, como el vaciado con congelación, ejecuta el siguiente comando:
SET maintenance_work_mem TO '2GB';
Nota: El valor predeterminado de maintenance_work_mem es 64 MB. Cuando se complete el vaciado, cambia el valor a su valor anterior. Si no cambias el valor, es posible que se produzcan problemas de memoria en instancias de menor tamaño.
Para iniciar la operación de vaciado, ejecuta el siguiente comando:
VACUUM FREEZE VERBOSE table_name;
Si hay índices grandes que requieren limpieza, autovacuum debe realizar varias operaciones. En PostgreSQL 16 y versiones anteriores, hay una cuota maintenance_work_mem de 1 GB que utiliza la operación de vaciado. PostgreSQL 17 y versiones posteriores usan TidStore que asigna memoria de forma dinámica y no usa una matriz de asignación única para que el proceso de vaciado pueda usar maintenance_work_mem de manera más eficiente.
Activación de vaciado en paralelo
En el caso de realizar un vaciado manual, puedes activar el vaciado en paralelo para que PostgreSQL asigne un trabajador de vaciado a cada índice y los vacíe en paralelo.
Para activar el vaciado en paralelo, ajusta la configuración max_parallel_maintenance_workers en función del número de vCPU disponibles para la instancia de base de datos y el número de índices de la tabla.
Para obtener más información, consulta Parallel vacuuming in Amazon RDS for PostgreSQL and Amazon Aurora PostgreSQL (Vaciado en paralelo en Amazon RDS para PostgreSQL y Amazon Aurora PostgreSQL).
Control de la cantidad de transacciones que utilizó la base de datos
Cuando la operación de autovacuum no puede completar un vaciado, es posible que la base de datos siga aumentando. Puedes usar la métrica MaximumUsedTransactionIDs de Amazon CloudWatch para obtener el número máximo de transacciones que utilizó la base de datos.
Además, puedes crear una alarma de CloudWatch para que la métrica MaximumUsedTransactionIDs te notifique cuando el número de transacciones alcance el valor que especificaste. Para obtener más información, consulta Implement an early warning system for transaction ID wraparound in Amazon RDS for PostgreSQL (Implementación de un sistema de alerta temprana para el wraparound del ID de transacción en Amazon RDS para PostgreSQL).
Para supervisar MaximumUsedTransactionIds en la consola de Amazon RDS, completa los pasos siguientes:
- Abre la consola de Amazon RDS.
- En el panel de navegación, selecciona Bases de datos y, a continuación, selecciona la base de datos.
- En la pestaña Registros y eventos, puedes ver MaximumUsedTransactionIDs en la sección Eventos recientes.
Si estás llegando a la cuota de MaximumUsedTransactionIDs, debes vaciar la tabla.
Para identificar los bloqueadores de vaciado, consulta Identify and resolve aggressive vacuum blockers in RDS for PostgreSQL (Identificación y solución de bloqueadores de vaciado intensivo en RDS para PostgreSQL).
- Temas
- Database
- Idioma
- Español

Contenido relevante
preguntada hace un año
preguntada hace un año
preguntada hace un año