- In PostgreSQL werden beim
DROP einer Spalte die Daten nicht tatsächlich gelöscht — sie werden in den Metadaten lediglich „versteckt“
- Weil die Spalte nach
DROP COLUMN intern weiterhin existiert, kann man das Limit von 1600 Spalten erreichen
- Um die Daten vollständig zu entfernen, ist
VACUUM FULL oder ein manuelles Umschreiben der Tabelle nötig
- Das ist ein Design zur Performance-Optimierung, erfordert aber aus Compliance-Sicht wie bei der DSGVO besondere Aufmerksamkeit
- Wenn man versteht, „was tatsächlich passiert“, ist das bei Fehlerbehebung, Performance-Optimierung und Datenmanagement von Vorteil
Wie DROP COLUMN in PostgreSQL tatsächlich funktioniert
Das Problem: Was passiert, wenn man Spalten wiederholt hinzufügt und löscht?
Was passiert intern in PostgreSQL?
Das Löschen einer Spalte ist keine „echte Löschung“
- PostgreSQL speichert Daten in 8-KB-Seiten
- Um eine Spalte physisch zu löschen, müsste die gesamte Tabelle neu geschrieben werden, was ineffizient ist
- Stattdessen wird die Spalte in den Metadaten als „dropped“ markiert und ignoriert
Über die Systemtabelle pg_attribute nachvollziehbar
SELECT attnum, attname, attisdropped FROM pg_attribute WHERE attrelid = 'test2'::regclass AND attnum > 0;
Im Datenfile prüfen (pg_filedump verwenden)
- Analysiert man PostgreSQL-Datenfiles, sieht man, dass die Werte gelöschter Spalten tatsächlich erhalten bleiben
- In älteren Daten (
Item 1) sind Werte für 3 Spalten vorhanden
- In nach dem Löschen eingefügten Daten (
Item 3) fehlt der Wert der betreffenden Spalte und wird als NULL behandelt
Wie man gelöschte Spalten tatsächlich entfernt
1. VACUUM FULL
- Dabei wird die gesamte Tabelle neu geschrieben und auch die Daten gelöschter Spalten entfernt
- Nachteil: Die Spalte selbst existiert in
pg_attribute weiterhin im Status „dropped“
2. Manuelles Umschreiben der Tabelle
DROP COLUMN und das DSGVO-Problem des „Rechts auf Vergessenwerden“
Wichtige Hinweise
- PostgreSQL arbeitet mit MVCC, daher bleiben Daten nach dem Löschen einer Zeile erhalten, bis
VACUUM abgeschlossen ist
- Auch auf Betriebssystemebene kann es sich nicht um physisches Löschen, sondern nur um ein „Delete-Flag“ handeln
- Rechtlich wichtig ist meist ein „angemessener Löschaufwand“; ein vollständiges physisches Überschreiben der Festplatte wird in den meisten Fällen nicht verlangt
Fazit: DROP COLUMN ist nur „Verstecken“, nicht „Löschen“
- Das ist ein auf Performance ausgelegtes Design, aber wenn sich Spalten ansammeln, kann man an das Limit von 1600 Spalten stoßen
- Falls nötig, sollte man die Daten mit
VACUUM FULL oder durch Umschreiben der Tabelle bereinigen
- Für Systemdesign und Compliance ist ein Verständnis der internen Funktionsweise von PostgreSQL sehr hilfreich
Referenzen
3 Kommentare
Die Perspektive ist aufschlussreich, dass sich Implementierungsentscheidungen zur Performance-Optimierung auch mit der GDPR-Problematik des Rechts auf Vergessenwerden verbinden lassen. Entscheidend ist, personenbezogene Daten sauber zu modellieren und zu löschen, weshalb man sogar zu dem Schluss kommt, dass es damit nichts zu tun hat. Sauber.
Obwohl
postgresqlin letzter Zeit sehr beliebt ist, bevorzuge ich bei der MVCC-Implementierung eher einen Ansatz, bei dem Redo-/Undo-Bereiche getrennt existieren.Da man bei Redo-/Undo-Bereichen eine gewisse Einbuße bei der Echtzeitfähigkeit in Kauf nehmen kann, gibt es auch Spielraum zur Kostenoptimierung, indem man Storage mit niedrigerer Leistungsklasse verwendet.
Auch der Umstand, dass man irgendwann die gesamte DB sperren und
VACUUM FULLausführen muss, ist für mich ein Minuspunkt.Muss man
VACUUM FULLirgendwann zwingend ausführen? In den meisten Dokumentationen, die ich gesehen habe, wird eher davon abgeraten.Eine der Quellen, die ich gelesen habe:
https://www.depesz.com/2023/02/06/when-to-use-vacuum-full/