数据库迁移指南

迁移工具对比

工具语言方式最适合
FlywayJava/CLI版本化 SQL 文件(V1__name.sql)Java 应用、SQL 优先团队
LiquibaseJava/CLIXML/YAML/SQL 变更日志多数据库、复杂变更集
golang-migrateGo/CLI编号 .up.sql / .down.sqlGo 应用、简单 SQL 迁移
AlembicPython含 upgrade/downgrade 的 Python 脚本SQLAlchemy/Python 项目
Prisma MigrateTypeScript基于 Schema Diff 自动生成Node.js/TypeScript 应用
AtlasGo/CLI声明式(目标状态)或版本化现代 Go 应用、CI/CD

零停机:扩展-收缩模式

-- 场景:将列 "username" 重命名为 "display_name" -- 不能直接执行(会立刻导致线上故障): -- ALTER TABLE users RENAME COLUMN username TO display_name; -- 第一步(扩展):新增列,保留旧列 ALTER TABLE users ADD COLUMN display_name VARCHAR(100); -- 第二步:回填新列数据 UPDATE users SET display_name = username WHERE display_name IS NULL; -- 第三步:部署同时写入两列的新代码 -- 第四步:确认新代码已全量部署 -- 第五步(收缩):删除旧列 ALTER TABLE users DROP COLUMN username; -- 零停机索引创建(PostgreSQL) CREATE INDEX CONCURRENTLY idx_users_email ON users(email); -- CONCURRENTLY 不阻塞写入,但耗时更长

迁移执行清单

阶段操作
迁移前全量备份数据库
迁移前在 staging 环境用生产数据副本测试
迁移前评估 DDL 变更的锁持有时长
迁移前准备回滚脚本并验证可用性
迁移中监控活跃连接数和主从延迟
迁移中设置 statement_timeout 避免无限等锁
迁移后验证行数和数据完整性
迁移后监控慢查询和索引使用情况
收尾确认旧代码完全下线后再删废弃列