Guide

Migrations

Schema changes that survive a rolling update

MIGRATIONS

Saasie provides no migration runner and does not run anything for you. Your
container starts, and what it does then is yours. What follows is the shape
of the problem this platform creates for you, because the rollout model
makes some ordinary approaches deadlock.

TWO VERSIONS RUN AT ONCE

During a rollout the old and new versions are both live against the same
database, and the old one is not stopped until the new one is healthy. So a
migration must leave the old version working. Add a column, do not rename
one; add a table, do not drop one. Removing something takes two deploys —
one that stops using it, one that removes it.

IF YOU MIGRATE AT STARTUP

Doing it before you listen is reasonable: it keeps the health path unanswered
until the schema is ready, so no request meets a half-migrated database. But
then a migration that never finishes is a service that never starts, and the
rollout waits forever.

  Anything you hold across the migration must be released, and must be
  released even when the migration throws.

  If you serialise with a Postgres advisory lock, be certain the lock and
  the unlock run on the same connection. pg_advisory_lock is session-scoped,
  and most clients are connection POOLS — the lock and the unlock can land
  on different connections, at which point pg_advisory_unlock returns false
  and the lock is held until that connection dies. It does not throw. The
  failure is silent, permanent, and it deadlocks every subsequent deploy:
  the new version waits for a lock the old version holds, and the old
  version is not stopped until the new one is healthy.

  Take a dedicated connection for the whole sequence, or use a
  transaction-scoped lock, which the database releases for you.

NEVER EDIT A MIGRATION THAT HAS RUN

Whatever records which migrations have been applied has already recorded
that filename. Editing the file changes nothing on a database that has seen
it, and your app starts against a schema that does not match your code —
usually as "relation ... does not exist" on the first query. Add a new
migration instead. This is the single most common way to break a second
deploy.

The same text, on your machine: saasie docs migrations