PostgreSQL verwendet einen Mechanismus namens MVCC (= Multi Version Concurrency Control), um Transaktionen möglichst parallel abarbeiten zu können. Um diese Parallelität zu erreichen, kann es nötig sein, mehrere Versionen einer Zeile zu speichern. Um diesen Platz wiederverwenden zu können, wird üblicherweise VACUUM eingesetzt. Dies gibt aber keinen Platz an das Dateisystem zurück – es macht den Platz lediglich wieder benutzbar. Um den Platz an das Dateisystem zurück zu geben, kann VACUUM FULL verwendet werden. Das Problem dabei ist, dass PostgreSQL für längere Zeit einen exklusiven Table Lock benötigt, was für eine produktive Live-Installation durchaus ein Todesurteil sein kann.

Die Lösung: pg_squeeze

Im Gegensatz zu den bestehenden Befehlen „VACUUM FULL“ oder „CLUSTER“ gibt es bei pg_squeeze kein langes Locking von Tabellen. Während des Prozesses kann sowohl gelesen als auch geschrieben werden. Auch der Wiederherstellungsprozess ist aufgrund eines neuen Ansatzes der Verwendung von Transaction-Log-Dateien und logischer Dekodierung (anstelle von Triggern) sehr effizient, um mögliche Datenänderungen in der wiederherzustellenden Tabelle zu erfassen. Das spart Speicherplatz und IO-Durchsatz und gewährleistet sehr kurze Locking-Zeiten, was pg_squeeze perfekt für unternehmenskritische OLTP Systeme macht.

Wie funktioniert pg_squeeze?
  1. Die Erweiterung wird als Background-Worker-Prozess implementiert – ein Framework, das in PostgreSQL 9.4 eingeführt wurde. Dieses überwacht regelmäßig benutzerdefinierte Tabellen und
  2. wenn es feststellt, dass eine Tabelle den „Bloat-Threshold“ überschritten hat,
  3. wird ein „squeeze“-Prozess automatisch gestartet und die Tabelle neu erstellt.

Der Wiederaufbau geschieht im Hintergrund bei minimalem Speicher- und Rechenaufwand durch die Verwendung der Replication-Logik von PostgreSQL in Verbindung mit der logischen Dekodierung, um mögliche Änderungen der Tabelle, die während des Wiederaufbaus passieren, vom XLOG zu erkennen.

„Bloat“-Schwellenwerte kann der User natürlich frei anpassen (auch pro Tabelle) und die Berechnung passiert mithilfe der postgres-internen Free-Space-Map, wobei auch der Fillfactor berücksichtigt wird. Unter Umständen kann auch die „pgstattuple“-Extension für die Berechnung benutzt werden, wenn sie vorhanden ist. Zusätzlich können Parameter wie „minimum table size“ eingestellt werden, wodurch nicht passende Tabellen ignoriert werden. Auch die Neuanordnung durch Index oder das Verschieben von Tabellen oder Indizes in einen anderen Tablespace sind möglich.

Zum Beitrag