¿Cómo reclamar espacio en disco en PostgreSQL?

25

Tengo instalación local de la base de datos 9.1 con pocas tablas que tenían cca. 300 millones de registros y la base de datos creció a unos 20 GB. Luego emití un delete fromcomando para eliminar todos los registros (debería haberlo usado truncate, pero no lo sabía). Así que hice un vacío completo en mi base de datos para recuperar espacio en disco, pero simplemente no ayuda. Mi problema parece idéntico a este , pero no se proporciona ninguna solución. Ya he revisado este hilo y la documentación sobre "recuperar espacio en disco" , pero todavía no puedo encontrar una solución. Yo uso este código para obtener el tamaño de todas las tablas

 SELECT nspname || '.' || relname AS "relation",
 pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size"
 FROM pg_class C
 LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
 WHERE nspname NOT IN ('pg_catalog', 'information_schema')
 AND C.relkind <> 'i'
 AND nspname !~ '^pg_toast'
 ORDER BY pg_total_relation_size(C.oid) DESC
 LIMIT 15;

Sin embargo, totalizando menos de 1 GB

SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname)) AS size FROM pg_database 

todavía muestra unos 20 GB. Cualquier consejo muy apreciado.

Comunidad
fuente
Bueno, su consulta de tamaño excluye: índices, tablas pg_catalogy tablas en information_schema. Así que intente ver si es alguno de esos eliminando esas restricciones en la WHEREcláusula. Muestre su versión exacta de PostgreSQL ( SELECT version()) y qué está haciendo exactamente para "aspirar la base de datos completa", es decir, el comando exacto. Si es posible, ejecute VACUUM FULL VERBOSE;(sin argumentos) y pegue el resultado en algún lugar y luego enlace a él aquí.
Craig Ringer el
Intenta descartar la base de datos. También puede intentar volcar la base de datos y luego restaurarla arrojaría la basura.
jb.
1
@jb Eso funcionaría, pero no debería ser necesario. Es mejor aprender cuál es el problema.
Craig Ringer el

Respuestas:

22

Aunque no lo dijo, asumo por sus referencias a los documentos que ha seguido que ha realizado un VACÍO COMPLETO en la base de datos y / o tablas afectadas. Tampoco especificó qué versión de postgresql está utilizando, supongo que es> 9.0 (VACUUM FULL se comportó de manera diferente antes de esto).

VACUUM FULL reescribirá las tablas afectadas en archivos nuevos y luego eliminará los archivos antiguos. Sin embargo, si algún proceso aún tiene abierto el archivo anterior, el sistema operativo no eliminará el archivo, hasta que el último proceso lo haya cerrado.

Si es práctico, reiniciar la base de datos aseguraría que todos los archivos abiertos se cierren.

Si eso no es práctico, puede verificar si este es su problema y averiguar qué proceso tiene abiertos los archivos.

Si usa Linux (o la mayoría de los otros sistemas similares a Unix), puede usar el comando 'lsof' para obtener una lista de todos los archivos abiertos en todos los procesos. Los archivos que están abiertos pero que han sido eliminados tendrán '(eliminado)' agregado al nombre del archivo. Por lo tanto, puede grep la salida de lsof, buscando archivos eliminados, como este:

sudo lsof -u postgres | grep 'deleted'

Si eso identifica procesos que todavía tienen abiertos los archivos antiguos, puede usar pg_terminate_backend para terminar ese proceso:

SELECT pg_terminate_backend(xxx);

donde xxx es el PID del proceso, que se encuentra en la salida lsof.

Si usa Windows, podría aplicarse el mismo principio, porque postgres abre archivos usando el indicador FILE_SHARE_DELETE, que le permite eliminar archivos que están abiertos en otro proceso. El comando ' manejar ' es el equivalente aproximado de lsof, aunque no estoy seguro de si puede decir si los archivos se eliminan o no, por lo que podría requerirse un trabajo adicional.

Es otra pregunta de por qué cualquiera de estos procesos se quedaría con los antiguos identificadores de archivos. Sin embargo, en el hilo que citó en su pregunta, Tom Lane parece implicar que puede suceder.

harmic
fuente
Tuve que recuperar urgentemente el espacio en disco, así que eliminé la base de datos y la restauré de la copia de seguridad. Sin embargo, el "cómo" resolver este problema sigue siendo muy valioso para futuros casos. Mi base de datos es 9.1, win 8 64 bit, ¿el nombre del archivo (caso de archivos abiertos) se aplica de la misma manera que en Linux?
@arcull OK, no me di cuenta de que estabas usando Windows. Agregué información a la respuesta sobre cómo esto se aplica a Windows. Si cree que podría ser una respuesta útil, considere la posibilidad de votar, ya que facilita que otros la encuentren.
harmic