mysql迁移不能只靠手动alter table,因多人协作时易出现字段冲突、字符集不一致、锁表超时等问题;liquibase通过版本化changelog实现跨环境可复现变更,但需正确配置驱动、url及处理外键顺序与不可逆操作风险。

MySQL 迁移为什么不能只靠手动 ALTER TABLE
多人协作时,ALTER TABLE users ADD COLUMN phone VARCHAR(20) 这种操作在本地跑通,推到测试库可能失败——比如字段已存在、字符集不一致、或加索引时锁表超时。Liquibase 的核心价值不是“多了一个工具”,而是把每次结构变更变成可版本控制、可回滚、可跨环境复现的 changelog 文件。
liquibase.properties 必须显式指定 driver 和 url 参数
MySQL 8+ 默认使用 caching_sha2_password 认证插件,而旧版 JDBC 驱动(如 mysql-connector-java:5.1.x)不支持,会导致 Access denied for user 错误。必须同时满足:
- 用
mysql-connector-java:8.0.33+驱动 -
url中显式加上?serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false -
driver设为com.mysql.cj.jdbc.Driver
driver: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false username: root password: pass
用 generate-changelog 初始化已有 MySQL 库要避开主键顺序陷阱
执行 liquibase generate-changelog 会把当前库结构导出为 XML/YAML/JSON 格式的 changelog,但 MySQL 的 SHOW CREATE TABLE 不保证外键定义顺序,可能导致生成的 <createtable></createtable> 和 <addforeignkeyconstraint></addforeignkeyconstraint> 在文件中颠倒——Liquibase 执行时报 Unknown table 'xxx'。
- 加参数
--outputFile=init.xml --diffTypes=tables,columns,primaryKeys,foreignKeys限制只导结构,不导数据和视图 - 导出后手动检查:所有
<addforeignkeyconstraint></addforeignkeyconstraint>必须出现在其引用的<createtable></createtable>之后 - 若已有外键依赖未建表,拆成两个 changelog 文件:先建表,再建约束
update 失败后 rollback 不一定安全
Liquibase 的 rollback 依赖 changelog 中是否定义了 <rollback></rollback> 块。MySQL 的某些操作天然不可逆,比如:
-
DROP COLUMN—— 没法自动还原丢失的数据 -
MODIFY COLUMN缩小长度(VARCHAR(100) → VARCHAR(10))—— 可能截断数据,rollback 不会恢复原值 -
CHANGE COLUMN改类型(INT → VARCHAR)—— 类型转换逻辑需人工写在<rollback></rollback>里
真正可靠的回滚方式是:用 mysqldump 在 liquibase update 前备份库,并记录本次 changeset id;出问题时直接还原 dump,再调整 changelog。










