Wie kann man Speicherplatz auf PostgreSQL zurückgewinnen?

25

Ich habe lokale Installation der Datenbank 9.1 mit wenigen Tabellen, die cca hatten. 300 Millionen Datensätze und die Datenbank wuchs auf etwa 20 GB. Danach gab ich den delete fromBefehl, alle Datensätze daraus zu löschen (ich hätte verwenden sollen truncate, aber ich wusste das nicht). Also habe ich mein db voll aufgesaugt, um Speicherplatz freizugeben, aber es hilft einfach nicht. Mein Problem sieht genauso aus wie dieses , aber es gibt keine Lösung. Ich habe diesen Thread und die Dokumentation zum Thema "Wiederherstellen von Speicherplatz" bereits überprüft , kann aber immer noch keine Lösung finden. Ich benutze diesen Code, um die Größe aller Tabellen zu ermitteln

 SELECT nspname || '.' || relname AS "relation",
 pg_size_pretty(pg_total_relation_size(C.oid)) AS "total_size"
 FROM pg_class C
 LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
 WHERE nspname NOT IN ('pg_catalog', 'information_schema')
 AND C.relkind <> 'i'
 AND nspname !~ '^pg_toast'
 ORDER BY pg_total_relation_size(C.oid) DESC
 LIMIT 15;

Insgesamt jedoch weniger als 1 GB

SELECT pg_database.datname, pg_size_pretty(pg_database_size(pg_database.datname)) AS size FROM pg_database 

zeigt immer noch etwa 20 GB. Jeder Rat sehr geschätzt.

Gemeinschaft
quelle
Nun, Ihre Größenabfrage schließt aus: Indizes, Tabellen in pg_catalogund Tabellen in information_schema. Versuchen Sie also herauszufinden, ob es sich um eine solche handelt, indem Sie diese Einschränkungen in der WHEREKlausel entfernen . Bitte zeigen Sie Ihre genaue PostgreSQL-Version ( SELECT version()) und was genau Sie tun, um "die gesamte Datenbank zu vakuumieren", dh den genauen Befehl. Führen Sie nach Möglichkeit VACUUM FULL VERBOSE;(keine Argumente) aus und fügen Sie die Ausgabe irgendwo ein. Verknüpfen Sie sie dann hier.
Craig Ringer
Versuchen Sie, die Datenbank zu löschen. Sie können auch versuchen, die Datenbank zu sichern. Wenn Sie sie dann wiederherstellen, wird der Müll gelöscht.
jb.
1
@jb Das würde funktionieren, sollte aber nicht nötig sein. Besser zu lernen, was das Problem ist.
Craig Ringer

Antworten:

22

Obwohl Sie dies nicht angegeben haben, gehe ich davon aus, dass Sie aus Ihren Verweisen auf Dokumente, denen Sie gefolgt sind, ein VACUUM FULL für die Datenbank und / oder die betroffenen Tabellen durchgeführt haben. Sie haben auch nicht angegeben, welche postgresql-Version Sie verwenden - ich gehe davon aus, dass sie> 9.0 ist (VACUUM FULL hat sich zuvor anders verhalten).

VACUUM FULL schreibt die betroffenen Tabellen in neue Dateien und löscht die alten Dateien. Wenn jedoch bei einem Prozess die alte Datei noch geöffnet ist, löscht das Betriebssystem die Datei erst, wenn der letzte Prozess sie geschlossen hat.

Wenn möglich, würde ein Neustart der Datenbank sicherstellen, dass alle geöffneten Dateien geschlossen werden.

Wenn dies nicht praktikabel ist, können Sie möglicherweise überprüfen, ob dies Ihr Problem ist, und herausfinden, bei welchem ​​Prozess die Dateien geöffnet sind.

Wenn Sie Linux (oder die meisten anderen Unix-ähnlichen Systeme) verwenden, können Sie den Befehl 'lsof' verwenden, um eine Liste aller Dateien zu erhalten, die in allen Prozessen geöffnet sind. Dateien, die geöffnet sind, aber inzwischen gelöscht wurden, werden an den Dateinamen mit '(gelöscht)' angehängt. So können Sie die Ausgabe von lsof durchsuchen und nach gelöschten Dateien suchen, wie folgt:

sudo lsof -u postgres | grep 'deleted'

Wenn dies Prozesse identifiziert, bei denen die alten Dateien noch geöffnet sind, können Sie diesen Prozess mit pg_terminate_backend beenden:

SELECT pg_terminate_backend(xxx);

Dabei ist xxx die PID des Prozesses, die in der Ausgabe von lsof angegeben ist.

Unter Windows kann dasselbe Prinzip gelten, da postgres Dateien mit dem Flag FILE_SHARE_DELETE öffnet, mit dem Dateien gelöscht werden können, die in einem anderen Prozess geöffnet sind. Der Befehl ' handle ' entspricht ungefähr dem Befehl lsof, obwohl ich nicht sicher bin, ob Sie feststellen können, ob die Dateien gelöscht wurden oder nicht, sodass möglicherweise zusätzliche Arbeit erforderlich ist.

Es ist eine andere Frage, warum solche Prozesse an alten Dateihandles hängen bleiben. In dem Thread, den Sie in Ihrer Frage zitiert haben, scheint Tom Lane jedoch zu implizieren, dass dies passieren kann.

schädlich
quelle
Ich musste dringend Speicherplatz zurückbekommen, also löschte ich die Datenbank und stellte sie von der Unterstützung wieder her. Die Vorgehensweise zur Lösung dieses Problems ist jedoch für zukünftige Fälle immer noch von großem Wert. Meine Datenbank ist 9.1, Win 8 64 Bit. Gilt der Dateiname (bei geöffneten Dateien) genauso wie unter Linux?
@arcull OK, ich wusste nicht, dass Sie Windows verwenden. Ich habe der Antwort einige Informationen hinzugefügt, wie dies auf Windows zutrifft. Wenn Sie der Meinung sind, dass dies eine nützliche Antwort sein könnte, sollten Sie eine Abstimmung in Erwägung ziehen, da dies anderen das Auffinden erleichtert.
Harmic