Ich muss VACUUM FULL ohne verfügbaren Speicherplatz ausführen


27

Ich habe eine Tabelle, die fast 90% des Festplattenspeichers auf unserem Server belegt. Ich habe beschlossen, ein paar Spalten abzulegen, um Speicherplatz freizugeben. Aber ich muss den Speicherplatz an das Betriebssystem zurückgeben. Das Problem ist jedoch, dass ich nicht sicher bin, was passieren wird, wenn ich VACUUM FULL ausführe und nicht genügend Speicherplatz vorhanden ist, um eine Kopie der Tabelle zu erstellen.

Ich verstehe, dass VACUUM FULL nicht verwendet werden sollte, aber ich dachte, es sei die beste Option in diesem Szenario.

Irgendwelche Ideen würden geschätzt.

Ich benutze PostgreSQL 9.0.6

Antworten:


19

Da Sie nicht genügend Speicherplatz haben, um ein Vacumm auszuführen oder neu zu erstellen, können Sie Ihre postgresql-Datenbanken jederzeit neu erstellen, indem Sie sie wiederherstellen. Durch das Wiederherstellen der Datenbanken, Tabellen und Indizes wird Speicherplatz freigegeben und eine Defragmentierung durchgeführt. Anschließend können Sie eine automatische Wartung einrichten, um Ihre Datenbanken regelmäßig zu durchsuchen.

1 Sichern Sie alle Datenbanken auf Ihrem postgresql-Server

Sie möchten alle Ihre Datenbanken auf einer Partition sichern, die über genügend Speicherplatz verfügt. Wenn Sie unter Linux arbeiten, können Sie das Backup mit gzip weiter komprimieren, um Speicherplatz zu sparen

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

2 Sichern Sie Ihre Konfigurationsdateien

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

3 Beenden Sie Postgresql

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

4 Löschen Sie den Inhalt des Datenverzeichnisses

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

5 Führen Sie initdb aus, um Ihr Datenverzeichnis neu zu initialisieren

initdb -D /path/to/postgresql/data_directory

6 Stellen Sie die Konfigurationsdateien wieder her

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

7 Starten Sie Postgresql

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

8 Stellen Sie den Speicherauszug aller von Ihnen erstellten Datenbanken wieder her

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

1
Danke, das habe ich mit ein paar Unterschieden gemacht. Ich habe die Datenbank gerade gelöscht, nachdem ich sie gesichert habe. Dann ein neues erstellt und wiederhergestellt.
Justin

Bitte. Ich dachte, dass das Entfernen des Inhalts des Datenverzeichnisses und das Ausführen von initdb ausreichend gewesen wäre.
Craig Efrein

Hat super funktioniert, ich empfehle nur, das gzipTeil zu überspringen , um Zeit zu sparen.
Rafael Barbosa

17

HINWEIS: Ich habe dies am 9.1 getestet. Ich habe keinen 9.0 Server hier rumliegen. Ich bin mir aber sicher, dass es mit 9.0 funktionieren wird.


VORSICHT (Wie in den Kommentaren von @erny vermerkt):

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

Sie können dies so gut wie ohne Ausfallzeit tun, indem Sie einen temporären Tablespace verwenden. Die Ausfallzeit erfolgt in Form von exklusiven Sperren. Aber nur auf dem Tisch saugen Sie. Alles, was passiert, ist, dass Client-Abfragen einfach darauf warten, dass die Sperre aktiviert wird wenn sie auf die betreffende Tabelle zugreifen. Sie müssen vorhandene Verbindungen nicht schließen.

Eines ist jedoch zu beachten: Wenn Sie den Tisch bewegen und das Vakuum voll ist, müssen Sie zunächst auf ein exklusives Schloss warten!


Zunächst benötigen Sie offensichtlich zusätzlichen Speicherplatz. Wie Stéphanein den Kommentaren erwähnt, muss diese mindestens doppelt so groß wie die betreffende Tabelle sein, wie VACUUM FULLdies bei einer vollständigen Kopie der Fall ist. Wenn Sie Glück haben und der Maschine dynamisch eine Festplatte hinzufügen können, tun Sie dies. Im schlimmsten Fall können Sie einfach ein USB-Laufwerk anschließen (riskant und langsam)!

Hängen Sie als Nächstes das neue Gerät ein und stellen Sie es als Tablespace zur Verfügung:

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

Sie können die Tablespaces einfach auflisten, indem Sie Folgendes verwenden:

\db

Überprüfen Sie den aktuellen Tablespace Ihrer Tabelle (Sie müssen wissen, wohin Sie ihn zurück verschieben können):

SELECT tablespace FROM pg_tables WHERE tablename = 'mytable';

Wenn dies der NULLFall ist , wird der Standardtabellenbereich verwendet:

SHOW default_tablespace;

Wenn das auch so ist NULL, wird es wahrscheinlich sein pg_default(überprüfen Sie die offiziellen Dokumente, falls es geändert wird).

Bewegen Sie nun den Tisch über:

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

Staubsaugen:

VACUUM FULL mytable;

Verschiebe es zurück:

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

Entfernen Sie den temporären Speicherplatz:

DROP TABLESPACE tempspace;

NB: Der Umzug scheint mehr Speicherplatz im ursprünglichen Datenverzeichnis zu belegen ...
Chris Withers

Habe es gerade auf 9.3 getestet und es funktioniert wie Charme.
Bartek Jablonski

Erfolgreich eingesetzt in der Produktion am 9.1. Nach dem Ändern des Tablespace wird der ursprünglich verwendete Speicherplatz freigegeben. Beachten Sie, dass eine hohe CPU-Last aufgrund von E / A-Vorgängen zu erwarten ist.
Erny

2
Tolle Tipps, danke für diese ausführliche Erklärung. Beachten Sie, dass Sie für den temporären Tablespace mindestens benötigen size of table x 2, da VACUUM FULLeine vollständige Kopie der Tabelle erstellt wird.
Stéphane

Danke @ Stéphane. Ich habe die Informationen zum Hauptteil hinzugefügt.
Exhuma

2

Schnell und dreckig:

  • Stoppen Sie Postgres
  • Verschieben Sie das Hauptdatenbankverzeichnis auf einen anderen Datenträger, auf dem ausreichend Platz zum Staubsaugen vorhanden ist
  • Fügen Sie am ursprünglichen Speicherort von main einen Symlink zum neuen Speicherort hinzu
  • Vakuum
  • Löschen Sie den Symlink und verschieben Sie das Hauptverzeichnis wieder an seinen ursprünglichen Speicherort
  • Starten Sie Postgres

Z.B,:

$ 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

Wenn Sie über den Festplattenspeicher verfügen, um einen Speicherauszug zu erstellen und wiederherzustellen, sollten Sie über den Festplattenspeicher verfügen, um ein Vakuum-DB-FULL durchzuführen. Das Problem ist, dass vacuumdb --full eine Kopie der gesamten Datendatei erstellt. Was Sie also tun könnten, ist:

  1. Kopieren Sie die Dateien, die die große Tabelle enthalten, auf ein anderes Laufwerk, z. B. ein langsameres, größeres Laufwerk.
  2. Stellen Sie symbolische Links vom ursprünglichen Speicherort zum neuen Speicherort auf dem anderen Laufwerk her.
  3. Führen Sie vacuumdb --full aus. Jetzt sollten die Daten von der anderen Festplatte gelesen und die endgültige Tabelle auf die ursprüngliche Festplatte geschrieben werden.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.