Per restituire spazio al sistema operativo, utilizzare VACUUM FULL
. Pur essendo lì, suppongo che tu corra VACUUM FULL ANALYZE
. Cito il manuale :
FULL
Seleziona il vuoto "completo", che può recuperare più spazio , ma richiede molto più tempo e blocca esclusivamente il tavolo. Questo metodo richiede anche spazio su disco aggiuntivo, poiché scrive una nuova copia della tabella e non rilascia la vecchia copia fino al completamento dell'operazione. Di solito questo dovrebbe essere usato solo quando è necessario recuperare una quantità significativa di spazio all'interno della tabella.
Enorme enfasi sulla mia.
CLUSTER
raggiunge anche questo come effetto collaterale.
Plain VACUUM
normalmente non raggiungere il tuo obiettivo ( "una o più pagine alla fine di un tavolo completamente liberi" ). Non riordina le righe e elimina solo le pagine vuote dalla fine fisica del file quando si presenta l'opportunità, come indica la tua citazione dal manuale.
Puoi ottenere pagine vuote alla fine del file fisico quando fai INSERT
un batch di righe e DELETE
prima che vengano aggiunte altre tuple. Oppure può succedere per coincidenza se vengono eliminate abbastanza righe.
Ci sono anche impostazioni speciali che potrebbero impedire VACUUM FULL
di recuperare spazio. Vedere:
Preparare le pagine vuote alla fine di una tabella per il test
La colonna di sistema ctid
rappresenta la posizione fisica di una riga. Devi capire quella colonna:
Possiamo lavorare con questo e preparare una tabella eliminando tutte le righe dall'ultima pagina:
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;
Ora, l'ultima pagina è vuota. Ciò ignora le scritture simultanee. O sei l'unico a scrivere su quel tavolo o devi prendere un blocco di scrittura per evitare interferenze.
La query è ottimizzata per identificare rapidamente le righe qualificanti. Il secondo numero di a tid
è l'indice tupla memorizzato come unsigned int2
, ed 65535
è il massimo per quel tipo ( 2^16 - 1
), quindi questo è il limite superiore sicuro.
SQL Fiddle (riutilizzando una tabella semplice da un caso diverso.)
Strumenti per misurare le dimensioni di riga / tabella:
Disco pieno
È necessario spostare spazio su disco per una di queste operazioni. C'è anche lo strumento di comunità pg_repack
in sostituzione di VACUUM FULL
/ CLUSTER
. Evita i blocchi esclusivi ma necessita anche di spazio libero per lavorare. Il manuale:
Richiede spazio libero su disco doppio rispetto alla tabella o alle tabelle di destinazione e agli indici.
Come ultima risorsa, è possibile eseguire un ciclo di dump / ripristino. Ciò rimuove anche tutto il gonfiore da tabelle e indici. Domanda strettamente correlata:
La risposta laggiù è piuttosto radicale. Se la tua situazione lo consente (senza chiavi esterne o altri riferimenti che impediscono l'eliminazione di righe) e nessun accesso simultaneo alla tabella), puoi semplicemente:
Scarica la tabella su disco collegandosi da un computer remoto con molto spazio su disco ( -a
per --data-only
):
Dalla shell remota, scaricare i dati della tabella:
pg_dump -h <host_name> -p <port> -t mytbl -a mydb > db_mytbl.sql
In una sessione PG, TRUNCATE
la tabella:
-- drop all indexes and constraints here for best performance
TRUNCATE mytbl;
Dalla shell remota, ripristina sulla stessa tabella:
psql -h <host_name> -p <port> mydb -f db_mytbl.sql
-- recreate all indexes and constraints here
Ora è libero da file o gonfiori morti.
Ma forse puoi avere quello più semplice?
Puoi fare abbastanza spazio sul disco cancellando (spostando) file non correlati?
Puoi VACUUM FULL
prima tavoli più piccoli, uno per uno, liberando così spazio su disco sufficiente?
Puoi eseguire REINDEX TABLE
o REINDEX INDEX
liberare spazio su disco da indici gonfiati?
Qualunque cosa tu faccia, non essere avventato . In caso di dubbi, eseguire prima il backup di tutto in un luogo sicuro.