Upgrade to a new version of postgres
Change the default postgres version for a module
- Individually upgrade all hosts to the new version, following the processes below.
- Change the default value of the
postgresTag
option for the module. - Remove the per-host
postgresTag
options.
Upgrade to a new minor version
This is generally safe. Just change the postgresTag
and rebuild the NixOS
configuration.
Upgrade to a new major version
In brief: take a backup, shut down the database, bring up the new one, and restore the backup. This does have some downtime, but is relatively risk free.
Shell variables:
$CONTAINER
- the database container name$POSTGRES_DB
- the database name$POSTGRES_USER
- the database user$POSTGRES_PASSWORD
- the database password$VOLUME_DIR
- the directory on the host that the container's/var/lib/postgresql/data
is bind-mounted to$TAG
- the new container tag to use
Replace podman
with docker
in the following commands if you're using that.
-
Stop all services which write to the database.
-
Dump the database:
sudo podman exec -i "$CONTAINER" pg_dump -U "$POSTGRES_USER" --no-owner -Fc "$POSTGRES_DB" > "${CONTAINER}.dump"
-
Stop the database container:
sudo systemctl stop "podman-$CONTAINER"
-
Back up the database volume:
sudo mv "$VOLUME_DIR" "${VOLUME_DIR}.bak"
-
Create the new volume:
sudo mkdir "$VOLUME_DIR"
-
Bring up a new database container with the dump bind-mounted into it:
sudo podman run --rm --name="$CONTAINER" -v "$(pwd):/backup" -v "${VOLUME_DIR}:/var/lib/postgresql/data" -e "POSTGRES_DB=${POSTGRES_DB}" -e "POSTGRES_USER=${POSTGRES_USER}" -e "POSTGRES_PASSWORD=${POSTGRES_PASSWORD}" --shm-size=1g "postgres:${TAG}"
-
In another shell, restore the dump:
sudo podman exec "$CONTAINER" pg_restore -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc -j4 --clean "/backup/${CONTAINER}.dump"
-
Ctrl-c the database container after the dump has restored successfully.
-
Change the
postgresTag
option in the host's NixOS configuration. -
Rebuild the NixOS configuration and check that the database and all of its dependent services come back up:
sudo nixos-rebuild switch
Rollback
The old database files are still present at ${VOLUME_DIR}.bak
, so:
-
Stop all the relevant services, including the database container.
-
Restore the backup:
sudo mv "$VOLUME_DIR" "${VOLUME_DIR}.aborted" sudo mv "${VOLUME_DIR}.bak" "$VOLUME_DIR"
-
If the
postgresTag
has been updated in the NixOS configuration:- Revert it to its previous version.
- Rebuild the NixOS configuration.
-
Restart all the relevant services.