From 2eb29d4ede65837fe64ee0f06a64fceb06f6970a Mon Sep 17 00:00:00 2001 From: Lee Hannigan <29015211+LeeroyHannigan@users.noreply.github.com> Date: Mon, 2 Nov 2026 14:48:29 +0000 Subject: [PATCH] docs(upgrade): confirm the server is stopped before the upgrade steps The General Upgrade Procedure, the version-history blocks and the rollback steps began with `extenddb stop` and carried on with whatever it returned. `extenddb stop` finds the server through its PID file, so it stops nothing and exits 1 for a `serve --foreground` server, a container, a wrong `--config`, or a different user, and the steps that follow then back up, migrate or copy files under a live old server. Each block now runs in a subshell and, before it touches a file or a database, confirms `extenddb status` reports the server is not running, stopping without closing the operator's shell when it still answers and behaving the same under `set -o pipefail`. Step 1 explains that `extenddb status` only checks 127.0.0.1 on the configured port, so a server on another address or host is confirmed through its runner. Text only; no version literal changed. --- docs/manuals/07-upgrade-manual.md | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/docs/manuals/07-upgrade-manual.md b/docs/manuals/07-upgrade-manual.md index f4451a0f5..2a8db880c 100755 --- a/docs/manuals/07-upgrade-manual.md +++ b/docs/manuals/07-upgrade-manual.md @@ -127,10 +127,18 @@ The consolidated schema file is what fresh installs get. Add your new column/tab For releases that include catalog changes. The names below in angle brackets are the ones chosen at `extenddb init`: `` and `` (`--catalog-db`, `--data-db`; defaults `extenddb_catalog` and `extenddb`) and ``, the application role (`--extenddb-user`, default `extenddb`). `` is the PostgreSQL role `init` connected as (`--pg-user`). -1. **Stop the server** +1. **Stop the server, and confirm it is down** + + `extenddb stop` finds the server through the PID file the daemon writes. It stops nothing and exits 1 for a server started with `serve --foreground` (which writes no PID file), when its `--config` path does not name the server's config file, or when it runs as a different user than the one that started the server. Stop the server through whatever runs it: `sudo systemctl stop extenddb` for the Deployment Guide's systemd unit, the container runtime for a container, otherwise `extenddb stop --config extenddb.toml`. Start it again the same way when the procedure is done. + + The exit status of `extenddb stop` does not show whether the server is down, so confirm with `extenddb status` before you back up, migrate or touch a file. The block below runs in a subshell, so it reports and stops without closing your shell when the server still answers. `extenddb status` connects to the port on 127.0.0.1 that the config file resolves to, so for a server whose `bind_addr` is another address, or one on another host, confirm the stop through whatever runs it instead. ```bash +( extenddb stop --config extenddb.toml +{ extenddb status --config extenddb.toml || true; } | grep -q 'is not running' \ + || { echo 'server not confirmed stopped; stop it through whatever runs it' >&2; exit 1; } +) ``` 2. **Back up the databases** (PostgreSQL; for SQLite see [SQLite](#sqlite) below) @@ -187,7 +195,7 @@ extenddb serve --config extenddb.toml If an upgrade fails (PostgreSQL; for SQLite see [SQLite](#sqlite) below): -1. Stop the server +1. Stop the server and confirm it is down, as in step 1 of the General Upgrade Procedure 2. Restore the catalog from the backup, connected as `` to the `postgres` database: ```bash @@ -217,12 +225,16 @@ The upgrade is not reversible in place: a 0.0.3 PostgreSQL or SQLite binary refu #### PostgreSQL ```bash +( extenddb stop --config extenddb.toml +{ extenddb status --config extenddb.toml || true; } | grep -q 'is not running' \ + || { echo 'server not confirmed stopped; stop it through whatever runs it' >&2; exit 1; } pg_dump -h -U > catalog_backup_$(date +%Y%m%d).sql export EXTENDDB_PG_PASSWORD='' extenddb migrate --config extenddb.toml --pg-user # exit 3, prints the plan extenddb migrate --config extenddb.toml --pg-user --yes # applies 003_backup_definitions.sql extenddb serve --config extenddb.toml +) ``` The preview reports the version change and the unapplied migration file, `Pending: catalog 0.0.3 -> 0.0.4; data migrations [catalog 003_backup_definitions.sql].`, and exits 3; after `--yes`, a second preview reports everything up to date and exits 0. `migrate` treats any catalog migration file that the catalog's ledger does not record as pending, even when the stored catalog version already matches the binary, and applies it with `--yes`; such files are listed under `data migrations` as `catalog `. @@ -238,11 +250,15 @@ On its first control-plane pass after the upgrade (at startup), the server remov The database is one file plus its `-wal` and `-shm` files beside it. Stop the server before copying them: `migrate` and `serve` take the same exclusive lock on `.lock`, so `migrate` refuses to run while a server is up (`this command needs exclusive use of the SQLite database and cannot have it: another extenddb process is already using ...`). A stopped server can leave a non-empty `-wal` file, so copy all three. ```bash +( extenddb stop --config extenddb.toml +{ extenddb status --config extenddb.toml || true; } | grep -q 'is not running' \ + || { echo 'server not confirmed stopped; stop it through whatever runs it' >&2; exit 1; } mkdir pre-upgrade && cp -p /path/to/extenddb.sqlite* pre-upgrade/ extenddb migrate --config extenddb.toml # exit 3, prints the plan extenddb migrate --config extenddb.toml --yes extenddb serve --config extenddb.toml +) ``` The upgrade rebuilds `backup_items` with a stable restore cursor, copying every row into a new table inside one write transaction; the database is locked for writes until it finishes. The preview names it with its row count, for example `Pending: catalog 0.0.3 -> 0.0.4; data migrations [rebuild backup_items (80 rows)].`, and `--yes` logs its start and end at info: @@ -252,7 +268,7 @@ catalog upgrade: rebuilding backup_items with a stable restore cursor (80 rows); catalog upgrade: rebuilt backup_items (80 rows) in 0.005s ``` -To roll back, stop the server, put the copied files back in place of the current ones (remove the current `-wal` and `-shm` first), and start the previous binary. +To roll back, stop the server and confirm it is down (step 1 of the General Upgrade Procedure), put the copied files back in place of the current ones (remove the current `-wal` and `-shm` first), and start the previous binary the same way. On SQLite, `extenddb serve` refuses to start a file database whose tables are in a pre-release 0.0.4 shape and names the pending step; stop the server and run `extenddb migrate --yes`. @@ -261,11 +277,15 @@ On startup the SQLite server removes any restore target left in `CREATING` by a #### Cassandra ```bash +( extenddb stop --config extenddb.toml +{ extenddb status --config extenddb.toml || true; } | grep -q 'is not running' \ + || { echo 'server not confirmed stopped; stop it through whatever runs it' >&2; exit 1; } export EXTENDDB_CASSANDRA_PASSWORD='' extenddb migrate --config extenddb.toml --cassandra-user # exit 3 extenddb migrate --config extenddb.toml --cassandra-user --yes # applies V005 extenddb serve --config extenddb.toml +) ``` `` is the role `init` used (`--cassandra-user`). `EXTENDDB_CASSANDRA_PASSWORD` keeps the password out of process arguments; `--cassandra-pass` still works and wins if both are given. Without a user and password `migrate` connects as the operating-system user with no password, which a cluster using `PasswordAuthenticator` refuses; the error reports a connection timeout. @@ -294,9 +314,13 @@ Adds vector index metadata: Upgrade sequence: ```bash +( extenddb stop --config extenddb.toml +{ extenddb status --config extenddb.toml || true; } | grep -q 'is not running' \ + || { echo 'server not confirmed stopped; stop it through whatever runs it' >&2; exit 1; } extenddb migrate --yes --config extenddb.toml extenddb serve --config extenddb.toml +) ``` Run `extenddb migrate` without `--yes` first to see what is pending; it reports `catalog 0.0.2 -> 0.0.3` and changes nothing.