Al ejecutar PostgreSQL en producción, el rendimiento puede degradarse y las transacciones pueden inflarse sin que te des cuenta. Este artículo cubre los fundamentos de mantenimiento que necesitas para mantener PostgreSQL funcionando sin problemas.
1. VACUUM: Limpieza de tuplas muertas
PostgreSQL usa MVCC (Control de Concurrencia Multiversión), lo que significa que las versiones antiguas de filas (tuplas muertas) permanecen en las tablas después de actualizaciones y eliminaciones. Si no se controlan, las tablas se inflan y el rendimiento sufre.
-- Ejecutar un VACUUM estándar (no bloquea otras operaciones)
VACUUM;
-- Recuperar espacio al SO (adquiere bloqueo de tabla)
VACUUM FULL;
Los entornos de producción tienen autovacuum habilitado por defecto, pero las tablas ocupadas pueden necesitar ajustes:
autovacuum_vacuum_scale_factor = 0.01
autovacuum_vacuum_threshold = 50
autovacuum_naptime = 30s
2. ANALYZE: Manteniendo estadísticas actualizadas
El planificador de consultas se basa en estadísticas de tablas para elegir planes de ejecución. Cambios de datos importantes sin un ANALYZE reciente pueden llevar a malas elecciones de índices y consultas lentas.
ANALYZE;
-- O combinar con VACUUM
VACUUM ANALYZE;
Autovacuum maneja esto automáticamente, pero es aconsejable ejecutar un ANALYZE manual después de importaciones grandes de datos.
3. Revisión de la estrategia de índices
Eliminar índices no utilizados
SELECT indexrelname, idx_scan, idx_tup_read
FROM pg_stat_user_indexes
WHERE idx_scan = 0;
Un idx_scan de 0 probablemente significa que el índice nunca se ha utilizado. Sin embargo, verifica cuidadosamente antes de eliminar — algunos índices solo se usan en trabajos batch mensuales.
Reconstruir índices inflados
Con el tiempo, los índices se fragmentan y el rendimiento baja:
REINDEX INDEX index_name;
REINDEX TABLE table_name;
REINDEX DATABASE database_name;
4. Monitoreo del rendimiento de consultas con pg_stat_statements
La extensión pg_stat_statements revela qué consultas consumen más tiempo:
-- Habilitar en postgresql.conf
shared_preload_libraries = 'pg_stat_statements'
pg_stat_statements.track = all
-- Encontrar las 10 consultas más lentas
SELECT query, calls, total_exec_time / calls AS avg_time_ms
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;
Usa estos datos para decidir dónde agregar índices o reescribir SQL lento.
5. Estrategia de copias de seguridad
| Método | Características | Frecuencia recomendada |
|---|---|---|
pg_dump | Copia lógica, por tabla | Diaria |
pg_basebackup | Copia física, lista para PITR | Diaria |
| Archivo WAL | Archivado continuo, recuperación point-in-time | Siempre |
pg_dump -U postgres mydb > /backup/mydb_$(date +%Y%m%d).sql
La copia de seguridad física combinada con el archivado WAL es el enfoque más seguro cuando es posible.
6. Pool de conexiones
PostgreSQL crea un proceso por conexión de cliente, por lo que muchas conexiones concurrentes pueden sobrecargar la memoria. Un pool de conexiones como PgBouncer comparte un pequeño número de conexiones de base de datos entre muchos clientes de manera eficiente.
Programa de mantenimiento de muestra
| Frecuencia | Tarea |
|---|---|
| Diaria | Monitorear autovacuum, verificar registros de errores |
| Semanal | Análisis de rendimiento de consultas (pg_stat_statements) |
| Mensual | Revisar índices no utilizados, ANALYZE manual |
| Trimestral | REINDEX, VACUUM FULL durante ventana de mantenimiento |
| Semestral | Probar restauración desde copia de seguridad |
Resumen
PostgreSQL es altamente confiable con el cuidado adecuado. Hacer que VACUUM, ANALYZE, la gestión de índices y las copias de seguridad sean parte de tu rutina reduce drásticamente las sorpresas en producción. Comienza habilitando pg_stat_statements para entender tu línea base actual de rendimiento de consultas.

