Verwenden Sie, um Speicherplatz an das Betriebssystem zurückzugeben VACUUM FULL
. Ich nehme an, du rennst weg, während du dabei bist VACUUM FULL ANALYZE
. Ich zitiere das Handbuch :
FULL
Wählt "volles" Vakuum, das mehr Platz beansprucht , aber viel länger dauert und den Tisch exklusiv sperrt. Diese Methode erfordert außerdem zusätzlichen Speicherplatz, da eine neue Kopie der Tabelle geschrieben und die alte Kopie erst freigegeben wird, wenn der Vorgang abgeschlossen ist. Normalerweise sollte dies nur verwendet werden, wenn eine erhebliche Menge an Speicherplatz innerhalb der Tabelle zurückgefordert werden muss.
Meine kühne Betonung.
CLUSTER
auch das als sicherheitseffekt.
VACUUM
Normalerweise erreicht Plain Ihr Ziel nicht ( "eine oder mehrere Seiten am Ende einer Tabelle sind völlig frei" ). Es werden keine Zeilen neu angeordnet und nur leere Seiten vom physischen Ende der Datei entfernt, wenn sich die Gelegenheit ergibt - wie in Ihrem Zitat aus den Anweisungen im Handbuch angegeben.
Sie können leere Seiten am Ende der physischen Datei erhalten, wenn Sie INSERT
einen Stapel von Zeilen und DELETE
sie, bevor andere Tupel angefügt werden. Oder es kann zufällig passieren, dass genügend Zeilen gelöscht werden.
Es gibt auch spezielle Einstellungen, die möglicherweise verhindern VACUUM FULL
, dass Speicherplatz freigegeben wird. Sehen:
Bereiten Sie leere Seiten am Ende einer Tabelle zum Testen vor
Die Systemspalte ctid
repräsentiert die physische Position einer Zeile. Sie müssen diese Spalte verstehen:
Wir können damit arbeiten und eine Tabelle vorbereiten, indem wir alle Zeilen von der letzten Seite löschen:
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;
Jetzt ist die letzte Seite leer. Dies ignoriert gleichzeitige Schreibvorgänge. Entweder Sie sind der einzige, der in diese Tabelle schreibt, oder Sie müssen eine Schreibsperre aktivieren, um Interferenzen zu vermeiden.
Die Abfrage ist optimiert, um qualifizierende Zeilen schnell zu identifizieren. Die zweite Zahl von a tid
ist der Tupelindex, der als vorzeichenlos gespeichert ist int2
, und 65535
ist das Maximum für diesen Typ ( 2^16 - 1
), das ist also die sichere Obergrenze.
SQL Fiddle (Wiederverwenden einer einfachen Tabelle aus einem anderen Fall.)
Tools zum Messen der Zeilen- / Tabellengröße:
Festplatte voll
Für diese Vorgänge benötigen Sie Wackelspielraum auf der Festplatte. Es gibt auch das Community-Tool pg_repack
als Ersatz für VACUUM FULL
/ CLUSTER
. Es vermeidet exklusive Sperren, benötigt aber auch freien Speicherplatz zum Arbeiten. Das Handbuch:
Benötigt freien Speicherplatz, der doppelt so groß ist wie die Zieltabelle (n) und -indizes.
Als letzte Möglichkeit können Sie einen Dump- / Wiederherstellungszyklus ausführen. Dadurch wird auch das Aufblähen von Tabellen und Indizes beseitigt. Eng verwandte Frage:
Die Antwort da drüben ist ziemlich radikal. Wenn Ihre Situation dies zulässt (keine Fremdschlüssel oder anderen Referenzen, die das Löschen von Zeilen verhindern) und kein gleichzeitiger Zugriff auf die Tabelle, können Sie einfach:
Kopieren Sie die Tabelle von einem Remotecomputer mit viel Speicherplatz auf die Festplatte ( -a
für --data-only
):
Sichern Sie die Tabellendaten von der Remote-Shell aus:
pg_dump -h <host_name> -p <port> -t mytbl -a mydb > db_mytbl.sql
In einer pg-Sitzung ist TRUNCATE
die Tabelle:
-- drop all indexes and constraints here for best performance
TRUNCATE mytbl;
Stellen Sie von der Remote-Shell aus dieselbe Tabelle wieder her:
psql -h <host_name> -p <port> mydb -f db_mytbl.sql
-- recreate all indexes and constraints here
Es ist jetzt frei von toten Reihen oder Blähungen.
Aber vielleicht können Sie das einfacher haben?
Können Sie genügend Speicherplatz auf der Festplatte schaffen, indem Sie nicht verwandte Dateien löschen (verschieben)?
Können Sie VACUUM FULL
zuerst die Tabellen einzeln verkleinern, um so genügend Speicherplatz freizugeben?
Können Sie ausführen REINDEX TABLE
oder REINDEX INDEX
Speicherplatz von aufgeblähten Indizes freigeben?
Was auch immer Sie tun, seien Sie nicht unbesonnen . Wenn Sie Zweifel haben, sichern Sie alles zuerst an einem sicheren Ort.
update table set field_1 = field_1
, aber beim Staubsaugen dieser Tabelle nach diesem Vorgang wurde kein freier Speicherplatz zurückgegeben. Irgendwelche Ideen?