feat(deploy): sync schema to replication subscribers before migrating

Logical replication carries rows but not DDL, so a migration that adds a
column stalls every subscriber with "missing replicated columns" until the
column exists there too. _prisma_migrations is replicated, so migrate deploy
on a subscriber reports nothing pending while its tables lag behind.

sync-replica-schema.sh applies pending migrations to each subscriber first,
tracking them locally in _replica_ddl_applied, then migrates the publisher.
--check reports subscription state and columns missing on any replica.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-11 21:34:02 +03:30
co-authored by Cursor
parent aec5e08a1e
commit 515e39d420
5 changed files with 206 additions and 1 deletions
+26
View File
@@ -105,6 +105,32 @@ sudo certbot --nginx -d adm.montzar.ir
2. `https://adm.montzar.ir/get_user?domain=montpar.ir` (or any known domain)
3. Confirm uploads/logo URLs use `PUBLIC_API_URL`
## 8) Migrations with logical replication (failover replicas)
`superadmin_pub` streams rows to the failover hosts (`adm.montech.ir`, `adm.montest.ir`).
Logical replication does **not** carry DDL: a migration that adds a column on the
publisher makes every subscriber fail with `missing replicated columns` and the
subscription stalls until that column exists there too. Because `_prisma_migrations`
is replicated, `prisma migrate deploy` on a subscriber wrongly reports
"No pending migrations".
So never run `migrate deploy` alone. On the publisher host:
```bash
cp deploy/replicas.env.example deploy/replicas.env # once; add real DSNs
bash deploy/sync-replica-schema.sh --init # once, when schemas already match
```
For every release:
```bash
npm run replicas:sync # DDL to each replica first, then migrate deploy here
npm run replicas:check # subscription state + columns missing on any replica
```
Keep migrations schema-only. Data backfills would run once per replica and then
again through replication, so apply those on the publisher by hand.
## Local development note
Prisma provider is **PostgreSQL** only. Local options: