Wie PostgreSQL Daten speichert: Datenbankstruktur und Transaktionsjournal (WAL)
Wenn du mit einer Datenbank arbeitest, wirkt alles erstmal ziemlich easy: Du fügst eine Zeile hinzu, änderst einen Eintrag, löschst einen Kunden. Aber hinter dieser Einfachheit steckt ein ziemlich ausgeklügelter Mechanismus. Wo liegen diese Daten eigentlich wirklich? Wie schafft es PostgreSQL, dass nichts verloren geht, selbst wenn der Server plötzlich abschmiert?
Um das zu checken, musst du zwei Dinge verstehen: Wo liegen die Daten physisch (Tabellen, Indizes, Metainfos) und wie funktioniert der Schutzmechanismus — das Transaktionsjournal, auch WAL (Write-Ahead Logging) genannt.
Die komplette PostgreSQL-Datenbank liegt als Sammlung von Dateien in einem speziellen Verzeichnis — data_directory. Normalerweise findest du das hier:
/var/lib/postgresql/17/main
In diesem Ordner steckt das Herz der Datenbank: Tabellen, Indizes, Metadaten und Einstellungen. Dort liegt auch das WAL-Journal — der Mechanismus, der alle Änderungen zuerst abfängt. Bevor Daten wirklich in die Tabelle auf der Platte geschrieben werden, landen sie im WAL. Das ist wie ein Entwurf, in dem die DB jeden Schritt festhält, damit im Fall eines Crashes alles bis zur letzten Aktion wiederhergestellt werden kann.
Dank diesem Ansatz ist PostgreSQL selbst unter den wildesten Bedingungen zuverlässig und robust.
Tabellen
Jede Tabelle ist physisch eine eigene Datei oder ein Satz von Dateien. Diese Files findest du im Unterordner base/. Die Struktur sieht ungefähr so aus:
$PGDATA/base/
├── 16384/
│ ├── 12345 ← tabelle
│ ├── 12346 ← index
│ └── ...
16384— das ist die interne Datenbank-ID (OID).12345— die ID der jeweiligen Tabelle.
Wenn eine Tabelle groß wird, teilt PostgreSQL sie in 1-GB-Segmente auf:
12345
12345.1
12345.2
...
Die Dateien enthalten keine "Zeilen" wie in einer CSV — das ist ein Binärformat aus 8-KB-Seiten.
WAL: Write-Ahead Logging — mehr als nur ein "Log"
Kommen wir jetzt zu einem der wichtigsten und oft missverstandenen Teile von PostgreSQL — WAL, oder Write-Ahead Logging. Trotz des Wortes Log im Namen ist WAL kein normales Text-Logfile wie Error- oder Query-Logs. Es ist ein lebenswichtiger Mechanismus für Konsistenz und Recovery, der auf Low-Level-Dateisystemänderungen arbeitet.
WAL ist kein Event-Report, sondern eine Vorab-Aufzeichnung aller Änderungen, die PostgreSQL an den Daten machen will. Diese Aufzeichnung passiert bevor die Tabellen auf der Platte wirklich geändert werden. Daher auch der Name write-ahead — "vorher schreiben".
Wenn du zum Beispiel eine neue Zeile in eine Tabelle einfügst, macht PostgreSQL folgendes:
- Aktualisiert die Tabelle NICHT sofort auf der Platte — das wäre langsam und riskant.
- Schreibt zuerst ins WAL, dass diese Zeile hinzugefügt wird.
- Erst später, wenn es passt (z.B. im Hintergrundprozess), landen die Daten wirklich in der Tabelle.
Das ist wie ein Scheck bei der Bank: Erst unterschreibst du ihn (WAL), und erst danach aktualisiert die Bank das Konto (Tabelle). Wenn was schiefgeht — der Scheck ist noch da und du kannst die Aktion wiederholen.
Format und Struktur von WAL
- WAL-Dateien sind im Binärformat gespeichert.
- Jede Datei ist ein streng geordneter Strom von Operationen, die interne Änderungen an Datenseiten, Indexstrukturen, Commits usw. beschreiben.
- Eine WAL-Datei hat eine feste Größe — standardmäßig 16 MB.
Wichtig: Im WAL stehen keine "SQL-Befehle" oder "Tabellenzeilen" wie du sie kennst. Es sind Instruktionen für die PostgreSQL-Engine, wie Änderungen Seite für Seite nachgebaut werden können.
Was passiert bei einem Crash?
Wenn der PostgreSQL-Server plötzlich ausfällt — zum Beispiel wegen Stromausfall — ist nicht alles verloren. Beim nächsten Start lädt die DB ganz entspannt die letzte gespeicherte „stabile“ Version der Daten von der Platte. Dann nimmt sie das Transaktionsjournal (WAL), in dem alle letzten Änderungen stehen, und „dreht sie nach“ — sie spielt alles durch, was noch nicht in die Hauptdateien geschrieben wurde. Am Ende ist die DB wieder komplett konsistent, als wäre nichts passiert.
Weitere WAL-Features
Point-In-Time Recovery (PITR). Das Aufbewahren von WAL-Dateien macht es möglich, die DB auf jeden beliebigen Zeitpunkt zwischen zwei vollständigen Backups zurückzusetzen.
Streaming Replication. PostgreSQL kann WAL-Einträge in Echtzeit auf einen anderen Server schicken. So kannst du eine heiße Replik betreiben — eine Kopie der DB, die mit dem Original synchron bleibt.
Inkrementelles Recovery. Zusammen mit einem Full-Backup kannst du mit WAL nur die Änderungen wiederherstellen, statt die ganze DB nochmal zu kopieren.
Binäre Backups erstellen: pg_basebackup
Wenn du schon ein bisschen mit pg_dump rumgespielt hast, weißt du: Das ist super für logische Backups (also Struktur und Daten als SQL-Statements). Aber was, wenn du ein physisches Backup brauchst? Zum Beispiel ein komplettes Spiegeln aller Datenbankdateien? Dafür gibt’s das Tool pg_basebackup.
pg_basebackup ist ein Tool, mit dem du physische Kopien deiner PostgreSQL-Daten machen kannst. Besonders praktisch bei großen Datenbanken, wo das Recovery effizient laufen muss. Der große Vorteil von pg_basebackup: Es ist richtig schnell.
Grundsyntax von pg_basebackup
Mit pg_basebackup startest du im Terminal. Die Basis-Command sieht so aus:
pg_basebackup -D /backup_directory -F tar -z -P
Was passiert hier?
-D /backup_directory— gibt das Verzeichnis an, in dem deine Backup-Files landen.-F tar— Datenformat. Die Optiontarerstellt ein Archiv im.tar-Format. Du kannst auchplainnehmen, dann bekommst du die DB als Dateistruktur.-z— komprimiert das Backup, spart also Platz auf der Platte. Immer nice, wenn das Backup weniger Speicher braucht!-P— zeigt den Fortschritt in Echtzeit an. Gibt ein gutes Gefühl: Du siehst, dass was passiert und der Server nicht „hängt“.
Beispiel für die Nutzung:
pg_basebackup -D /backups/university_backup -F tar -z -P
Nach dem Ausführen findest du im angegebenen Verzeichnis /backups/university_backup ein Backup im .tar-Format.
Vorteile von pg_basebackup
Effizienz: Inkrementelle Backups vermeiden das Kopieren unveränderter Daten — spart Zeit und Platz.
Einfache Bedienung: pg_basebackup kümmert sich automatisch um alles, auch um die WAL-Dateien.
Zuverlässigkeit: Durch die Integration mit der PostgreSQL-Mechanik erstellt pg_basebackup exakte Kopien der kompletten DB, die du easy wiederherstellen kannst.
Beispiele aus der Praxis
Jetzt wird’s praktisch. Hier ein paar echte Beispiele, wie du mit pg_basebackup Backups deiner PostgreSQL-DB machen kannst. Wir zeigen, wie du ein Basis-Backup erstellst, wie du Kompression hinzufügst und wie du das WAL-Archiv aktivierst, um ein „Point-in-Time“-Recovery zu ermöglichen. Die Commands sind sowohl für Einsteiger als auch für Fortgeschrittene geeignet.
Ein Basis-Backup erstellen
pg_basebackup -D /backups/full_backup -F tar -z -P
Ergebnis: Ein vollständiges DB-Backup als .tar-Archiv.
Kompression und Format einstellen
Backup mit hohem Kompressionslevel erstellen:
pg_basebackup -D /backups/full_backup -F tar -z -Z 9 -P
Hier gibt -Z 9 das Kompressionslevel an (maximal — 9).
WAL-Archivierung
Wenn du die WAL-Archivierung aktivierst, kannst du die DB auf jeden beliebigen Zeitpunkt zurücksetzen. Der Command für das WAL-Backup:
pg_basebackup -D /backups/incremental_backup -F tar -z -P --wal-method=archive
GO TO FULL VERSION