Reorganizar una tabla con bloat sin bloqueos largos (pg_repack)
PostgreSQLMantenimientoComando
-- Once per target database (the pg_repack package must be installed on the server)
CREATE EXTENSION pg_repack;
# Dry run: show what would be done
pg_repack -h localhost -U postgres -d mydb --table=public.orders --dry-run
# Rewrite the table and its indexes: 2 parallel index builds, wait at most 60 s for locks
pg_repack -h localhost -U postgres -d mydb --table=public.orders --jobs=2 --wait-timeout=60 --no-kill-backend
# Rebuild indexes only
pg_repack -h localhost -U postgres -d mydb --table=public.orders --only-indexesQué hace
Construye en segundo plano una copia compactada de la tabla, captura los cambios concurrentes en una tabla de log mediante un trigger e intercambia las tablas al final bajo un breve bloqueo ACCESS EXCLUSIVE; a diferencia de VACUUM FULL, no bloquea lecturas/escrituras durante toda la operación.
Cuándo usarlo
Cuando hay que recuperar en un sistema en producción un bloat severo que VACUUM no puede devolver (verificado con pgstattuple).
Precaución
La tabla debe tener una PRIMARY KEY o un índice UNIQUE sobre columnas NOT NULL. Necesita temporalmente un espacio en disco adicional igual al de la tabla más sus índices y genera mucho WAL (lag de réplicas, volumen de archivado). Se necesitan bloqueos ACCESS EXCLUSIVE al inicio y al final; cuando vence --wait-timeout, por defecto se cancelan las consultas en conflicto y, si es necesario, se terminan sus sesiones, mientras que --no-kill-backend omite la tabla en su lugar. No ejecute DDL sobre la tabla de destino mientras se ejecuta. Las versiones del cliente y de la extensión deben coincidir. Si se interrumpe, limpie los restos con DROP EXTENSION pg_repack CASCADE; CREATE EXTENSION pg_repack;