MySQL写入数据十几秒后自动消失:双部署节点定时任务冲突排查

栗子
栗子
发布时间:2026-10-15 | 4人浏览过
原创

在 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 与虚拟机混合部署。此次部署可能导致同一时间段内,新旧两个版本的定时任务同时运行:

  1. 新节点(新版代码): 执行“只新增”逻辑,顺利写入数据。
  2. 旧节点(旧版代码): 仍驻留在某台未升级的服务器上,执行老版的“先 Delete 再 Update”逻辑。

由于涉及第三方接口数据同步,两节点执行存在时间差。新节点写完数据后,旧节点的定时任务启动,依据旧逻辑将刚写入的数据判定为“需更新项”,先将其 Delete,随后因旧版更新逻辑出错或条件不匹配,导致数据未被重新写回,最终表现为数据凭空消失。

总结与避坑指南

本案是一个典型的由运维部署不一致引发的“乌龙”事件。核心教训在于:

  • 多节点一致性: 在进行定时任务相关的多实例部署时,必须确保所有节点代码版本严格一致,或引入分布式锁(如 Redis SETNX)来防止同一任务在多机重复执行且逻辑冲突。
  • 全链路思维: 当应用层代码看似无误但现象持续发生时,应迅速跳出代码视角,检查环境变量、Docker 容器列表、Crond 定时任务以及 CI/CD 流水线记录。
  • 幂等性设计: 数据库写入应尽量保证幂等性(如使用 ON DUPLICATE KEY UPDATE 或 Upsert 语义),避免依赖应用层复杂的“先查后删后插”逻辑,以减少并发和版本差异带来的副作用。

以上就是MySQL写入数据十几秒后被自动删除了如何解决的详细内容,更多关于MySQL数据定时被删的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表