Flyway 的脚本按什么顺序执行?改了已经执行过的脚本会怎样?脚本执行到一半失败了库是什么状态?已有表的库怎么接入?这篇在 Spring Boot 4.0.8、Flyway 11、MySQL 上逐个实测。
V1、V2、V10、V1_1 四个脚本:启动成功
历史表:4 行
rank 1 version 1 "create a" SQL checksum -1193849269 success=1
rank 2 version 1.1 "alter a" SQL checksum 869508972 success=1
rank 3 version 2 "create b" SQL checksum 1407251784 success=1
rank 4 version 10 "create c" SQL checksum -1138581898 success=1
业务表:['a', 'b', 'c']按版本号的数值顺序,V1_1 是 1.1;历史表记录每次的校验和与成功与否。
V2 的内容被改了一个字符之后再启动:启动失败
Caused by: org.flywaydb.core.api.exception.FlywayValidateException: Validate failed: Migrations have failed validation ‖ Migration checksum mismatch for migration version 2 ‖ -> Applied to database : 1407251784 ‖ -> Resolved locally : 1460908494
历史表:2 行
rank 1 version 1 "create a" SQL checksum -1193849269 success=1
rank 2 version 2 "create b" SQL checksum 1407251784 success=1
业务表:['a', 'b']
可重复迁移 R__view_a.sql 改了内容之后再启动:启动成功
历史表:3 行
rank 1 version 1 "create a" SQL checksum -1193849269 success=1
rank 2 version None "view a" SQL checksum 924199270 success=1
rank 3 version None "view a" SQL checksum 1391577623 success=1
业务表:['a', 'va']改了已执行的 V 脚本启动失败;R 脚本改了就重跑。
默认(out-of-order=false):启动失败
Caused by: org.flywaydb.core.api.exception.FlywayValidateException: Validate failed: Migrations have failed validation ‖ Detected resolved migration not applied to database: 1.5.
历史表:2 行
rank 1 version 1 "create a" SQL checksum -1193849269 success=1
rank 2 version 2 "create b" SQL checksum 1407251784 success=1
业务表:['a', 'b']
spring.flyway.out-of-order=true:启动成功
历史表:3 行
rank 1 version 1 "create a" SQL checksum -1193849269 success=1
rank 2 version 2 "create b" SQL checksum 1407251784 success=1
rank 3 version 1.5 "late" SQL checksum 531052471 success=1
业务表:['a', 'b', 'late']迟到的小版本号脚本默认校验失败,out-of-order=true 才补执行。
V2 里第一条建表成功、第二条出错:启动失败
Caused by: org.flywaydb.core.internal.sqlscript.FlywaySqlScriptException: Failed to execute script V2__two_statements.sql ‖ SQL State : 42S02 ‖ Message : Table 'demo.no_such_table' doesn't exist ‖ Line : 2 ‖ Statement : Run Flyway with -X option to see the actual statement causing the problem
历史表:2 行
rank 1 version 1 "create a" SQL checksum -1193849269 success=1
rank 2 version 2 "two statements" SQL checksum 1582595889 success=0
业务表:['a', 't2']
不改任何东西再启动一次:启动失败
Caused by: org.flywaydb.core.api.exception.FlywayValidateException: Validate failed: Migrations have failed validation ‖ Detected failed migration to version 2 (two statements).
历史表:2 行
rank 1 version 1 "create a" SQL checksum -1193849269 success=1
rank 2 version 2 "two statements" SQL checksum 1582595889 success=0
业务表:['a', 't2']MySQL 的 DDL 不能回滚,脚本中途失败留下半截对象和 success=0 的行,需要 repair 加手工清理。
库里已有 legacy 表、没有历史表:启动失败
Caused by: org.flywaydb.core.api.FlywayException: Found non-empty schema(s) `demo` but no schema history table. Use baseline() or set baselineOnMigrate to true to initialize the schema history table.
历史表:(没有 flyway_schema_history)
业务表:['legacy']
spring.flyway.baseline-on-migrate=true:启动成功
历史表:2 行
rank 1 version 1 "<< Flyway Baseline >>" BASELINE checksum None success=1
rank 2 version 2 "create b" SQL checksum 1407251784 success=1
业务表:['b', 'legacy']非空库默认拒绝;baseline-on-migrate 的基线版本默认 1,会跳过 V1。