Para devolver espacio al sistema operativo, use VACUUM FULL
. Mientras estás en eso, supongo que corres VACUUM FULL ANALYZE
. Cito el manual :
FULL
Selecciona el vacío "completo", que puede reclamar más espacio , pero lleva mucho más tiempo y bloquea exclusivamente la mesa. Este método también requiere espacio en disco adicional, ya que escribe una nueva copia de la tabla y no libera la copia anterior hasta que se completa la operación. Por lo general, esto solo debe usarse cuando se necesita recuperar una cantidad significativa de espacio desde la tabla.
El énfasis en negrita es mío.
CLUSTER
logra eso también como un efecto colateral.
Plain VACUUM
normalmente no logra su objetivo ( "una o más páginas al final de una tabla totalmente gratis" ). No reordena las filas y solo elimina las páginas vacías del final físico del archivo cuando surge la oportunidad, como lo indica su cita del manual.
Puede obtener páginas vacías al final del archivo físico cuando agrupa INSERT
un lote de filas DELETE
antes de que se agreguen otras tuplas. O puede suceder por coincidencia si se eliminan suficientes filas.
También hay configuraciones especiales que pueden evitar VACUUM FULL
reclamar espacio. Ver:
Prepare páginas vacías al final de una tabla para probar
La columna del sistema ctid
representa la posición física de una fila. Necesitas entender esa columna:
Podemos trabajar con eso y preparar una tabla eliminando todas las filas de la última página:
DELETE FROM tbl t
USING (
SELECT (split_part(ctid::text, ',', 1) || ',0)')::tid AS min_tid
, (split_part(ctid::text, ',', 1) || ',65535)')::tid AS max_tid
FROM tbl
ORDER BY ctid DESC
LIMIT 1
) d
WHERE t.ctid BETWEEN d.min_tid AND d.max_tid;
Ahora, la última página está vacía. Esto ignora las escrituras concurrentes. O usted es el único que escribe en esa tabla o necesita tomar un bloqueo de escritura para evitar interferencias.
La consulta está optimizada para identificar filas calificadas rápidamente. El segundo número de a tid
es el índice de tupla almacenado como sin signo int2
, y 65535
es el máximo para ese tipo ( 2^16 - 1
), por lo que ese es el límite superior seguro.
SQL Fiddle (reutilizando una tabla simple de un caso diferente).
Herramientas para medir el tamaño de la fila / tabla:
Disco lleno
Necesita espacio en el disco para cualquiera de estas operaciones. También existe la herramienta comunitaria pg_repack
como reemplazo de VACUUM FULL
/ CLUSTER
. Evita bloqueos exclusivos, pero también necesita espacio libre para trabajar. El manual:
Requiere espacio libre en disco dos veces más grande que las tablas e índices de destino.
Como último recurso, puede ejecutar un ciclo de volcado / restauración. Eso también elimina toda la hinchazón de tablas e índices. Pregunta estrechamente relacionada:
La respuesta allí es bastante radical. Si su situación lo permite (sin claves externas u otras referencias que impidan la eliminación de filas) y sin acceso simultáneo a la tabla), puede simplemente:
Volcar la tabla al disco conectando desde una computadora remota con mucho espacio en disco ( -a
para --data-only
):
Desde el shell remoto, volcar los datos de la tabla:
pg_dump -h <host_name> -p <port> -t mytbl -a mydb > db_mytbl.sql
En una sesión de pg, TRUNCATE
la tabla:
-- drop all indexes and constraints here for best performance
TRUNCATE mytbl;
Desde el shell remoto, restaure a la misma tabla:
psql -h <host_name> -p <port> mydb -f db_mytbl.sql
-- recreate all indexes and constraints here
Ahora está libre de filas muertas o hinchazón.
¿Pero tal vez puedas tener eso más simple?
¿Puede hacer suficiente espacio en el disco eliminando (moviendo) archivos no relacionados?
¿Pueden VACUUM FULL
las tablas más pequeñas primero, una por una, liberando así suficiente espacio en disco?
¿Se puede ejecutar REINDEX TABLE
o REINDEX INDEX
liberar espacio en disco de índices hinchados?
Hagas lo que hagas, no seas imprudente . En caso de duda, primero haga una copia de seguridad de todo en una ubicación segura.