Devo eseguire VACUUM FULL senza spazio su disco disponibile


27

Ho un tavolo che occupa quasi il 90% dello spazio hd sul nostro server. Ho deciso di eliminare alcune colonne per liberare spazio. Ma devo restituire lo spazio al sistema operativo. Il problema, tuttavia, è che non sono sicuro di cosa accadrà se eseguo VACUUM FULL e non c'è abbastanza spazio libero per fare una copia della tabella.

Capisco che VACUUM FULL non dovrebbe essere usato ma ho pensato che fosse l'opzione migliore in questo scenario.

Qualsiasi idea sarebbe apprezzata.

Sto usando PostgreSQL 9.0.6

Risposte:


19

Dato che non hai abbastanza spazio per eseguire un vuoto o ricostruire, puoi sempre ricostruire i tuoi database postgresql ripristinandoli. Il ripristino di database, tabelle, indici consentirà di liberare spazio e deframmentare. Successivamente, è possibile impostare la manutenzione automatizzata per svuotare regolarmente i database.

1 Eseguire il backup di tutti i database sul server postgresql

È consigliabile eseguire il backup di tutti i database in una partizione che disponga di spazio sufficiente. Se eri su Linux, puoi usare gzip per comprimere ulteriormente il backup per risparmiare spazio

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

2 Eseguire il backup dei file di configurazione

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

3 Stop Postgresql

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

4 cancella il contenuto della directory dei dati

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

5 Eseguire initdb per reinizializzare la directory dei dati

initdb -D /path/to/postgresql/data_directory

6 Ripristina i file di configurazione

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

7 Avviare Postgresql

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

8 Ripristinare il dump di tutti i database creati

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

1
Grazie, questo è quello che ho finito per fare, con un paio di differenze. Ho appena lasciato cadere il database dopo averlo eseguito il backup. Quindi ne ha creato uno nuovo e lo ha ripristinato.
Giustino,

Prego. Ho pensato che rimuovere il contenuto della directory dei dati e fare initdb sarebbe stato sufficiente.
Craig Efrein,

Ha funzionato alla grande, consiglio solo di saltare la gzipparte per risparmiare tempo.
Rafael Barbosa,

17

NOTA: l'ho provato su 9.1. Non ho un server 9.0 in giro qui. Sono sicuro che funzionerà comunque su 9.0.


ATTENZIONE (Come notato nei commenti di @erny):

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

Puoi farlo praticamente senza downtime utilizzando uno spazio tabella temporaneo. Il tempo morto sarà sotto forma di blocchi esclusivi. Ma solo sul tavolo stai aspirando. Quindi tutto ciò che accadrà è che le query dei client aspetteranno semplicemente l'acquisizione del blocco se accedono alla tabella in questione. Non è necessario chiudere le connessioni esistenti.

Una cosa da tenere presente, però, è che spostare il tavolo e il vuoto pieno dovrà prima aspettare un blocco esclusivo!


Innanzitutto, è ovviamente necessario ulteriore spazio di archiviazione. Come Stéphanemenzionato nei commenti, questo deve essere almeno il doppio della tabella in questione rispetto a VACUUM FULLuna copia completa. Se sei fortunato e puoi aggiungere dinamicamente un disco alla macchina, fallo. Nel peggiore dei casi puoi semplicemente collegare un disco USB (rischioso e lento però)!

Successivamente, monta il nuovo dispositivo e rendilo disponibile come tablespace:

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

Puoi elencare facilmente i tablespace usando:

\db

Controlla nuovamente il tablespace corrente del tuo tavolo (devi sapere dove spostarlo di nuovo):

SELECT tablespace FROM pg_tables WHERE tablename = 'mytable';

Se lo è NULL, sarà nello spazio tabelle predefinito:

SHOW default_tablespace;

Se quello è NULLcosì, sarà probabilmente pg_default(controllare la documentazione ufficiale , in caso è cambiato).

Ora sposta il tavolo sopra:

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

Vuoto:

VACUUM FULL mytable;

Sposta indietro:

-- 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

Rimuovi lo spazio temporaneo:

DROP TABLESPACE tempspace;

NB: la mossa sembra utilizzare più spazio su disco nella directory dei dati originale ...
Chris Withers,

L'ho appena provato su 9.3 e funziona come un fascino.
Bartek Jablonski,

Utilizzato con successo in produzione il 9.1. Dopo aver modificato il tablespace viene rilasciato lo spazio utilizzato originale. È possibile prevedere un carico elevato della CPU dovuto alle operazioni di I / O.
erny,

2
Suggerimenti incredibili, grazie per questa spiegazione dettagliata. Si noti che sul tablespace temporaneo è necessario almeno size of table x 2, poiché VACUUM FULLsta eseguendo una copia completa della tabella.
Stéphane

Grazie @ Stéphane. Ho aggiunto le informazioni al corpo principale.
exhuma,

2

Veloce e sporco:

  • Stop Postgres
  • Spostare la directory del database principale su un altro disco in cui vi sia spazio sufficiente per l'aspirazione
  • Nella posizione originale di main, aggiungi un link simbolico alla nuova posizione
  • Vuoto
  • Elimina il collegamento simbolico e sposta la directory principale nella posizione originale
  • Inizia Postgres

Per esempio,:

$ 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

Se si dispone dello spazio su disco per eseguire il dump e il ripristino, è necessario disporre dello spazio su disco per eseguire un vacuumdb --full. Il problema è che vacuumdb --full farà una copia dell'intero file di dati. Quindi, quello che potresti fare è:

  1. copia i file che contengono l'enorme tabella su un'unità diversa, ad esempio un'unità più lenta e più grande.
  2. creare collegamenti simbolici dalla posizione originale alla nuova posizione sull'altra unità.
  3. eseguire vacuumdb --full, ora dovrebbe leggere i dati dall'altro disco e scrivere la tabella finale sul disco dati originale.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.