Necesito ejecutar VACUUM FULL sin espacio en disco disponible


27

Tengo una tabla que ocupa cerca del 90% del espacio en HD en nuestro servidor. He decidido dejar caer algunas columnas para liberar espacio. Pero necesito devolver el espacio al sistema operativo. Sin embargo, el problema es que no estoy seguro de qué sucederá si ejecuto VACUUM FULL y no hay suficiente espacio libre para hacer una copia de la tabla.

Entiendo que VACUUM FULL no debe usarse, pero pensé que era la mejor opción en este escenario.

Cualquier idea sería apreciada.

Estoy usando PostgreSQL 9.0.6

Respuestas:


19

Como no tiene suficiente espacio para ejecutar un vacío o reconstruir, siempre puede reconstruir sus bases de datos postgresql al restaurarlas. Restaurar las bases de datos, tablas, índices liberará espacio y desfragmentará. Luego, puede configurar el mantenimiento automatizado para aspirar sus bases de datos de forma regular.

1 Haga una copia de seguridad de todas las bases de datos en su servidor postgresql

Deberá hacer una copia de seguridad de todas sus bases de datos en una partición que tenga suficiente espacio. Si estaba en Linux, puede usar gzip para comprimir aún más la copia de seguridad para ahorrar espacio

su - postgres
pg_dumpall | gzip -9 > /some/partition/all.dbs.out.gz

2 Copia de seguridad de sus archivos de configuración

cp /path/to/postgresql/data_directory/*.conf /some/partition/

3 Detener Postgresql

pg_ctl -D /path/to/postgresql/data_directory stop

4 borra el contenido del directorio de datos

rm -Rf /path/to/postgresql/data_directory/*

5 Ejecute initdb para reinitalizar su directorio de datos

initdb -D /path/to/postgresql/data_directory

6 Restaurar archivos de configuración

cp /some/partition/*.conf /path/to/postgresql/data_directory/*.conf 

7 Iniciar Postgresql

pg_ctl -D /path/to/postgresql/data_directory start

8 Restaura el volcado de todas las bases de datos que hiciste

gunzip /some/partition/all.dbs.out.gz
psql -f /some/partition/all.dbs.out

1
Gracias, esto es lo que terminé haciendo, con un par de diferencias. Acabo de soltar la base de datos después de hacer una copia de seguridad. Luego creó uno nuevo y lo restauró.
Justin

De nada. Sin embargo, supuse que eliminar el contenido del directorio de datos y hacer initdb habría sido suficiente.
Craig Efrein

Funcionó muy bien, solo recomiendo omitir la gzipparte para ahorrar tiempo.
Rafael Barbosa

17

NOTA: He probado esto en 9.1. No tengo un servidor 9.0 por aquí. Sin embargo, estoy bastante seguro de que funcionará en 9.0.


PRECAUCIÓN (Como se señaló en los comentarios de @erny):

Note that high CPU load due to I/O operations may be expected.

Puede hacer esto prácticamente sin tiempo de inactividad utilizando un espacio de tabla temporal. El tiempo de inactividad será en forma de bloqueos exclusivos. Pero solo en la mesa estás aspirando. Entonces, todo lo que sucederá es que las consultas de los clientes simplemente esperarán a que se obtenga el bloqueo si acceden a la tabla en cuestión. No necesita cerrar las conexiones existentes.

Sin embargo, una cosa a tener en cuenta es que mover la mesa y la aspiradora por completo deberán esperar primero un bloqueo exclusivo.


Primero, obviamente necesitas algo de almacenamiento adicional. Como se Stéphanemenciona en los comentarios, esto debe ser al menos dos veces más grande que la tabla en cuestión, al igual VACUUM FULLque una copia completa. Si tiene suerte y puede agregar dinámicamente un disco a la máquina, hágalo. ¡En el peor de los casos, solo puede conectar un disco USB (aunque arriesgado y lento)!

A continuación, monte el nuevo dispositivo y póngalo a disposición como espacio de tabla:

CREATE TABLESPACE tempspace LOCATION '/path/to/new/folder';

Puede enumerar los espacios de tabla fácilmente usando:

\db

Vuelva a verificar el espacio de tabla actual de su tabla (necesita saber dónde moverlo de nuevo):

SELECT tablespace FROM pg_tables WHERE tablename = 'mytable';

Si es así NULL, estará en el espacio de tabla predeterminado:

SHOW default_tablespace;

Si eso es NULLasí, probablemente lo será pg_default(consulte los documentos oficiales en caso de que se modifique).

Ahora mueva la mesa sobre:

ALTER TABLE mytable SET TABLESPACE tempspace;
COMMIT;  -- if autocommit is off

Aspirarlo:

VACUUM FULL mytable;

Muévelo hacia atrás:

-- assuming you are using the defaults, the tablespace will be "pg_default".
-- Otherwise use the value from the SELECT we did earlier.
ALTER TABLE mytable SET TABLESPACE pg_default;
COMMIT;  -- if autocommit is off

Eliminar el espacio temporal:

DROP TABLESPACE tempspace;

NB: el movimiento parece utilizar más espacio en disco en el directorio de datos original ...
Chris Withers

Solo lo probé en 9.3 y funciona a la perfección.
Bartek Jablonski

Utilizado con éxito en producción en 9.1. Después de cambiar el espacio de tabla, se libera el espacio utilizado original. Tenga en cuenta que se puede esperar una alta carga de CPU debido a las operaciones de E / S.
erny

2
Consejos increíbles, gracias por esta explicación detallada. Tenga en cuenta que en el espacio de tabla temporal necesitará al menos size of table x 2, ya que VACUUM FULLestá haciendo una copia completa de la tabla.
Stéphane

Gracias @ Stéphane. Agregué la información al cuerpo principal.
exhuma

2

Rápido y sucio:

  • Stop Postgres
  • Mueva el directorio principal de la base de datos a otro disco donde haya suficiente espacio para pasar la aspiradora.
  • En la ubicación original de main, agregue un enlace simbólico a la nueva ubicación
  • Vacío
  • Elimine el enlace simbólico y mueva el directorio principal a su ubicación original
  • Iniciar Postgres

P.ej,:

$ service postgresql stop $ mv /var/lib/postgresql/9.5/main /mnt/bigdisk $ ln -sr /mnt/bigdisk/main /var/lib/postgresql/9.5 $ vacuumdb --all --full $ rm /var/lib/postgresql/9.5/main $ mv /mnt/bigdisk/main /var/lib/postgresql/9.5 $ service postgresql start


0

Si tiene espacio en el disco para realizar un volcado y restaurar, debe tener espacio en el disco para hacer un vacíodb --full. El problema es que vacuumdb --full hará una copia de todo el archivo de datos. Entonces, lo que podrías hacer es:

  1. copie los archivos que contienen la gran tabla en una unidad diferente, por ejemplo, una unidad más lenta y más grande.
  2. haga enlaces simbólicos desde la ubicación original al nuevo lugar en la otra unidad.
  3. ejecute vacuumdb --full, ahora debería leer los datos del otro disco y escribir la tabla final en su disco de datos original.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.