Versionswechsel im Betrieb

Die PostgreSQL-Hauptversion wechseln, ohne zu improvisieren

Drei Wege führen zur neuen Hauptversion, und sie unterscheiden sich vor allem in der Zeit, die der Betrieb dafür stillsteht. Die Vorarbeit ist bei allen dreien dieselbe.

KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Seit 1997 am Markt Kleine Gruppen Präsenz und Live-Online Zertifizierte Trainer
Worum es geht

Aufgeschobene Upgrades werden mit jedem Jahr teurer

Jede Hauptversion wird fünf Jahre lang mit Fehlerkorrekturen versorgt, danach erscheint eine letzte Minor-Version und die Reihe ist beendet. Wer zwei oder drei Hauptversionen zurückliegt, bekommt für Sicherheitslücken keine Korrektur mehr und kann Erweiterungen, die neuere Versionen voraussetzen, nicht mehr einsetzen.

Der Aufschub kostet zusätzlich an anderer Stelle. Ein Sprung über eine Version ist überschaubar, weil du die Änderungen einer Release-Notiz durchgehen kannst. Über vier Versionen hinweg summieren sich geänderte Voreinstellungen, entfernte Konfigurationsparameter und Erweiterungen, die es in dieser Form nicht mehr gibt, zu einem Projekt statt zu einem Wartungsfenster.

Am unangenehmsten ist der Fall, in dem das Upgrade unter Zeitdruck erzwungen wird, weil eine Anwendung eine neuere Version verlangt oder ein Betriebssystem-Wechsel ansteht. Dann fallen beide Umstellungen zusammen, und wenn danach etwas nicht stimmt, ist nicht mehr klar, woran es lag.

KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt
Schritt für Schritt

Schritt für Schritt

  1. 1

    Zielversion und Minor-Stand festlegen

    Nimm nicht die Version, die zufällig im Paketverzeichnis liegt, sondern die aktuelle Hauptversion mit dem neuesten Minor-Stand. Jede Hauptversion wird fünf Jahre unterstützt, ein Sprung auf die vorletzte verkürzt den Abstand bis zum nächsten Upgrade unnötig. Prüf gleichzeitig, welche Hauptversion deine Anwendungen und Treiber freigegeben haben.

    Geschafft, wenn: Zielversion und Minor-Stand stehen schriftlich fest und sind mit den Anwendungen abgeglichen.

  2. 2

    Erweiterungen und Fremdmodule inventarisieren

    SELECT extname, extversion FROM pg_extension in jeder Datenbank liefert die Liste. Für jede Erweiterung muss die passende Bibliothek für die neue Version installiert sein, bevor pg_upgrade startet. Wichtig: Nach dem Upgrade darfst du kein CREATE EXTENSION ausführen, die Definitionen kommen aus dem alten Cluster mit. pg_upgrade schreibt stattdessen ein Skript mit den nötigen ALTER EXTENSION UPDATE-Befehlen.

    Geschafft, wenn: Für jede Erweiterung ist ein Paket der Zielversion benannt und auf dem Zielsystem vorhanden.

  3. 3

    Den Weg wählen und begründen

    Bis etwa fünfzig Gigabyte und mit einem Fenster von einigen Stunden ist pg_dumpall gefolgt von einem Restore der einfachste Weg, weil er nebenbei aufräumt und keine Kompatibilitätsfallen kennt. Darüber ist pg_upgrade der Standard. Ist nur ein Fenster von Sekunden erlaubt, bleibt die logische Replikation zwischen altem und neuem Cluster.

    Geschafft, wenn: Der gewählte Weg passt zur Datenmenge und zur erlaubten Ausfallzeit.

  4. 4

    Trockenlauf mit pg_upgrade --check

    Der Prüflauf läuft gegen den laufenden alten Server und ändert nichts. Er meldet unter anderem Spalten mit reg-Datentypen wie regproc oder regnamespace, die nicht übertragbar sind, fehlende Erweiterungsbibliotheken und eine abweichende Prüfsummeneinstellung. Letztere ist seit PostgreSQL 18 ein häufiger Stolperstein, weil initdb dort Prüfsummen standardmäßig einschaltet und ein alter Cluster ohne Prüfsummen nicht in einen neuen Cluster mit Prüfsummen passt.

    Geschafft, wenn: pg_upgrade --check meldet keine Beanstandungen mehr.

  5. 5

    Sicherung erstellen und den Rückweg proben

    Welcher Rückweg möglich ist, hängt vom Übertragungsmodus ab. --copy und --clone lassen den alten Cluster unangetastet, du kannst ihn im Notfall wieder starten. --link und --swap verändern ihn, sobald der neue Cluster läuft, dann bleibt nur die Sicherung. Spiel sie einmal auf ein Testsystem ein und miss, wie lange das dauert, denn diese Dauer ist deine tatsächliche Ausfallzeit im schlechtesten Fall.

    Geschafft, wenn: Die Sicherung wurde einmal vollständig zurückgespielt und die Dauer ist bekannt.

  6. 6

    Umschalten und Statistiken erzeugen

    Nach dem Lauf startest du den neuen Cluster und erzeugst sofort Statistiken, sonst planen die ersten Abfragen ins Blaue. Ab PostgreSQL 18 übernimmt pg_upgrade die meisten Planerstatistiken, erweiterte Statistiken aus CREATE STATISTICS und die kumulierten Zähler der pg_stat-Sichten aber nie. Der Aufruf vacuumdb --all --analyze-in-stages liefert in drei Durchgängen zuerst grobe, dann brauchbare Werte, sodass die Anwendung schon während des Laufs vernünftig arbeitet.

    Geschafft, wenn: Die ersten Abfragen laufen mit realistischen Plänen statt mit Schätzungen aus dem Nichts.

  7. 7

    Beobachten, dann erst den alten Cluster löschen

    pg_upgrade legt ein Skript delete_old_cluster.sh an. Führ es nicht am selben Tag aus. Beobachte stattdessen ein paar Tage lang die Laufzeiten, am einfachsten über log_min_duration_statement und pg_stat_statements, denn geänderte Voreinstellungen des Planers zeigen sich erst unter echter Last. Erst wenn nichts auffällt, gibst du den Platz frei.

    Geschafft, wenn: Nach einigen Tagen ohne Auffälligkeiten ist delete_old_cluster.sh an der Reihe.

Fünf Punkte, die vor dem Wartungsfenster geklärt sein müssen

  1. 01 Für jede installierte Erweiterung gibt es ein Paket der Zielversion.
  2. 02 pg_upgrade --check läuft ohne Beanstandung gegen den laufenden Betrieb.
  3. 03 Die Prüfsummeneinstellung stimmt zwischen altem und neuem Cluster überein.
  4. 04 Der Rückweg wurde einmal tatsächlich geprobt, nicht nur aufgeschrieben.
  5. 05 Der Befehl für neue Statistiken steht im Ablauf, nicht in der Nachbereitung.
Was du mitnimmst

Danach planst du den Wechsel entlang deiner Ausfallzeit

Die Wahl des Weges ist keine Geschmacksfrage, sondern das Ergebnis aus zwei Zahlen: wie groß der Bestand ist und wie lange er nicht erreichbar sein darf. Alles Weitere, von der Prüfung der Erweiterungen bis zum Rückweg, ist bei allen Wegen dieselbe Vorarbeit.

Den Weg an der Ausfallzeit ausrichten

Dump und Restore skaliert mit der Datenmenge und ist bei einigen hundert Gigabyte keine Option mehr. pg_upgrade mit --link oder --swap arbeitet unabhängig von der Datenmenge, die Dauer hängt stattdessen an der Zahl der Tabellen und Indizes. Die logische Replikation drückt das Fenster auf den Moment des Umschaltens.

Erweiterungen vor allem anderen prüfen

Für jede Zeile aus pg_extension muss es ein passendes Paket der Zielversion geben. Fehlt eines, ist das Upgrade an dieser Stelle beendet, und das merkst du besser vorher als im Wartungsfenster.

Mit --check trocken laufen lassen

pg_upgrade --check prüft Binärkompatibilität, nicht übertragbare Datentypen und die Prüfsummeneinstellung, während der alte Server weiterläuft. Der Lauf ist ungefährlich und lässt sich beliebig oft wiederholen.

Statistiken einplanen statt hoffen

Bis PostgreSQL 17 gehen beim Upgrade sämtliche Planerstatistiken verloren, und die ersten Abfragen laufen mit Plänen, die auf nichts beruhen. Ab Version 18 übernimmt pg_upgrade die meisten davon, erweiterte Statistiken aber nie.

Den Rückweg vorher proben

Mit --link oder --swap ist der alte Cluster nach dem Start des neuen nicht mehr verwendbar. Der Rückweg ist dann die wiederhergestellte Sicherung, und die muss einmal tatsächlich eingespielt worden sein, nicht nur existieren.

Die Umgebung mitdenken

Ein gleichzeitiger Wechsel des Betriebssystems ändert die Sortierreihenfolge der Systembibliothek. Indizes auf Textspalten sind danach möglicherweise nicht mehr in der Reihenfolge, die der Planer annimmt, und gehören neu gebaut.

KI-generiertDieses Bild wurde mit KI erzeugt · Yves Hoppe / KI / cmt

Die drei Wege und wofür sie taugen

Dump und Restore ist der ehrlichste Weg: pg_dumpall schreibt den gesamten Cluster als SQL, der neue Cluster liest ihn ein. Alles wird dabei neu aufgebaut, Indizes, Sichten, Berechtigungen, und alte Datei-Fragmentierung verschwindet. Der Nachteil ist die Dauer, denn sie wächst mit der Datenmenge und wird beim Indexaufbau schnell zur Sache von Stunden. Für kleine Cluster und für den Wechsel auf andere Hardware ist es trotzdem oft der beste Weg.

pg_upgrade schreibt nur den Systemkatalog neu und übernimmt die Datendateien unverändert. Mit --copy werden sie kopiert, mit --clone über Dateisystem-Verweise geteilt, mit --link hart verlinkt, mit --swap werden die Verzeichnisse getauscht. Die letzten drei Varianten sind unabhängig von der Datenmenge und brauchen typischerweise Minuten. Bezahlt wird das mit dem Rückweg: --link und --swap machen den alten Cluster unbrauchbar, sobald der neue gestartet ist.

Die logische Replikation ist der einzige Weg mit einem Fenster von Sekunden. Der alte Cluster wird zum Publisher, der neue zum Subscriber, die Anfangsdaten werden kopiert, danach folgt der neue Cluster laufend nach. Umgeschaltet wird, wenn der Rückstand nahe null ist. Das ist aufwendig genug, dass es sich nur bei echtem Verfügbarkeitsdruck lohnt, und es hat Bedingungen, die man vorher kennen muss.

Was die logische Replikation nicht mitnimmt

Drei Lücken sorgen regelmäßig für Überraschungen. Sequenzen werden nicht repliziert: Der neue Cluster kennt die Werte, die beim Kopieren galten, aber nicht die inzwischen vergebenen. Vor dem Umschalten müssen alle Sequenzen auf den aktuellen Stand gesetzt werden, sonst vergibt die Anwendung Schlüssel, die es schon gibt. DDL wird ebenfalls nicht repliziert, während der Umstellung darf sich also kein Schema ändern. Und Large Objects bleiben außen vor.

Dazu kommt eine Voraussetzung an die Tabellen: Jede replizierte Tabelle braucht einen Primärschlüssel oder eine als REPLICA IDENTITY festgelegte eindeutige Spalte, sonst können UPDATE und DELETE nicht zugeordnet werden. REPLICA IDENTITY FULL funktioniert als Notlösung. Bis PostgreSQL 15 kostete das auf der Empfängerseite einen vollständigen Tabellendurchlauf je geänderter Zeile, ab Version 16 darf der Subscriber dafür einen passenden B-Baum-Index verwenden. Der muss dann allerdings vorhanden sein, sonst bleibt es beim Durchlauf.

Ein verbreitetes Missverständnis betrifft pg_createsubscriber. Das Werkzeug macht aus einem physischen Standby einen logischen Subscriber und spart damit das erste Kopieren der Daten, was bei großen Beständen viel Zeit spart. Für ein Hauptversions-Upgrade hilft es trotzdem nicht: Quelle und Ziel müssen dieselbe Hauptversion haben. Ebenso an eine Version gebunden ist die Übernahme von Replikations-Slots durch pg_upgrade, die es seit PostgreSQL 17 gibt und die einen alten Cluster ab Version 17 voraussetzt.

Was pg_upgrade übernimmt und was nicht

Nicht übernommen werden die Konfigurationsdateien. postgresql.conf und pg_hba.conf des neuen Clusters sind die Voreinstellungen der Zielversion, und wer hier nur kopiert, holt sich Parameter ins neue System, die es dort nicht mehr gibt oder die anders wirken. Der bessere Weg ist, die eigenen Abweichungen aus dem alten Cluster gezielt zu übertragen. SELECT name, setting FROM pg_settings WHERE source = 'configuration file' liefert genau diese Liste.

Ebenfalls nicht übernommen werden die kumulierten Zähler der Statistiksichten. pg_stat_user_tables und pg_stat_statements starten bei null, was die Beobachtung nach dem Upgrade erschwert. Wenn du Kennzahlen für den Vorher-Nachher-Vergleich brauchst, sicher sie vorher in eine eigene Tabelle.

Ein oft übersehener Punkt sind Spalten mit reg-Datentypen. pg_upgrade verweigert die Arbeit, wenn irgendwo eine Spalte vom Typ regproc, regnamespace, regoper oder regconfig liegt, weil diese Werte auf interne Objektnummern zeigen, die im neuen Cluster andere sind. In Anwendungsschemata sind solche Spalten selten, in selbstgebauten Verwaltungstabellen kommen sie vor, und --check findet sie zuverlässig.

Der Fall, der unabhängig von PostgreSQL schiefgeht

Ein Hauptversions-Upgrade fällt oft mit einem Wechsel des Betriebssystems zusammen, weil die neue PostgreSQL-Version bequem als Paket der neuen Distribution kommt. Damit ändert sich in der Regel die Version der Systembibliothek, und mit ihr kann sich die Sortierreihenfolge von Text ändern. Indizes auf Textspalten sind dann in einer Reihenfolge sortiert, die der Server nicht mehr für richtig hält, und Abfragen können Zeilen übersehen, die tatsächlich vorhanden sind. Der Fehler zeigt sich nicht als Absturz, sondern als fehlendes Suchergebnis.

Vorbeugen kannst du auf zwei Arten. Entweder du trennst beide Umstellungen zeitlich, dann weißt du im Fehlerfall, welche der beiden es war. Oder du baust nach dem Wechsel alle betroffenen Indizes mit REINDEX neu, was bei großen Tabellen mit REINDEX CONCURRENTLY im laufenden Betrieb möglich ist. Wer die Sortierung über ICU statt über die Systembibliothek steuert, hat dieses Problem in geringerem Maß, weil die verwendete Version dann an der Datenbank hängt und nicht am Betriebssystem.

Verwandt ist eine Kleinigkeit, die PostgreSQL 18 sichtbar gemacht hat: Auf manchen Architekturen ist der Datentyp char vorzeichenbehaftet, auf anderen nicht, und das wirkte sich auf gespeicherte Daten aus. pg_upgrade bringt dafür die Option --set-char-signedness mit, um das Verhalten des alten Clusters im neuen fortzuschreiben. Relevant wird das, wenn der Cluster zwischen unterschiedlichen Prozessorarchitekturen umzieht.

Dazu passende Kurse

Wer einen Cluster verantwortet, sollte diesen Ablauf einmal geübt haben, statt ihn im Wartungsfenster zum ersten Mal zu lesen, und dafür gibt es die PostgreSQL-Kurse zu Versionswechsel und Wartungsfenstern .

Wissen prüfen

Wie sicher bist du beim Thema wirklich?

Lesen fühlt sich schnell nach Können an. Ein kurzer Test zeigt dir, was davon schon sitzt und wo sich ein Kurs lohnt. Kostenlos, ohne Anmeldung, mit einer Erklärung zu jeder Antwort.

Super Schulung, in der der Trainer auch auf eigene Fragestellungen eingegangen ist.
PostgreSQL Datenbankentwicklung Aufbaukurs
Super Grundlagenschulung mit allen wichtigen Punkten und hilfreichen Tipps!
PostgreSQL Einführung und SQL Grundlagenkurs
Schön, sich 5 Tage ungestört mit Postgres beschäftigen zu können.
PostgreSQL für Administratoren Grundkurs

Häufige Fragen

Kann ich mehrere Hauptversionen auf einmal überspringen?
Ja, pg_upgrade unterstützt sehr alte Ausgangsversionen und braucht keine Zwischenschritte. Der Aufwand liegt nicht im Werkzeug, sondern in den Änderungen, die sich über mehrere Versionen angesammelt haben. Geh die Abschnitte zu inkompatiblen Änderungen aller übersprungenen Versionen durch, das ist die eigentliche Arbeit an einem großen Sprung.
Wie lange dauert ein Upgrade mit pg_upgrade wirklich?
Mit --link, --clone oder --swap hängt die Dauer nicht an der Datenmenge, sondern an der Zahl der Relationen, weil für jede Tabelle und jeden Index Katalogeinträge geschrieben werden. Ein Cluster mit wenigen tausend Objekten ist in Minuten fertig, eine Datenbank mit Hunderttausenden Partitionen braucht deutlich länger. Miss es einmal auf einer Kopie, dann hast du deine Zahl.
Warum ist die Datenbank nach dem Upgrade langsamer als vorher?
Fast immer wegen fehlender Statistiken. Bis einschließlich PostgreSQL 17 nimmt pg_upgrade keine Planerstatistiken mit, der Planer schätzt also jede Tabelle gleich groß und wählt entsprechend falsche Zugriffswege. Deshalb gehört vacuumdb --all --analyze-in-stages direkt hinter das Upgrade und nicht in die Nachbereitung.
Brauche ich ein Upgrade auch für Minor-Versionen?
Ja, aber das ist eine andere Größenordnung. Ein Minor-Update ändert das Datenformat nicht, du tauschst die Binärdateien und startest den Dienst neu. Da dort Fehlerkorrekturen und Sicherheitsbehebungen enthalten sind, gehören Minor-Updates in den regelmäßigen Wartungsrhythmus und nicht in ein Projekt.
Persönlich für dich da

Deine Ansprechpartner

Du bist dir nicht sicher, welcher Kurs oder welches Level zu dir passt? Wir beraten dich persönlich und kostenlos.

Yves Hoppe

Yves Hoppe

Weiterbildung & Beratung

Hilft dir, aus dem Datenbanken-Programm den passenden Kurs für deinen Stand zu finden.

Norbert Jansen

Norbert Jansen

Beratung & Inhouse

Plant mit dir Inhouse-Trainings, die auf eure Abläufe und euren Datenbestand zugeschnitten sind.

Wartungsfenster, die man vorher durchgerechnet hat

Den Ablauf eines Versionswechsels samt Prüflauf, Statistiken und Rückweg gehst du bei cmt einmal vollständig durch, bevor du ihn auf einem System machst, das jemand braucht.