feat(repo): PostgreSQL 16 to 18, with make pg-upgrade and a hard-stop guard (#1245) #1299
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/1245-postgres-18"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #1245. Supersedes Renovate's #627.
What changes
dbrunspostgres:18-alpineon a new volume,postgres18_data, mounted at/var/lib/postgresqlbecause the 18 image keeps its data in18/docker. The oldpostgres_datavolume is kept untouched, as the rollback copy and archive.pg-upgrade-guard, a one-shot service thatdbdepends on: it exits 1 when the old volume holds a cluster and the new one has none. Without it, starting the new stack would create an empty database and migrate an empty schema. Fresh installs and upgraded installs both pass.make pg-upgrade(scripts/pg-upgrade.sh), which:FORCE=1;DockerfilePG_MAJOR=18) and the e2e compose file all move to 18. Renovate readsPG_MAJOR.docs/OPERATIONS.mdhas a new section, "Upgrading PostgreSQL 16 → 18". It covers the guard's states, the steps, the prod order and rollback.Verified on docker-test
make pg-upgradetook 22 s, with all 115 tables and the alembic revision matching;Prod order (at the 4.7.0 deploy, owner's say only):
make backup-now→ check out the tag →docker compose pull→make pg-upgrade→docker compose up -d. Do not runmake migrate-safeorupbeforepg-upgrade: the 18 client refuses to back up a 16 server, andupwould stop the old db at the guard.🤖 Generated with Claude Code
Independent review, and fixes
The review found no path that loses or corrupts data, but it found three defects. I checked each against the code and fixed them in 2 commits:
compose rm -sf db. At that pointdbis still the old release's running 16 container, and the message then said the stack was untouched. Fixed:dbonly after step 5 has started the 18 one;PGDATAsubdirectory. It read only$old/PG_VERSION, so withPGDATA=.../data/pgdatait would pass, 18 would start empty, andmigratewould build an empty schema. Fixed: anything in the old volume now counts as data. There is a new test for that layout. The script's step 1 now names the layout instead of saying "nothing to upgrade".NEW_VOLUME=<old volume>, followed by any failure, would remove the 16 data. Fixed: the script refuses the same name for both, and refuses a "new" volume laid out like the old one.Also:
COLLATE "C";PGDATAand any extra roles before the window;FORCE=1, which would mix 4.7.0 tables with an older revision.Checked on docker-test:
test_pg_upgrade,test_backup_client_versionandtest_migrate_safe_scriptpass on postgres:18 (33 passed).Not rehearsed: the new cleanup paths on a real stack; their tests only read the script. The dev rehearsal with the 4.7.0 release candidate is where they get a real run, before prod.
Before the prod window, check on prod: that
docker compose exec db printenv PGDATAprints nothing or/var/lib/postgresql/data.