我报名参与金石计划1期应战——瓜分10万奖池,这是我的第2篇文章,点击查看活动概况

最近遇上了一件困扰了我好几天的一个问题,为此排查了一整天都无功而返,想到这感觉真对不起老板,一天一行代码没写,啥也没做成。

背景

工作是这样的,在公司内部新开发了一个功能还没有上线,现在布置在测验环境,Node服务会开启一个守时使命,每5分钟会处理好一部分数据写入到mysql数据库中。

在这之前,一切都运转正常,中秋节后上班第一天翻开后台体系发现没有数据展示了,然后查询数据库发现前史存储的数据都没了,没了。现在只会存储最新的守时使命履行后的数据。可在此之间没有修正过任何代码,这个就神奇了。

头疼时刻

查看写入的数据一向都只会存储最新的数据,则查看是否没有触发更新的逻辑,悉数都射中新增的逻辑。

const isExist = await this.Model.findOne({
  where: {
    projectId
  }
});
if (isExist) {
  await isExist.destroy()
  updateList.push(item)
} else {
  createList.push(item)
}

现在的逻辑是将新增和更新分隔处理,经查看发现所有的isExist都是null,导致悉数射中新增的逻辑。可是数据库中分明是有数据的,为什么查询不出来呢?置疑是有第三方数据存在脏数据之类的状况,所以我将数据库现存数据悉数清空,从头写入查看作用。成果第一次写入是正常的,后续仍是不会触发更新,经过查询发现每次写入数据库大约十几秒数据就被清空了。

可是在写入后的代码逻辑中是没有履行删去数据的处理,并且每次都是安稳复现,写入后就被删去了,查询无果无法找到db帮找原因。db查询日志给出的定论便是有守时履行删去的逻辑。

头大了,Mysql写入数据十几秒后被主动删去了
看到日志只能持续在代码中找原因了。因为此刻是运用的 sequelize 的 bulkCreate 批量创立数据,所以开端置疑是不是这个批量处理的过程中呈现了问题,最初是因为每次履行的数据量太多所以没有选择单条履行,这个时分为了排查问题,所以我改成了单条数据 create 方法创立数据。

this.Model.bulkCreate(list)

修正为

for (const item of list) {
  this.Model.create(item)     
}

成果不出意外的仍是守时被删去了, 然后开端置疑是业务没有提交的问题,尽管此逻辑是彻底不需要用到业务操作,但仍是抱着置疑的心态试试看。

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();
}

成果不出意外的仍是守时被删去了,此刻现已没有改动的余地了,此刻的天都现已黑了,可是问题还没处理,只能持续面向百度编程了,此刻查找到也有同一个人遇到这样的问题,他的处理计划是修正表称号,这时分也只能死马当作活马医了。

头大了,Mysql写入数据十几秒后被主动删去了

成果出意外的恢复正常写入以及更新了。

为什么更改了表称号后就正常呢,思来想去也想不出为什么。成果今天在从头布置服务的时分看了一眼前史布置记载,发现了端倪。就在假日的最终一天晚上有一个布置记载,然后我回看了和最开端产生数据异常的时刻段相差无几。根本就可以断定和此次布置有很大的联系,因为公司内部的布置计划有docker和虚拟机两种方法,导致每个时刻段都会有两个守时使命一起履行,因为数据处理的过程中需要查询第三方数据,最终两头写入的时刻会存在必定的延时,导致写好的数据被另一边履行了删去的逻辑,因为那台服务器一向未更新修正的代码,一向履行的是最开端那份先删去再更新的逻辑。至于为啥履行了删去可是没有更新,猜测是删去后更新的逻辑出错了。这也是为什么修正了表称号后就正常了,因为那台服务器上面仍是旧的代码,新增删去不能读到之前的那张表了,问题到此终所以告一段落了。

收尾

到此是否感觉看了一个大乌龙事件,最终的原因和代码没有任何联系,可是却屡次三番的改动无果。在排查过程中还有许多没有写的,比方置疑重复数据导致所以添加仅有索引,置疑自增ID多大从头清零,可是这个改动的过程中也学到了不少新的知识,怎么运用业务,新增仅有索引,修正表称号,重置自增ID等许多服务端相关的知识。最终的总结是遇到问题先不要质疑代码,从体系层面,运转版本,环境变量,运维等方面也要有必定的考虑。

专注前端开发,分享前端相关技术干货,大众号:南城大前端(ID: nanchengfe)