2017-02-02 8 views
3

Running Postgres-9.5. Ich habe einen großen Tisch, den ich mache ALTER TABLE table SET UNLOGGED auf. Ich habe bereits alle Fremdschlüsselbeschränkungen fallengelassen, die auf die Tabelle abzielen, da FK-bezogene Tabellen nicht nicht protokolliert werden können. Die Abfrage dauerte ungefähr 20 Minuten und verbrauchte die gesamte Zeit 100% CPU. Ich kann verstehen, dass es lange dauert, bis ein Tisch geloggt wird, aber es nicht schwer zu machen, es nicht zu protokollieren ... aber ist es das?Postgres SET UNLOGGED dauert eine lange Zeit

Gibt es etwas, was ich tun könnte, um schneller eine Tabelle unlogged zu setzen?

+0

Vielleicht wartet es auf ein Schloss? https://wiki.postgresql.org/wiki/Lock_Monitoring –

+0

Ich überwachte es, indem ich alle paar Sekunden 'pg_stat_activity' abfragen konnte und die' wartende' Spalte nicht als wahr erkannte, außerdem sah ich eine konstant hohe CPU-Auslastung, die darauf hinwies es wartet nicht. Außerdem weiß ich, dass überhaupt keine anderen Abfragen ausgeführt wurden, da es sich um eine isolierte Testdatenbank handelte. – sudo

+0

@NickBarnes Ah, dann ist das die Lösung. Es erscheint mir merkwürdig, dass das Aufzeichnen nicht protokolliert eine Neufassung erfordert, aber ich weiß nicht wirklich, wie Postgres unter der Haube funktioniert. – sudo

Antwort

4

SET UNLOGGED beinhaltet eine Tabelle neu schreiben, so dass Sie für eine große Tabelle erwarten können, dass es eine ganze Weile dauert.

Wie Sie gesagt haben, es scheint nicht so, als ob eine Tabelle UNLOGGED so schwierig sein sollte. Und einfach die Tabelle umwandeln ist nicht das schwierig; der erschwerende Faktor ist die Notwendigkeit, es crashsicher zu machen. Eine UNLOGGED Tabelle enthält eine zusätzliche Datei (init fork), und es gibt keine Möglichkeit, die Erstellung dieser Datei mit dem Rest des Commits zu synchronisieren.

Also stattdessen SET UNLOGGED erstellt eine Kopie der Tabelle, mit einem Init-Gabel angeschlossen, und dann tauscht die neue relfilenode, die das Commit kann atomar behandeln. Eine effizientere Implementierung wäre möglich, aber nicht ohne die Darstellung von nicht gemeldeten Tabellen (die lange vorliegen) oder der Logik hinter COMMIT selbst, die beide für dieses relativ kleine Merkmal als zu aufdringlich angesehen wurden. Sie können die Diskussion hinter dem Design auf der pgsql-hackers list lesen.

Wenn Sie wirklich Downtime minimieren möchten, könnten Sie einen ähnlichen Ansatz wie SET UNLOGGED verwenden: Erstellen Sie eine neue UNLOGGED Tabelle, kopieren Sie alle Datensätze, sperren Sie die alte Tabelle kurz, während Sie die letzten Änderungen synchronisieren, und tauschen Sie die neue Tabelle mit einem RENAME, wenn Sie fertig sind.

Verwandte Themen