03 November 2025

PostgreSQL 18 aktiviert standardmäßig Daten-Checksummen

Wie ich in meinem Vortrag auf der PostgreSQL Conference Europe 2025 erläutert habe, kann Datenbeschädigung unbemerkt in jeder PostgreSQL-Datenbank vorhanden sein und bleibt unentdeckt, bis wir beschädigte Daten physisch lesen. Es kann viele Gründe geben, warum einige Datenblöcke in Tabellen oder anderen Objekten beschädigt werden können. Selbst moderne Speicherhardware ist alles andere als unfehlbar. Binäre Backups, die mit dem pg_basebackup-Tool erstellt wurden – einer sehr gängigen Backup-Strategie in der PostgreSQL-Umgebung – lassen diese Probleme verborgen. Denn sie prüfen keine Daten, sondern kopieren ganze Datendateien so, wie sie sind. Mit der Veröffentlichung von PostgreSQL 18 hat die Community beschlossen, Daten-Checksummen standardmäßig zu aktivieren – ein wichtiger Schritt zur frühzeitigen Erkennung dieser Fehler. Dieser Beitrag untersucht, wie PostgreSQL Checksummen implementiert, wie es Checksummenfehler behandelt und wie wir sie auf bestehenden Clustern aktivieren können.

Warum PostgreSQL-Checksummen wichtig sind

Warum Checksummen wichtig sind

Eine PostgreSQL-Tabelle oder ein Index wird in 8-KB-Seiten gespeichert. Wenn eine Seite auf die Festplatte geschrieben wird, berechnet PostgreSQL eine 16-Bit-Checksumme unter Verwendung jedes Bytes der Seite (mit Ausnahme des Checksummenfelds selbst) und der physischen Blockadresse der Seite. Die Checksumme wird im Seitenheader gespeichert. Bei jedem Lesevorgang berechnet PostgreSQL die Checksumme neu und vergleicht sie mit dem gespeicherten Wert. Da die Blockadresse Teil der Berechnung ist, erkennt das System sowohl Bit-Flips innerhalb der Seite als auch Seiten, die an den falschen Ort geschrieben wurden. Checksummen werden nicht verwaltet, während sich die Seite in gemeinsam genutzten Puffern befindet – sie werden nur berechnet, wenn die Seite aus dem Puffer-Cache in den Betriebssystem-Seiten-Cache geleert wird. Folglich kann eine falsche In-Memory-Seite erst erkannt werden, wenn sie geschrieben und wieder gelesen wird. PostgreSQL verwendet einen schnellen FNV-1a-Hash (mit CRC32C auf WAL-Datensätzen), der für die Leistung optimiert ist. Auf typischer Hardware scheinen die Kosten für die Berechnung der Checksumme gering zu sein. Eine Benchmarking-Studie ergab, dass die Strafe für normale Arbeitslasten in der Regel weniger als 2 % beträgt. In den Versionshinweisen zu PostgreSQL 18 wird bestätigt, dass der Overhead nicht Null ist, aber er wird zum Vorteil der Datenintegrität akzeptiert.

Änderungen in PostgreSQL 18
Version 18 aktiviert standardmäßig Daten-Checksummen. In früheren Versionen erforderte initdb das Flag –data-checksums. Die neuen Versionshinweise listen die Änderung explizit im Abschnitt Inkompatibilitäten auf: „Ändern Sie die initdb-Standardeinstellung, um Daten-Checksummen zu aktivieren… Checksummen können mit der neuen Option –no-data-checksums deaktiviert werden“.
Für DBAs hat diese Standardänderung zwei wichtige Konsequenzen:
  • Cluster-Upgrades müssen mit den Checksummen-Einstellungen übereinstimmen (explizit in den PostgreSQL 18-Versionshinweisen erwähnt). Beim Upgrade über pg_upgrade müssen sowohl der Quell- als auch der Zielcluster Checksummen aktiviert oder deaktiviert haben. Wenn Sie von einem älteren Cluster ohne Checksummen aktualisieren müssen, initialisieren Sie den neuen Cluster mit –no-data-checksums oder aktivieren Sie zuerst Checksummen auf dem alten Cluster.
  • Statistiken zur Überwachung von Fehlern – PostgreSQL verfügt bereits über zwei Spalten in pg_stat_database: checksum_failures, die die Anzahl der Seiten zählen, deren Checksummen fehlgeschlagen sind, und checksum_last_failure, den Zeitstempel des letzten Fehlers. Diese Metriken ermöglichen es Ihnen, bei Korruptionsereignissen über alle Datenbanken im Cluster hinweg zu warnen.

Um zu sehen, ob unser Cluster Daten-Checksummen verwendet, überprüfen wir die schreibgeschützte Systemvariable data_checksums mit dem Befehl: „SHOW data_checksums;“ Ein Ergebnis von „ON“ bedeutet, dass Daten-Seiten-Checksummen aktiv sind.

Aktivieren und Deaktivieren von Checksummen mit pg_checksums
Checksummen sind eine Cluster-weite Eigenschaft und können nicht umgeschaltet werden, während der Server läuft. PostgreSQL liefert das pg_checksums-Dienstprogramm zum Überprüfen, Aktivieren oder Deaktivieren von Checksummen. Wichtige Punkte aus der Dokumentation:
  • Der Cluster muss sauber heruntergefahren werden, bevor pg_checksums ausgeführt wird.
  • Das Überprüfen von Checksummen (–check) scannt jede Datei in PGDATA und gibt einen Exit-Code ungleich Null zurück, wenn eine Nichtübereinstimmung gefunden wird.
  • Das Aktivieren von Checksummen (–enable) schreibt jeden Beziehungsblock neu und aktualisiert das Checksummenfeld auf der Festplatte. Das Deaktivieren von Checksummen (–disable) aktualisiert nur die Steuerdatei – es schreibt keine Seiten neu.
  • Optionen wie –progress zeigen den Fortschritt an, –no-sync überspringt fsync nach Änderungen und –filenode beschränkt die Überprüfung auf eine bestimmte Beziehung.
  • Auf großen oder replizierten Clustern kann das Aktivieren von Checksummen lange dauern; alle Standby-Server müssen gestoppt oder neu erstellt werden, damit alle Knoten denselben Checksummenstatus beibehalten (explizit in der Dokumentation erwähnt).
Upgrade-Strategie
Wenn Sie einen Pre-18-Cluster ohne Checksummen aktualisieren, haben wir zwei Optionen:
  • Deaktivieren Sie Checksummen auf dem neuen Cluster: Führen Sie initdb mit –no-data-checksums aus, damit pg_upgrade die Migration zulässt. Nach dem Upgrade können Sie Checksummen offline mit pg_checksums –enable aktivieren.
  • Aktivieren Sie zuerst Checksummen auf dem alten Cluster: Fahren Sie den alten Server herunter, führen Sie pg_checksums –enable -D $PGDATA aus (auf jedem Knoten, wenn Sie Streaming-Replikation verwenden), starten Sie dann den Server und überprüfen Sie den neuen SHOW data_checksums-Wert. Wenn Sie PostgreSQL 18 initialisieren, erbt es den aktivierten Zustand.
Behandlung von Checksummenfehlern
Wenn PostgreSQL eine Checksummen-Nichtübereinstimmung erkennt, gibt es eine Warnung aus und löst einen Fehler aus. Zwei GUCs nur für Entwickler steuern, was als Nächstes geschieht. Sie sollten niemals im Normalbetrieb aktiviert werden, aber DBAs können sie zur Datenwiederherstellung verwenden:
  • ignore_checksum_failure – Wenn deaktiviert (Standard), bricht der Server die aktuelle Transaktion beim ersten Checksummenfehler ab. Wenn es auf on gesetzt ist, protokolliert es eine Warnung und setzt die Verarbeitung fort, sodass Abfragen beschädigte Blöcke überspringen können. Diese Option kann Beschädigungen verbergen, Abstürze verursachen oder falsche Daten zurückgeben; nur Superuser können es ändern.
  • zero_damaged_pages – Wenn ein beschädigter Seitenheader oder eine Checksumme erkannt wird, bewirkt das Setzen dieses Parameters auf on, dass PostgreSQL die gesamte 8-KB-Seite im Speicher durch Nullen ersetzt und dann die Verarbeitung fortsetzt. Die genullte Seite wird später auf die Festplatte geschrieben, wodurch alle Tupel auf dieser Seite zerstört werden. Verwenden Sie dies nur, wenn Sie Backup- oder Standby-Optionen ausgeschöpft haben. Das Deaktivieren von zero_damaged_pages stellt keine Daten wieder her und wirkt sich nur darauf aus, wie zukünftige beschädigte Seiten behandelt werden.
Die folgenden vereinfachten Beispiele veranschaulichen diese Einstellungen:
-- Mit ignore_checksum_failure=off stoppt die Abfrage beim ersten Fehler:
test=# SELECT * FROM pg_toast.pg_toast_17453;
WARNING: page verification failed, calculated checksum 19601 but expected 152
ERROR: invalid page in block 0 of relation base/16384/16402

-- Mit ignore_checksum_failure=on protokolliert der Server Warnungen und scannt weiter, bis er gute Daten findet:
test=# SET ignore_checksum_failure = ON;
test=# SELECT * FROM pg_toast.pg_toast_17453;
WARNING: page verification failed, calculated checksum 29668 but expected 57724
WARNING: page verification failed, calculated checksum 63113 but expected 3172
WARNING: page verification failed, calculated checksum 59128 but expected 3155
Mit zero_damaged_pages=on werden ungültige Seiten genullt, anstatt einen Fehler zu verursachen. Die Abfrage wird fortgesetzt, aber die Daten auf diesen Seiten gehen verloren:
test=# SET zero_damaged_pages = ON;
test=# SELECT * FROM pg_toast.pg_toast_17453;
WARNING: page verification failed, calculated checksum 29668 but expected 57724
WARNING: invalid page in block 204 of relation base/16384/17464; zeroing out page
WARNING: page verification failed, calculated checksum 63113 but expected 3172
WARNING: invalid page in block 222 of relation base/16384/17464; zeroing out page

Intern führt der Puffer-Manager diese Nullung durch Aufrufen von memset() auf der 8-KB-Seite durch, wenn die Überprüfung fehlschlägt und das READ_BUFFERS_ZERO_ON_ERROR-Flag gesetzt ist. Wenn das Flag nicht gesetzt ist, wird der Puffer als ungültig markiert und ein Fehler wird ausgelöst. Wir müssen natürlich verstehen, dass Checksummen und ignore_checksum_failure- und zero_damaged_pages-Einstellungen beschädigte Datenblöcke nicht reparieren können. Diese Optionen sind letzte Auswege, um verbleibende Zeilen zu retten. Ihre Verwendung führt immer zu Datenverlusten. Sobald eine Seite im Speicher genullt ist, kann ihr vorheriger beschädigter Inhalt nicht wiederhergestellt werden, selbst wenn wir zero_damaged_pages wieder auf OFF setzen. Um ursprüngliche gute Daten zurückzubekommen, müssen wir sie aus einem bekannten guten Backup oder Standby wiederherstellen.

Autovacuum-Interaktion

Vacuum-Prozesse können beim Scannen von Tabellen auf beschädigte Seiten stoßen. Da das automatische Nullsetzen von Seiten Daten stillschweigend zerstören könnte, deaktiviert der Autovacuum-Launcher zero_damaged_pages für seine Worker zwangsweise. Der Quellcode ruft SetConfigOption mit „zero_damaged_pages“, „false“ mit einem Kommentar auf, der erklärt, dass diese gefährliche Option niemals nicht-interaktiv angewendet werden sollte. Auf diese Weise werden beschädigte Seiten nur dann genullt, wenn wir direkt mit ihnen arbeiten.

Warum wir Checksummen begrüßen sollten
Datenbeschädigung auf der Datenbank, die keine Checksummen verwendet, kann zu viel problematischeren Situationen führen. Ohne Checksummen können nur Seiten mit eindeutig beschädigtem Seitenheader erkannt und genullt werden. Unten sehen wir einen Test im PostgreSQL-Code, der zeigt, dass selbst diese Erkennung ohne Checksummen nicht einfach ist – siehe den Kommentar:
/*
* Die folgenden Überprüfungen beweisen nicht, dass der Header korrekt ist, sondern nur, dass
* es vernünftig genug aussieht, um in den Pufferpool aufgenommen zu werden. Spätere Verwendung von 
* der Block kann immer noch Probleme aufdecken, weshalb wir die
* Checksummenoption anbieten.
*/
if ((p->pd_flags & ~PD_VALID_FLAG_BITS) == 0 &&
p->pd_lower <= p->pd_upper &&
p->pd_upper <= p->pd_special &&
p->pd_special <= BLCKSZ &&
p->pd_special == MAXALIGN(p->pd_special))
header_sane = true;

if (header_sane && !checksum_failure)
return true;
Im Allgemeinen testet dieser Code, ob wichtige Werte im Seitenheader in erwartete Beziehungen ihrer Werte passen. Eine gesunde Datenseite wird hier gezeigt:
SELECT * FROM page_header(get_raw_page('pg_toast.pg_toast_32840', 100));
 lsn | checksum | flags | lower | upper | special | pagesize | version | prune_xid
------------+----------+-------+-------+-------+---------+----------+---------+-----------
 0/2B2FCD68 | 0 | 4 | 40 | 64 | 8192 | 8192 | 4 | 0
(1 row)
So können nur Seitenheader mit eindeutig beschädigten Flag-Bits, lower, upper, special und/oder pagesize sicher als beschädigt erkannt werden. In diesem Fall erhalten wir eine Fehlermeldung:
ERROR: XX001-invalid page in block 578 of relation base/16384/28751
Und nur diese Seiten können genullt werden. Aber wenn der Header intakt ist (oder zumindest den obigen Test besteht), können wir viele verschiedene Fehler erhalten, die entweder durch beschädigte Item-IDs-Arrays oder beschädigte Systemspalten in Tupeln verursacht werden.
Beschädigte Item-IDs-Arrays enthalten falsche Offsets zum Anfang des Tupels und eine falsche Länge des Tupels. Diese beschädigten Zahlen können ungültige Speicheranforderungen oder sogar einen Absturz der Sitzung verursachen, die Daten liest:
ERROR: invalid memory alloc request size 18446744073709551594
DEBUG: server process (PID 76) was terminated by signal 11: Segmentation fault
Wenn die Item-IDs-Array-Werte intakt sind, aber Tupel beschädigt sind, sehen wir normalerweise verschiedene Fehler, die signalisieren, dass die Systemspalten xmin und xmax, die für die Überprüfung der Sichtbarkeit im Multiversion-Concurrency-Control-System entscheidend sind, nutzlose Werte enthalten:
58P01 - could not access status of transaction 3047172894
XX000 - MultiXactId 1074710815 has not been created yet -- apparent wraparound
WARNING: Concurrent insert in progress within table "test_table_bytea"

Bei diesen Fehlern können wir mit schwierigen und zeitaufwändigen manuellen Reparaturen und Datenrettungen konfrontiert werden, wenn wir kein zuverlässiges Backup haben, das wir zur Wiederherstellung von Daten verwenden könnten. Diese Beschreibungen zeigen deutlich, dass das Aktivieren von Daten-Checksummen eine sehr wichtige Änderung für die PostgreSQL-Community ist.

Fazit
Die Entscheidung von PostgreSQL 18, Daten-Seiten-Checksummen zu aktivieren, spiegelt die Erfahrung wider, dass die Auswirkungen auf die Leistung minimal und die Vorteile enorm sind. Checksummen erkennen eine Vielzahl von stillen Korruptionsereignissen, sodass wir Fälle, in denen Hardware schief geht, leichter diagnostizieren können. Sie machen auch die Rettung guter Daten viel schneller und einfacher – wenn aus irgendeinem Grund keine zuverlässigen Backups verfügbar sind.
Mehr dazu:
Wir helfen Ihnen gerne!

Ob Ansible, Debian, Proxmox, Kubernetes oder PostgreSQL, mit über 25 Jahren Entwicklungs- und Serviceerfahrung im open source-Bereich unterstützt Sie die credativ GmbH mit einem beispiellosen und individuell anpassbaren Support. Wir sind für Sie da, um Sie bei allen Ihren open source-Infrastrukturbedürfnissen zu unterstützen.

Haben Sie Fragen zu unserem Artikel oder möchten Sie, dass die Spezialisten von credativ einen Blick auf eine andere Software Ihrer Wahl werfen?
Dann schauen Sie vorbei und nehmen Sie über unser Kontaktformular Kontakt auf oder schreiben Sie uns eine E-Mail an info@credativ.de.

Über credativ

Die credativ GmbH ist ein herstellerunabhängiges Beratungs- und Dienstleistungsunternehmen mit Sitz in Mönchengladbach.

 

Kategorien: PostgreSQL®
Tags: planetpostgres planetpostgresql postgresql 18 PostgreSQL®

JM

über den Autor

Josef Machytka


Beitrag teilen: