MySQL写入数据十几秒后自动消失:双部署节点定时任务冲突排查
在 Node.js + Sequelize 的测试环境中,数据写入 MySQL 数据库后约十几秒即自动消失。该现象并非代码逻辑中的增删查改直接导致,而是由于部署环境变更引发的多节点并发执行冲突。旧版部署节点残留了“先删除后更新”的逻辑,与新版节点的写入操作产生时序竞争,从而清理了新数据。解决思路需聚焦于部署一致性与任务去重。
背景:数据异常写入场景
某内部功能在测试环境部署时,采用 Node.js 服务配合 Sequelize ORM 框架,通过定时任务每 5 分钟处理一部分数据并批量写入 MySQL 数据库。业务逻辑旨在覆盖写入(Upsert),但上线后却发现后台数据显示为空,数据库中也仅保留最后一次任务的最新数据,历史数据不翼而飞。
在确认未修改任何核心业务代码的前提下,初步怀疑是 ORM 层的查询或插入逻辑失效。检查原代码发现,逻辑分为“查找是否存在”与“新增/更新”两部分:
const isExist = await this.Model.findOne({
where: { projectId }
});
if (isExist) {
await isExist.destroy()
updateList.push(item)
} else {
createList.push(item)
}
实际运行时 isExist 始终为 null,导致所有数据均走新增流程。尽管数据库中已有数据,却无法查出。尝试清空表重测,首次正常,随后仍出现“写入-存活十几秒-消失”的稳定复现现象。此时需进入深度排查阶段。
排查过程:从代码逻辑到系统层面
第 1 步:排除 ORM 批量操作缺陷
最初怀疑是 bulkCreate 批量写入过程中出现了事务回滚或主键冲突导致的静默失败。尝试将批量操作改为单条循环创建以隔离风险:
// 原逻辑
this.Model.bulkCreate(list)
// 修改为单条创建
for (const item of list) {
this.Model.create(item)
}
修改后问题依旧,数据依然会在十几秒后消失。这表明问题不在单次写入机制,而在外部干预或后续操作。
第 2 步:验证事务与会话状态
考虑到可能因连接池空闲超时或隐式提交问题,尝试显式包裹数据库事务。虽然业务本身不涉及复杂原子性要求,但这有助于排除底层驱动层面的异常:
let transaction;
try {
// 建立事务对象
transaction = await this.ctx.model.transaction();
for (const item of list) {
// 事务内增操作
await this.Model.create(item, {
transaction,
});
}
// 统一提交事务
await transaction.commit();
} catch (err) {
// 发生错误时回滚
await transaction.rollback();
}
结果数据仍被定时清除。此时已排除 Node.js 应用层代码逻辑本身的问题,怀疑点转向基础设施或协同进程。
第 3 步:借助 DBA 定位物理删除来源
通过联系数据库管理员(DBA)审查 MySQL 慢查询日志与操作日志,最终发现确实在每隔十几秒的规律时间点,存在针对该表的 DELETE 操作。既然代码中没有对应的定时删除脚本,这意味着有其他进程在执行删除逻辑。
第 4 步:回归部署架构寻找根源
在陷入僵局时,临时采取“修改表名”作为障眼法测试,结果写入恢复正常。这提示可能是特定表的元数据、触发器或权限绑定出了问题,但也可能是因为新表名让旧的干扰进程“找不到目标”。结合近期部署记录,发现中秋节假期最后一天有过一次重新部署。
经核实,公司测试环境采用了 Docker 与虚拟机混合部署。此次部署可能导致同一时间段内,新旧两个版本的定时任务同时运行:
- 新节点(新版代码): 执行“只新增”逻辑,顺利写入数据。
- 旧节点(旧版代码): 仍驻留在某台未升级的服务器上,执行老版的“先 Delete 再 Update”逻辑。
由于涉及第三方接口数据同步,两节点执行存在时间差。新节点写完数据后,旧节点的定时任务启动,依据旧逻辑将刚写入的数据判定为“需更新项”,先将其 Delete,随后因旧版更新逻辑出错或条件不匹配,导致数据未被重新写回,最终表现为数据凭空消失。
总结与避坑指南
本案是一个典型的由运维部署不一致引发的“乌龙”事件。核心教训在于:
- 多节点一致性: 在进行定时任务相关的多实例部署时,必须确保所有节点代码版本严格一致,或引入分布式锁(如 Redis SETNX)来防止同一任务在多机重复执行且逻辑冲突。
- 全链路思维: 当应用层代码看似无误但现象持续发生时,应迅速跳出代码视角,检查环境变量、Docker 容器列表、Crond 定时任务以及 CI/CD 流水线记录。
- 幂等性设计: 数据库写入应尽量保证幂等性(如使用
ON DUPLICATE KEY UPDATE或 Upsert 语义),避免依赖应用层复杂的“先查后删后插”逻辑,以减少并发和版本差异带来的副作用。
以上就是MySQL写入数据十几秒后被自动删除了如何解决的详细内容,更多关于MySQL数据定时被删的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









