Das Script tools/pg_upgrade_inplace.sh führt ein In-Place Upgrade von PostgreSQL durch, ohne die Daten zu kopieren. Es nutzt Hardlinks, wodurch kein zusätzlicher Speicherplatz benötigt wird.
Unterstützte Upgrades: PostgreSQL 14 → 15 → 16 → 17 → 18
| Anforderung | Beschreibung |
|---|---|
| Docker | Muss installiert und lauffähig sein |
| Root-Rechte | sudo für Dateisystem-Operationen |
| Gestoppte Container | Alle Container mit dem Volume müssen gestoppt sein |
| Speicherplatz | Minimal (nur für Logs, ~100MB) |
# 1. Stack stoppen
docker compose down
# 2. Upgrade durchführen (Standard: 15 → 18)
sudo ./tools/pg_upgrade_inplace.sh --volume-name ${STACK_NAME}-postgres
# 3. Stack starten
docker compose up -d
# 4. Statistiken aktualisieren
docker exec ${STACK_NAME}_DATABASE vacuumdb -U nocodb --all --analyze-in-stages./pg_upgrade_inplace.sh [OPTIONEN] <VOLUME_PFAD>
./pg_upgrade_inplace.sh [OPTIONEN] --volume-name <DOCKER_VOLUME_NAME>| Option | Beschreibung | Standard |
|---|---|---|
--from <VERSION> |
Quell-PostgreSQL-Version | 15 |
--to <VERSION> |
Ziel-PostgreSQL-Version | 18 |
--volume-name <NAME> |
Docker Volume Name (Alternative zu Pfad) | - |
--dry-run |
Nur prüfen, keine Änderungen | false |
--force |
Keine Bestätigung abfragen | false |
--help |
Hilfe anzeigen | - |
# Standard-Upgrade mit Volume-Pfad
sudo ./pg_upgrade_inplace.sh /var/lib/docker/volumes/db_crm_app-postgres
# Mit Docker Volume Name (empfohlen)
sudo ./pg_upgrade_inplace.sh --volume-name db_crm_app-postgres
# Andere Versionen (z.B. 14 → 17)
sudo ./pg_upgrade_inplace.sh --from 14 --to 17 --volume-name mystack-postgres
# Dry-Run: Nur prüfen, nichts ändern
sudo ./pg_upgrade_inplace.sh --dry-run --volume-name db_crm_app-postgres
# Für Scripting ohne Bestätigung
sudo ./pg_upgrade_inplace.sh --force --volume-name db_crm_app-postgres
# Mit Umgebungsvariablen für UID/GID
sudo PG_UID=1000 PG_GID=1000 ./pg_upgrade_inplace.sh --volume-name mystack-postgresDas Script führt folgende Schritte durch:
┌─────────────────────────────────────────────────────────────────────┐
│ PRE-FLIGHT CHECKS │
├─────────────────────────────────────────────────────────────────────┤
│ ✓ Docker verfügbar │
│ ✓ Volume-Pfad existiert │
│ ✓ PG_VERSION passt zur Quell-Version │
│ ✓ Keine laufenden Container mit diesem Volume │
│ ✓ Ausreichend Speicherplatz │
│ ✓ Helper-Image verfügbar (wird ggf. heruntergeladen) │
└─────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ UPGRADE-PROZESS │
├─────────────────────────────────────────────────────────────────────┤
│ 1. Verschiebe _data → v15 (Backup des alten Clusters) │
│ 2. Erstelle neues leeres _data Verzeichnis │
│ 3. Starte pg_upgrade im Docker Container │
│ 4. Verifiziere neuen Cluster (PG_VERSION) │
└─────────────────────────────────────────────────────────────────────┘
│
┌─────────────┴─────────────┐
▼ ▼
┌───────────────┐ ┌───────────────┐
│ ERFOLG │ │ FEHLER │
├───────────────┤ ├───────────────┤
│ Neuer Cluster │ │ Automatischer │
│ in _data │ │ Rollback │
│ │ │ │
│ Backup in v15 │ │ Alter Cluster │
│ (kann später │ │ wiederher- │
│ gelöscht │ │ gestellt │
│ werden) │ │ │
└───────────────┘ └───────────────┘
/var/lib/docker/volumes/mystack-postgres/
└── _data/ ← Aktiver PostgreSQL 15 Cluster
├── PG_VERSION (Inhalt: "15")
├── base/
├── global/
├── pg_wal/
└── ...
/var/lib/docker/volumes/mystack-postgres/
├── _data/ ← Aktiver PostgreSQL 18 Cluster (NEU)
│ ├── PG_VERSION (Inhalt: "18")
│ ├── base/
│ ├── global/
│ ├── pg_wal/
│ └── ...
│
└── v15/ ← Backup des alten Clusters
├── PG_VERSION (Inhalt: "15")
├── base/
└── ...
docker compose up -dNach einem Major-Upgrade sollten die Optimizer-Statistiken neu erstellt werden:
# Empfohlen: Stufenweise Analyse (schneller, weniger Last)
docker exec ${STACK_NAME}_DATABASE vacuumdb -U nocodb --all --analyze-in-stages
# Alternativ: Vollständige Analyse
docker exec ${STACK_NAME}_DATABASE vacuumdb -U nocodb --all --analyzedocker exec ${STACK_NAME}_DATABASE psql -U nocodb -d nocodb -c "
SELECT extname, extversion FROM pg_extension WHERE extname != 'plpgsql';
"
# Falls Extensions vorhanden, aktualisieren:
docker exec ${STACK_NAME}_DATABASE psql -U nocodb -d nocodb -c "
ALTER EXTENSION <extension_name> UPDATE;
"Nach erfolgreicher Prüfung kann das Backup gelöscht werden:
# Prüfen ob alles funktioniert
docker exec ${STACK_NAME}_DATABASE psql -U nocodb -d nocodb -c "SELECT version();"
# Backup löschen
sudo rm -rf /var/lib/docker/volumes/${STACK_NAME}-postgres/v15Bei Fehlern während des Upgrades führt das Script automatisch einen Rollback durch:
- Neues
_dataVerzeichnis wird gelöscht - Backup
v15wird zurück nach_dataverschoben - Alter Cluster ist wieder aktiv
Falls der automatische Rollback fehlschlägt oder nach dem Upgrade Probleme auftreten:
# 1. Container stoppen
docker compose down
# 2. Neuen Cluster löschen
sudo rm -rf /var/lib/docker/volumes/${STACK_NAME}-postgres/_data
# 3. Alten Cluster wiederherstellen
sudo mv /var/lib/docker/volumes/${STACK_NAME}-postgres/v15 \
/var/lib/docker/volumes/${STACK_NAME}-postgres/_data
# 4. docker-compose.yml anpassen: POSTGRES_VERSION auf alte Version setzen
# In .env: POSTGRES_VERSION=15
# 5. Container starten
docker compose up -dAlle Upgrade-Logs werden gespeichert unter:
/var/lib/docker/pg-upgrade-<volume-name>/
├── logs/
│ └── pg_upgrade_15_to_18_20250125_143022.log
└── markers/
└── upgraded_15_to_18.ok
# Neuestes Log anzeigen
cat /var/lib/docker/pg-upgrade-${STACK_NAME}-postgres/logs/*.log
# Bei Fehlern: Detaillierte pg_upgrade Ausgabe
grep -i error /var/lib/docker/pg-upgrade-${STACK_NAME}-postgres/logs/*.log[pg-upgrade][ERROR] Folgende Container nutzen dieses Volume: mystack_DATABASE
Lösung: Alle Container mit diesem Volume stoppen:
docker compose down
# oder
docker stop ${STACK_NAME}_DATABASE[pg-upgrade][ERROR] PG_VERSION ist 14, erwartet 15.x
Lösung: Die --from Option anpassen:
sudo ./pg_upgrade_inplace.sh --from 14 --to 18 --volume-name mystack-postgres[pg-upgrade][ERROR] Verzeichnis /var/.../v15 existiert bereits
Ursache: Ein früheres Upgrade wurde durchgeführt oder abgebrochen.
Lösung:
# Prüfen ob _data die aktuelle Version enthält
cat /var/lib/docker/volumes/${STACK_NAME}-postgres/_data/PG_VERSION
# Falls _data bereits aktuell ist, altes Backup löschen:
sudo rm -rf /var/lib/docker/volumes/${STACK_NAME}-postgres/v15
# Falls Rollback nötig, siehe Abschnitt "Manueller Rollback"[pg-upgrade][ERROR] Konnte Image nicht herunterladen: tianon/postgres-upgrade:15-to-18
Mögliche Ursachen:
- Keine Internetverbindung
- Docker Hub Rate Limit erreicht
- Image existiert nicht für diese Versionskombination
Lösung:
# Manuell prüfen welche Images verfügbar sind
docker search tianon/postgres-upgrade
# Alternativ: Image manuell pullen
docker pull tianon/postgres-upgrade:15-to-18Typische Ursachen und Lösungen:
| Fehler | Ursache | Lösung |
|---|---|---|
lc_collate mismatch |
Unterschiedliche Locale | Container mit gleicher Locale starten |
extension ... not available |
Extension fehlt in neuer Version | Extension vor Upgrade deinstallieren |
could not access directory |
Berechtigungsproblem | chown auf Volume ausführen |
| Variable | Beschreibung | Standard |
|---|---|---|
PG_USER |
PostgreSQL-Benutzer für pg_upgrade | nocodb |
PG_DATABASE |
PostgreSQL-Datenbank | nocodb |
PG_UID |
User-ID für PostgreSQL-Dateien | 999 |
PG_GID |
Group-ID für PostgreSQL-Dateien | 999 |
MAJOR_OLD |
Quell-Version (Alternative zu --from) | 15 |
MAJOR_NEW |
Ziel-Version (Alternative zu --to) | 18 |
Beispiel:
# Standard (nocodb)
sudo ./pg_upgrade_inplace.sh --volume-name mystack-postgres
# Mit anderen Datenbank-Credentials
sudo PG_USER=myuser PG_DATABASE=mydb \
./pg_upgrade_inplace.sh --volume-name mystack-postgres
# Alle Optionen kombiniert
sudo PG_USER=nocodb PG_DATABASE=nocodb PG_UID=1000 PG_GID=1000 MAJOR_OLD=14 MAJOR_NEW=17 \
./pg_upgrade_inplace.sh --volume-name mystack-postgresDas Script nutzt pg_upgrade --link, welches Hardlinks statt Kopien erstellt:
- Vorteil: Kein zusätzlicher Speicherplatz benötigt
- Vorteil: Upgrade dauert nur Sekunden statt Stunden
- Nachteil: Nach dem ersten Start des neuen Clusters ist kein Rollback mehr möglich (Dateien werden modifiziert)
Das Script nutzt das offizielle tianon/postgres-upgrade Image:
- Enthält beide PostgreSQL-Versionen
- Führt
pg_upgradesicher aus - Unterstützt alle gängigen Upgrade-Pfade
| Feature | Beschreibung |
|---|---|
| Pre-Flight Checks | Prüft alle Voraussetzungen vor dem Start |
| Read-Only Mount | Alter Cluster wird nur lesend gemountet |
| Automatischer Rollback | Bei Fehler wird alter Cluster wiederhergestellt |
| Signal-Handling | CTRL+C zeigt Rollback-Anleitung |
| Logging | Vollständige Protokollierung aller Schritte |
- Backup erstellen - Auch wenn das Script ein lokales Backup anlegt, sollte ein externes Backup existieren
- Dry-Run zuerst -
--dry-runzeigt alle Checks ohne Änderungen - Außerhalb der Geschäftszeiten - Upgrade erfordert kurze Downtime
- Statistiken aktualisieren -
vacuumdb --analyze-in-stagesnach dem Upgrade - Backup behalten - v15-Ordner erst nach erfolgreicher Prüfung löschen
Erstellt: 2025-01-25 Für: NocoDB mit PostgreSQL-Backend