Encontrar los que retienen el xmin horizon e impiden que VACUUM elimine dead tuples
PostgreSQLMantenimientoComando
SELECT 'session' AS source, pid::text AS id, usename::text AS owner, state AS detail,
age(backend_xmin) AS xmin_age
FROM pg_stat_activity
WHERE backend_xmin IS NOT NULL AND pid <> pg_backend_pid()
UNION ALL
SELECT 'prepared_xact', gid, owner::text, prepared::text, age(transaction)
FROM pg_prepared_xacts
UNION ALL
SELECT 'replication_slot', slot_name::text, slot_type, active::text,
greatest(age(xmin), age(catalog_xmin))
FROM pg_replication_slots
WHERE xmin IS NOT NULL OR catalog_xmin IS NOT NULL
UNION ALL
SELECT 'standby_feedback', application_name, usename::text, state, age(backend_xmin)
FROM pg_stat_replication
WHERE backend_xmin IS NOT NULL
ORDER BY xmin_age DESC NULLS LAST;Qué hace
Lista, ordenadas por antigüedad de xmin, las cuatro fuentes que pueden bloquear la limpieza de dead tuples: sesiones que mantienen snapshots, prepared transactions, replication slots y standbys que envían hot_standby_feedback.
Cuándo usarlo
Cuando VACUUM VERBOSE informa de 'dead row versions cannot be removed yet', el bloat sigue creciendo y la antigüedad de XID no baja.
Precaución
El xmin más antiguo define el horizonte de limpieza; los replication slots y el feedback de los standbys afectan a todas las bases de datos. Las prepared transactions sobreviven a los reinicios; verifique el propietario y ciérrelas con COMMIT PREPARED / ROLLBACK PREPARED '<gid>'. Eliminar un slot sin uso rompe su consumidor (standby, CDC); verifique antes el propietario. Ejecutado en un standby, solo muestra las sesiones de ese standby.