ERP对接升级提示数据库迁移失败:SQLite逐版本事务到底回滚到哪一步

ERP对接程序升级时提示"数据库迁移第N版失败",数据库就一定退回升级前的完整状态吗?要看迁移事务包住的是每个版本,还是整次升级。

本文依据项目真实SQLite初始化函数,用新建实验库和进程内临时追加的故障SQL,验证逐版本事务的回滚范围。没有编辑项目迁移源码,没有操作生产库或启动服务。

1. 当前迁移以版本为事务边界

代码读取 schema_version.v,从该位置继续执行 MIGRATIONS 数组。每个版本单独开启事务,核心顺序是:

javascript 复制代码
db.exec('BEGIN');
try {
  db.exec(MIGRATIONS[i]);
  db.prepare('UPDATE schema_version SET v = ?').run(i + 1);
  db.exec('COMMIT');
} catch (e) {
  db.exec('ROLLBACK');
  throw new Error(`数据库迁移第 ${i + 1} 版失败:${e.message}`);
}

一个版本内,结构变化与版本号更新在同一事务中提交。但前一个版本的COMMIT已经完成,不会因为下一个版本失败而自动撤销。

因此,"本次迁移失败"要进一步拆成:哪个版本失败,该版本有没有提交,以及此前哪些版本已经提交。

2. 用故障版本验证实际结果

当前项目真实迁移数组共有3版。本地验证仅在当前Node进程中临时追加一个第4版,不把它写进项目源码:

sql 复制代码
CREATE TABLE demo_migration_probe (id INTEGER);
INSERT INTO demo_missing_table(id) VALUES (1);

第一条创建演示表,第二条因演示目标表不存在而失败。新建实验库从头执行初始化,得到:

检查项 本地结果
抛出的失败版本 第4版
失败后schema_version.v 3
第3版创建的source_runs表 存在
第4版刚创建的演示表 不存在

第4版内已经执行的建表被回滚,版本号没有推进到4;此前已提交的前三版仍然保留。

这里的第4版只是人为构造,不是项目已经发布过的数据库升级,也不是客户升级事故。检查使用独立数据库连接读取实验文件,验证的是SQLite中的持久结果。

图1:当前迁移函数加构造故障SQL的本地结果,未修改生产数据库。

3. 失败以后,先读版本,不要先改版本

排查时建议先只读核对当前版本与实际表结构:

sql 复制代码
SELECT v FROM schema_version;
SELECT name FROM sqlite_master WHERE type = 'table';

同时确认打开的是哪份数据库、使用的是哪个应用版本,以及报错指向的迁移SQL。数据目录配置或部署路径不一致,也可能让人检查到另一份文件。

不要看到失败就把v改成0。此前的表可能已经存在,重跑历史建表语句可能再次失败;更重要的是,手工改数字会破坏版本与结构之间的对应关系。

也不要直接把v填成更高版本来跳过报错。数字推进了,不代表缺失的表、字段和数据变换已经完成。

4. 修复失败版本需要考虑哪些条件

先确认故障版本是否完全处于这份数据库事务的控制范围。文件操作、外部接口或其他数据库连接的变化,不会因为这里执行ROLLBACK就一并撤销。

对尚未提交的失败迁移,要核对它的输入结构和执行前提;对已经在其他环境成功执行过的历史版本,则不能随意改写SQL,应该设计兼容升级与验证方案。

当前循环是按顺序继续,失败版本没有通过,后续版本也不会执行。因此仅在末尾增加一个版本,不能自然绕过前面仍会报错的步骤。

是否将整批升级放入一个事务、是否允许分阶段提交,应结合数据量、锁定时间与数据库能力决定。本文说明当前实现的行为,没有给出适用于所有项目的迁移框架。

5. 升级验收不能只看启动成功

建议先在隔离副本上验证旧版本到新版本的结构和数据,再故意制造某个版本失败,核对版本号、部分SQL的回滚、错误记录与再次执行条件。

还应验证已有数据是否保留、业务查询是否能正常读取,以及应用版本是否认识当前数据库版本。需要降级时,不能假定旧应用会自动撤销新结构。

本次已经验证逐版本事务的失败边界:第4版回滚,前三版保留。没有实测生产大表升级、锁竞争、断电恢复或跨版本降级。数据库升级报告应把这些范围分别记录,不能用一次构造回滚通过替代全部上线验收。

相关推荐
西瓜拿铁好喝1 小时前
开源和闭源 AI 办公工具,分别适合谁
java·前端·数据库
IT_陈寒1 小时前
深入理解SpringBoot:核心原理与最佳实践
前端·人工智能·后端
学长毕设1 小时前
基于SpringBoot的校园礼服租赁系统的设计与实现
java·spring boot·后端
代码派1 小时前
业务不停机迁移 MySQL 到 TiDB,NineData 数据增量同步实操演示
数据库·mysql·tidb·ninedata·无停机迁移·增量迁移·全量迁移
Gauss松鼠会1 小时前
GaussDB 中 gsql 与 DBeaver(JDBC)客户端工具查询时间不一致:原因、排查与处理
运维·服务器·数据库·sql·gaussdb·经验总结
Elastic 中国社区官方博客1 小时前
基于 Jina OCR v1 与 Elasticsearch 的 PDF 智能混合检索与 RAG 系统实战指南
大数据·数据库·elasticsearch·搜索引擎·ocr·jina
Best_Liu~1 小时前
SpringBoot全局日期格式化
java·spring boot·后端
小蒜学长1 小时前
基于Django+Vue喵汪联盟宠物领养系统的设计与实现(代码+数据库+LW)
后端·python·django·宠物领养系统·流程规范化
楚识科技1 小时前
信创环境下 OCR 部署实践:从麒麟系统到达梦数据库的全栈适配
数据库·ocr