In diesem Post schauen wir uns ein Major-Upgrade von PostgreSQL auf Debian/Ubuntu basierten Distributionen an. Der Versionierung von PostgreSQL folgend, ist ein Major-Upgrade ein Update von 15 auf 16 oder 17. Minor-Updates, also 16.1 auf 16.2 können ohne weitere Aktionen über den Paketmanager installiert werden.
Wir benutzen ‚pg_upgradecluster‚ da dies einige Vorteile gegenüber dem Standard-Tool ‚pg_upgrade‘ mit sich bringt. So wird beispielsweise der neue Cluster automatisch initialisiert und die bestehende Konfiguration übertragen.
Warum updaten
Die Datenbanken sollten regelmäßig upgedatet werden, die Gründe dafür sind:
Security- und Bug-Fixes
Performance-Optimierungen
Neue Funktionalitäten
LTS-Support beibehalten (5 Jahre)
Für jedes der in der Folge dargestellten Szenarien gilt:
Da ‚pg_upgradecluster‘ ausschließlich auf Debian/Ubuntu basierten Distributionen verfügbar ist, muss auf anderen Distributionen ‚pg_upgrade‘ genutzt werden.
Vorab sollten immer die Release-Notes der neuen Major-Version gelesen werden um eventuelle Inkompatibilitäten im Vorfeld erkennen und beseitigen zu können.
Die neue PostgreSQL-Version muss vorab installiert sein. Sind mehrere neue Versionen installiert, kann die gewünschte Version mit dem Parameter -v angegeben werden.
Um einen garantiert konsistenten Zustand upzudaten ist die aktuelle Datenbank zu stoppen, alternativ können alle Applikationen die auf die Datenbank zugreifen gestoppt werden oder der Zugriff über eine Firewall verhindert werden.
Vor dem Upgrade sollten die Backups immer auf Wiederherstellbarkeit geprüft werden.
Nach einem erfolgreichen Update stoppt ‚pg_upgradecluster‚ die alte Version automatisch.
Die neue Version wird auf dem Port der alten Version (Standard: 5432) gestartet, so dass keine Änderungen an den Applikationen nötig sind.
Im Gegensatz zu ‚pg_upgrade‚, initialisiert ‚pg_upgradecluster‚ auch den neuen Cluster und übernimmt die bestehende Konfiguration.
‚pg_upgradecluster‚ bietet drei verschiedene Modi, die jeweils Vor- und Nachteile bieten bzw. eigene Voraussetzungen haben.
Unser Ausgangszenario ist ein PostgreSQL-Cluster in Version 15, namens ‚main‘, im Verzeichnis: ‚/database/postgresql/15/main‘ Die Zielversion ist PostgreSQL 16, der neue Cluster soll in: ‚/database/postgresql/16/main‘ auf dem selben Dateisystem laufen.
Upgrade
Dump
pg_upgradecluster –method=dump 15 main /database/postgresql/16/main
Die Standard-Methode arbeitet mit ‚pg_dump‚ zum Sichern, und ‚pg_restore‚ zum Wiederherstellen der Datenbank im neuen Cluster.
Nachteile
Benötigt den doppelten Speicherplatz.
Dauert im Vergleich zu den folgenden Methoden deutlich länger. Eine Test-Datenbank mit ca. 15 GB benötigt ca. 11 Minuten.
Vorteile
Kann genutzt werden um die Datenbank auf ein anderes Storage-Device zu migrieren.
Fall beim Update irgendetwas schief gegangen ist, kann die vorherige Version problemlos wieder gestartet werden.
Link
pg_upgradecluster –method=link 15 main /database/postgresql/16/main
Link benutzt Hardlinks im Dateisystem um PostgreSQL auf die neue Version upzudaten. Das PostgreSQL Datenverzeichnis muss daher auf dem selben Dateisystem liegen. Im Hintergrund wird ‚pg_upgrade‚ genutzt.
Nachteile
Nachdem die neue Version einmal gestartet wurde, darf der alte Cluster nicht wieder gestartet werden. Dies kann (und wird mit sehr hoher Wahrscheinlichkeit) zu Inkonsistenzen der Datenbank führen!
Vorteile
Da keine Dateien kopiert werden müssen, braucht Link im Gegensatz zu Dump, nur rund 10 Sekunden für unsere 15 GB Datenbank.
Es ist kein zusätzlicher Speicherplatz für das Upgrade nötig.
Clone
pg_upgradecluster –method=clone 15 main /database/postgresql/16/main
Diese Methode funktioniert ähnlich wie Link, benötigt aber ein Dateisystem mit reflink Unterstützung. Dies sind unter Linux aktuell: xfs und btrfs.
Nachteile
Funktioniert derzeit nur auf xfs und btrfs
Vorteile
Braucht keinen zusätzlichen Speicherplatz.
Der alte Cluster kann ohne Probleme wieder gestartet werden.
Braucht – wie Link – ebenfalls nur ca. 10 Sekunden für eine 15 GB Datenbank.
Nacharbeiten
Systemd
Nach dem erfolgreichen Update muss noch sichergestellt werden, das Systemd den Service aktiviert und gestartet hat.
Daher den Daemon einmal neu laden:
systemctl daemon-reload
Den neuen Cluster via ‚pg_ctlcluster‚ noch einmal stoppen
pg_ctlcluster 16 main stop
Im Anschluss den Service via Systemd aktivieren und neu starten
systemctl enable postgresql@16-main
systemctl start postgresql@16-main
Cleanup
Nachdem sichergestellt ist, das mit der neuen PostgreSQL Version 16 alles wie gewohnt funktioniert, kann der alte Cluster entfernt werden:
pg_dropcluster 15 main
Hast du Kommentare zu dem Artikel oder Fragen zu unseren PostgreSQL-Angeboten? Melde dich gerne über die unten stehenden Kontakt-Möglichkeiten.