Lab 04: Database Migrations — Flyway

Time: 50 minutes | Level: Architect | DB: PostgreSQL 15, Flyway


🎯 Objective

Master schema migration with Flyway: versioned and repeatable migrations, lifecycle commands (migrate/validate/info/repair), and zero-downtime migration patterns (expand-contract). Compare with Liquibase.


📚 Background

Why Schema Migration Tools?

Manual ALTER TABLE scripts don't scale:

  • Which version is production on? Dev? Staging?

  • Did this migration already run?

  • How to rollback safely?

Migration tools solve: version tracking, ordering, idempotency, and team coordination.

Flyway Concepts

File Type
Naming
Purpose

Versioned

V1__description.sql

Runs once, in order

Repeatable

R__description.sql

Runs when checksum changes

Undo

U1__description.sql

Rollback (Flyway Teams)

Flyway Schema History Table

Zero-Downtime Migration: Expand-Contract


Step 1: Start PostgreSQL & Install Flyway

📸 Verified Output:


Step 2: Create Migration Scripts

📸 Verified Output:


Step 3: Run Flyway Migrations

📸 Verified Output:


Step 4: Validate & Query Current State

📸 Verified Output:


Step 5: Zero-Downtime Migration — Expand-Contract

📸 Verified Output:

💡 Zero-downtime key: Never ALTER TABLE RENAME COLUMN or DROP COLUMN while old code still runs. Use expand-contract: add → both write → remove old.


Step 6: Flyway Repair & Failed Migrations

📸 Verified Output:


Step 7: Liquibase Comparison

📸 Verified Output:


Step 8: Capstone — Migration Best Practices

📸 Verified Output:


Summary

Concept
Key Takeaway

Versioned migration

V1__name.sql — runs once, tracked by version number

Repeatable migration

R__name.sql — re-runs when file checksum changes

flyway migrate

Apply all pending migrations in version order

flyway validate

Check that applied migrations match files on disk

flyway info

Show status of all migrations (pending/applied/failed)

flyway repair

Remove failed entries from history; fix checksums

Expand-Contract

Add nullable column → backfill → add constraint → drop old

CREATE INDEX CONCURRENTLY

Build index without blocking writes

NOT VALID constraint

Add FK without scanning existing rows

💡 Architect's rule: Treat migration scripts like production code — version controlled, reviewed, tested in staging before production. Never edit a migration that has already run.

Last updated