Add db-migrations-flyway-liquibase: Flyway vs Liquibase migrations, rollbacks and baselines on Spring Boot 4.1
Companion code for the Flyway vs Liquibase article: checksum validation, out-of-order and repeatable migrations, baselining an existing schema, Flyway Community's undo/diff/deploy stubs, concurrent-startup locking for both tools, Liquibase changeset identity and rollback (auto-generated vs explicit), a verified Liquibase 5.0.3 filename-caching defect, the new OSS license service, the FSL license change, and running both tools against one database. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Q6XdRjtsp4862EM44T7i9a
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
# 3. Checksum validation: why editing an applied migration fails
|
||||
|
||||
[← 2. Anatomy of a migration run](02-anatomy-of-a-migration-run.md) · [Index](../README.md) · Next: [4. Out-of-order migrations →](04-out-of-order-migrations.md)
|
||||
|
||||
The most common way a migration tool earns its keep is by refusing to do something that would
|
||||
otherwise fail silently, weeks later, on a machine nobody's watching. This is the simplest version
|
||||
of that: someone "just tweaks" a migration file that has already run somewhere, instead of writing
|
||||
a new one.
|
||||
|
||||
[`FlywayChecksumMismatchTest`](../src/test/java/com/ankurm/dbmigrations/flyway/FlywayChecksumMismatchTest.java)
|
||||
starts a context against `V1__init.sql`, lets it apply cleanly, then edits that same file on disk
|
||||
— widening a `varchar(50)` to `varchar(80)` — and starts a second context against the same
|
||||
database. Flyway's default (`spring.flyway.validate-on-migrate=true`) compares every applied
|
||||
migration's recorded checksum against the file's current checksum *before* attempting to migrate
|
||||
anything else, and the second startup fails outright:
|
||||
|
||||
```
|
||||
FlywayValidateException: Validate failed: Migrations have failed validation
|
||||
Migration checksum mismatch for migration version 1
|
||||
-> Applied to database : -712784830
|
||||
-> Resolved locally : 756220147
|
||||
Either revert the changes to the migration, or run repair to update the schema history.
|
||||
```
|
||||
|
||||
(quoted verbatim from
|
||||
[`docs/output/02-flyway-checksum-mismatch.txt`](output/02-flyway-checksum-mismatch.txt))
|
||||
|
||||
That message is doing real work: it's telling you the checksum stored in `flyway_schema_history`
|
||||
for version 1 no longer matches the file Flyway just read off disk. Nothing about the *schema* is
|
||||
inconsistent yet — the failure happens before any SQL runs, which is the entire point. A team that
|
||||
lets this slide by running `flyway repair` out of habit is telling Flyway "the file changed on
|
||||
purpose, update your record" — which is right for a comment or formatting fix, and very wrong for
|
||||
"I need this table to actually have the new column now", which needs a new `V3__...` file, not a
|
||||
rewrite of `V1`.
|
||||
|
||||
## What checksum validation is not
|
||||
|
||||
It is not a guarantee that the *applied* schema matches the *current* file. Flyway checks the file
|
||||
against what it already recorded, not against the live schema — if someone hand-edits the table
|
||||
after the fact, nothing here notices. It's a version-control safety net for the migration files
|
||||
themselves, not a schema-drift detector.
|
||||
|
||||
## Going deeper
|
||||
|
||||
- [`spring.flyway.validate-on-migrate`](https://docs.spring.io/spring-boot/appendix/application-properties/index.html#application-properties.data-migration.spring.flyway.validate-on-migrate) in the Spring Boot configuration reference (`rel="nofollow"`) — `true` by default.
|
||||
- [Flyway's `repair` command](https://documentation.red-gate.com/flyway/flyway-cli-and-api/commands/repair) (`rel="nofollow"`) — what actually happens to `flyway_schema_history` when you run it, and why it's a deliberate, logged action rather than something to script into a startup hook.
|
||||
Reference in New Issue
Block a user