跳转到内容

数据迁移

升级时数据库 schema 可能变化——加字段、改类型、删字段。BangNiCMS 自带迁移机制处理这些,但你需要理解原理。

典型变更

v1.5 → v2.0:
✓ Article 表新增 tags 字段
✓ Product 表的 price 字段从 整数 改为 小数
✓ Inquiry 表新增 sourceLanguage 字段
✗ User 表删除 deprecatedField 字段

自动迁移意味着:

  • 升级时 BangNiCMS 自动执行 SQL 改 schema
  • 现有数据自动转换
  • 运维不需要手写 SQL
  1. 新版本启动

  2. 检查当前数据库版本 与 新版本要求是否一致

  3. 不一致 → 执行迁移脚本

    • 加字段(默认 NULL 或默认值)
    • 改类型(自动转换 / 报错跳过)
    • 删字段(先归档可选)
  4. 更新数据库版本号

  5. 服务正常启动

Product.price: 整数 → 小数
✓ 整数 100 → 小数 100.00(自动)
但反向:
Product.price: 小数 → 整数
✗ 小数 99.99 → 整数 ?(信息丢失,迁移报错)

怎么办:开发者写迁移脚本明确舍入策略保留旧字段

Inquiry 表新增 sourceLanguage 字段(必填)
✗ 现有 1000 条 inquiry 没这个字段 → 必填校验失败

怎么办

  • 加字段时给默认值'unknown'
  • 或先允许 NULL,迁移后手动填
  • 或写迁移脚本自动推断

百万级数据迁移可能几小时

怎么办

  • 让运维分批迁移
  • 异步迁移(升级后慢慢跑)

如 1.x → 3.x,不要直接跳

推荐:
1.5 → 1.9 → 2.0 → 2.5 → 3.0
不推荐:
1.5 → 3.0(直接跳过 2.x 的所有迁移)

原因:每个版本的迁移脚本依赖上一版的 schema——跳过会让脚本找不到字段。

升级失败需要回滚到旧版:

  1. 服务降级:进入维护模式

  2. 数据库回滚

    • 升级前的备份恢复(推荐)
    • 或运行反向迁移脚本(开发者提供)
  3. 代码回滚

    • Docker 切换回旧版镜像
    • git checkout 旧版
  4. 重启服务

  5. 验证

  6. 退出维护模式

理想情况:开发者为每个迁移脚本提供”反向”版本:

迁移脚本:v1 → v2
反向脚本:v2 → v1

实际上

  • 简单变更(加字段)容易反向
  • 复杂变更(改类型 + 数据转换)反向困难
  • 删字段后反向 = 数据无法恢复

保险做法:升级前完整备份。回滚 = 恢复备份。

每次升级前完整备份——不要跳。

把生产数据复制到测试环境跑一遍迁移:

  • 看是否成功
  • 看是否丢失数据
  • 看耗时

跨大版本时逐版本升——降低单次失败的影响。

避免高峰期。

升级前确认

  • 备份完整
  • 知道怎么回滚
  • 运维 + 业务方都在线

不要相信”升级成功”提示——抽样验证:

  • 5-10 条产品的字段
  • 几篇文章的多语言翻译
  • 用户登录
  • 询盘提交

升级后保持高度警惕:

  • 错误率监控
  • 用户反馈
  • 数据完整性

正常迁移不丢——BangNiCMS 的迁移脚本经过测试。

  • bug 可能导致丢数据
  • 不兼容的类型变更可能丢精度
  • 删字段 = 删数据

保险:备份 + 测试。

典型

  • 小型站点(< 10000 条数据):几秒-几分钟
  • 中型(10k-100k):几分钟-半小时
  • 大型(> 100k):半小时-几小时

实际看具体迁移内容——加字段快、改类型慢。

立刻

  • 不要重启服务
  • 看运维日志找断点
  • 决定:继续 / 回滚

预防

  • 给迁移脚本加事务(要么全成功要么全回滚)
  • 让运维监控迁移过程

通常不能——会让数据库 schema 不一致。

如果某个迁移对你不重要(如某个字段你从不用),让开发者**提供”轻量迁移”**版本。