| Kategorien: | PostgreSQL® |
|---|---|
| Tags: | planetpostgres planetpostgresql postgresql 18 PostgreSQL® |
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.

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.
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.
-- 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
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.
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.
/* * 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;
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)ERROR: XX001-invalid page in block 578 of relation base/16384/28751
ERROR: invalid memory alloc request size 18446744073709551594 DEBUG: server process (PID 76) was terminated by signal 11: Segmentation fault
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.
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.
Die credativ GmbH ist ein herstellerunabhängiges Beratungs- und Dienstleistungsunternehmen mit Sitz in Mönchengladbach.
| Kategorien: | PostgreSQL® |
|---|---|
| Tags: | planetpostgres planetpostgresql postgresql 18 PostgreSQL® |
Sie müssen den Inhalt von reCAPTCHA laden, um das Formular abzuschicken. Bitte beachten Sie, dass dabei Daten mit Drittanbietern ausgetauscht werden.
Mehr InformationenSie sehen gerade einen Platzhalterinhalt von Brevo. Um auf den eigentlichen Inhalt zuzugreifen, klicken Sie auf die Schaltfläche unten. Bitte beachten Sie, dass dabei Daten an Drittanbieter weitergegeben werden.
Mehr InformationenSie müssen den Inhalt von reCAPTCHA laden, um das Formular abzuschicken. Bitte beachten Sie, dass dabei Daten mit Drittanbietern ausgetauscht werden.
Mehr InformationenSie müssen den Inhalt von Turnstile laden, um das Formular abzuschicken. Bitte beachten Sie, dass dabei Daten mit Drittanbietern ausgetauscht werden.
Mehr InformationenSie müssen den Inhalt von reCAPTCHA laden, um das Formular abzuschicken. Bitte beachten Sie, dass dabei Daten mit Drittanbietern ausgetauscht werden.
Mehr InformationenSie sehen gerade einen Platzhalterinhalt von Turnstile. Um auf den eigentlichen Inhalt zuzugreifen, klicken Sie auf die Schaltfläche unten. Bitte beachten Sie, dass dabei Daten an Drittanbieter weitergegeben werden.
Mehr Informationen