Modern DevSecOps Foundations Module 4 · Test and Release

Database Changes Without Fear

Last reviewed · content updated

Advanced

What you'll learn

~18 min
  • Pick a migration discipline from four operational criteria, deliberately
  • Run expand/contract when continuous delivery demands it - and paired-rollback when the criteria say otherwise
  • Keep either school honest: versioned, gated, rehearsed

Two schools, both real

If you took Cloud Modernization, you learned its promotion lesson’s law: schema rolls forward only; rollback is a new migration; expand/contract keeps code reversible. True — for the systems it described. But walk into a real estate (this training’s reference estate included) and you’ll find a second, equally deliberate school thriving: every deploy script ships with a paired fallback script, releases move as human-gated folders, and rollback is a rehearsed plan, not a forbidden word. Neither school is legacy; they serve different operational worlds — and the failure mode is not picking the “wrong” one, it’s inheriting one unexamined. Four criteria decide:

CRITERION favors EXPAND/CONTRACT favors PAIRED-ROLLBACK
1 Deploy cadence continuous/daily - no windows release trains + maintenance
to coordinate in windows that EXIST anyway
2 Schema ownership the app team owns its schema DBA/vendor-owned schemas,
(migrations ride app CI) change-controlled separately
3 Online migration the platform does online DDL long-locking operations on
feasibility well; tables sized for it hot tables; engines/sizes
where "online" is a fiction
4 Audit unit the COMMIT is the audit trail the RELEASE FOLDER is what
(each migration tiny, CI-run) auditors/regulators review

Score your system honestly across the four; mixed answers are common (and fine — per system, not per team).

School one: expand/contract, mechanized

The continuous-delivery school, now standard teaching: never break the old code’s world. Expand (add the nullable column, the new table, dual-write), migrate data online, flip readers, then contract (drop the old shape) a release later — every step backward-compatible one version, which is precisely what kept Lesson 4.3’s five-minute rollback answerable. What’s new in 2026 is mechanization: tooling that automates the choreography (versioned-views/dual-write frameworks for Postgres, declarative schema-as-code diffing) — worth adopting where criterion 3 says yes, because hand-rolled expand/contract is the school’s hard part. Migrations ride CI as versioned files, applied by the pipeline decoupled from app deploy (bundles/jobs, never migrate-on-startup — startup migration couples the two things this module just separated).

School two: paired rollback, disciplined

The reference estate’s Oracle discipline, taught as the pattern it is rather than the fossil it’s mistaken for:

releases/2026.08/
precheck/ run-before gates: versions, row counts, invariants
wave1/ 001_DeployDDL.sql 001_fallback.sql <- EVERY deploy script
002_DeployDML.sql 002_fallback.sql ships its inverse,
wave2/ ... written TOGETHER
control/ commit.sql continue.sql rollback.sql <- explicit decision
runbook.md human-gated, step-ordered points, scripted

The discipline’s teeth: the fallback is written with the deploy script (same PR, same review — an inverse written during an incident is a guess); waves order dependencies; prechecks gate entry; and the runbook names the decision points where a human chooses commit/continue/rollback. What keeps it modern rather than merely old: the scripts still live in git, still pass CI gates (the estate front-loads SAST/SCA before any DB release), and the rollback rehearsal is on the calendar like 4.3’s drill. Paired-rollback without rehearsal is the same hypothesis-not-capability trap.

The bridge between schools — because criterion answers change: a paired-rollback estate moving toward continuous delivery adopts expand/contract per table as criteria 1–3 flip, using the release-folder apparatus as the wrapper until the cadence itself dissolves it. Migration between migration schools is itself an expand/contract.

The artifact: (1) score Meridian's three data systems against the four
criteria - crew-scheduling Postgres (app-owned, continuous), the billing
Oracle (DBA-owned, release trains, hot tables), the reporting lake
(append-only - neither school; contracts govern it, per the Cloud
Modernization data lessons); (2) for the Postgres: one worked expand/
contract - the nullable-column add through contract, each step's
compatibility stated; (3) for the Oracle: one worked release folder -
deploy+fallback pair, precheck, runbook decision points; (4) the rule
card each team pins up, and the REHEARSAL date for each.
💬The anti-pattern is the unexamined default

Most estates didn’t choose their migration school — they inherited whatever the first DBA or the first framework shipped, and defend it as identity. The four criteria turn identity back into engineering: an expand/contract shop with a vendor-owned hot-table Oracle is hurting for a release folder; a paired-rollback shop deploying its app-owned Postgres daily is paying window-coordination tax for nothing. Same estate, both true at once. Score per system; choose out loud; write the ADR (3.5’s form).

KNOWLEDGE CHECK

Meridian's billing team (Oracle, DBA-owned, monthly release train, regulator audits by release) reads modern guidance saying 'forward-only migrations are the professional standard — down-scripts are a myth because they destroy data.' They ask whether their paired-fallback discipline is technical debt to eliminate. What's the criteria-based answer?

Key takeaway

Migration discipline is a per-system engineering choice made on four criteria — cadence, ownership, online feasibility, audit unit — not an inherited identity. Expand/contract, mechanized, where delivery is continuous; paired-rollback folders, rehearsed and CI-gated, where trains, DBAs, and auditors rule; a written bridge for when criteria flip. Either way: versioned, reviewed together, gated, and drilled. Module 4 closes — Module 5 makes what you ship provable.

Search lessons