The control plane applies config-store schema changes from embedded SQL files in
controlplane/configstore/migrations/ during NewConfigStore startup.
- The control plane opens the config-store Postgres database.
- Goose takes a Postgres session advisory lock named
duckgres:configstore:migrations, so concurrent replicas do not apply the same migration at the same time. - Goose creates or updates its
goose_db_versiontracking table. - Goose applies pending migration files in version order.
- After each file succeeds, Goose records the applied version.
Treat shipped migrations as immutable: add a new migration file instead of editing one that may already have run in an environment.
- Add a new file under
controlplane/configstore/migrations/with the next zero-padded prefix, for example000004_add_example_column.sql. - Keep the SQL idempotent where practical, using
IF EXISTSorIF NOT EXISTSfor additive DDL and guarded data backfills. - Add or update a Postgres-backed test in
tests/configstore/. - Run the red-green loop:
just test-configstore-integration- Run lint before committing:
just lintIf startup fails while applying a migration, that migration is not recorded in
goose_db_version. Fix the SQL or the existing schema state, then restart the
control plane.
Do not manually edit goose_db_version unless you have verified the database is
already at the exact same schema and data state as the migration would produce.