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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 头大了,Mysql写入数据十几秒后被自动删除了

我报名参加金石计划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查询日志给出的结论就是有定时执行删除的逻辑。

b29559550c8e2f147fc30dcc7d4e6c2.png

看到日志只能继续在代码中找原因了。由于此时是使用的 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();
}

结果不出意外的还是定时被删除了,😭😭😭此时已经没有改动的余地了,此时的天都已经黑了,可是问题还没解决,只能继续面向百度编程了,此时搜索到也有同一个人遇到这样的问题,他的解决方案是修改表名称,这时候也只能死马当作活马医了。

939e25200110654cc21282b2d37e73a.png

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

为什么更改了表名称后就正常呢,思来想去也想不出为什么。结果今天在重新部署服务的时候看了一眼历史部署记录,发现了端倪。就在假期的最后一天晚上有一个部署记录,然后我回看了和最开始发生数据异常的时间段相差无几。基本就可以断定和此次部署有很大的关系,由于公司内部的部署方案有docker和虚拟机两种方式,导致每个时间段都会有两个定时任务同时执行,由于数据处理的过程中需要查询第三方数据,最后两边写入的时间会存在一定的延时,导致写好的数据被另一边执行了删除的逻辑,由于那台服务器一直未更新修改的代码,一直执行的是最开始那份先删除再更新的逻辑。至于为啥执行了删除但是没有更新,猜想是删除后更新的逻辑出错了。这也是为什么修改了表名称后就正常了,因为那台服务器上面还是旧的代码,新增删除不能读到之前的那张表了,问题到此终于是告一段落了。

收尾

到此是否感觉看了一个大乌龙事件,最终的原因和代码没有任何关系,但是却三番五次的改动无果。在排查过程中还有很多没有写的,比如怀疑重复数据导致所以增加唯一索引,怀疑自增ID多大重新清零,但是这个改动的过程中也学到了不少新的知识,如何使用事务,新增唯一索引,修改表名称,重置自增ID等很多服务端相关的知识。最后的总结是遇到问题先不要质疑代码,从系统层面,运行版本,环境变量,运维等方面也要有一定的思考🤔。



相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
27天前
|
Java 关系型数据库 MySQL
SpringBoot 通过集成 Flink CDC 来实时追踪 MySql 数据变动
通过详细的步骤和示例代码,您可以在 SpringBoot 项目中成功集成 Flink CDC,并实时追踪 MySQL 数据库的变动。
181 43
|
20天前
|
存储 SQL 关系型数据库
MySQL底层概述—4.InnoDB数据文件
本文介绍了InnoDB表空间文件结构及其组成部分,包括表空间、段、区、页和行。表空间是最高逻辑层,包含多个段;段由若干个区组成,每个区包含64个连续的页,页用于存储多条行记录。文章还详细解析了Page结构,分为通用部分(文件头与文件尾)、数据记录部分和页目录部分。此外,文中探讨了行记录格式,包括四种行格式(Redundant、Compact、Dynamic和Compressed),重点介绍了Compact行记录格式及其溢出机制。最后,文章解释了不同行格式的特点及应用场景,帮助理解InnoDB存储引擎的工作原理。
MySQL底层概述—4.InnoDB数据文件
|
10天前
|
监控 关系型数据库 MySQL
MySQL和SQLSugar百万条数据查询分页优化
在面对百万条数据的查询时,优化MySQL和SQLSugar的分页性能是非常重要的。通过合理使用索引、调整查询语句、使用缓存以及采用高效的分页策略,可以显著提高查询效率。本文介绍的技巧和方法,可以为开发人员在数据处理和查询优化中提供有效的指导,提升系统的性能和用户体验。掌握这些技巧后,您可以在处理海量数据时更加游刃有余。
41 9
|
4天前
|
SQL 关系型数据库 MySQL
基于SQL Server / MySQL进行百万条数据过滤优化方案
对百万级别数据进行高效过滤查询,需要综合使用索引、查询优化、表分区、统计信息和视图等技术手段。通过合理的数据库设计和查询优化,可以显著提升查询性能,确保系统的高效稳定运行。
17 2
|
12天前
|
存储 关系型数据库 MySQL
MySQL进阶突击系列(09)数据磁盘存储模型 | 一行数据怎么存?
文中详细介绍了MySQL数据库中一行数据在磁盘上的存储机制,包括表空间、段、区、页和行的具体结构,以及如何设计和优化行数据存储以提高性能。
|
11天前
|
存储 SQL 关系型数据库
【YashanDB 知识库】MySQL 迁移至崖山 char 类型数据自动补空格问题
问题分类】功能使用 【关键字】char,char(1) 【问题描述】MySQL 迁移至崖山环境,字段类型源端和目标端都为 char(2),但应用存储的数据为'0'、'1',此时崖山查询该表字段时会自动补充空格 【问题原因分析】mysql 有 sql_mode 控制,检查是否启用了 PAD_CHAR_TO_FULL_LENGTH SQL 模式。如果启用了这个模式,MySQL 才会保留 CHAR 类型字段的尾随空格,默认没有启动。 #查看sql_mode mysql> SHOW VARIABLES LIKE 'sql_mode'; 【解决/规避方法】与应用确认存储的数据,正确定义数据
|
3月前
|
存储 关系型数据库 MySQL
mysql怎么查询longblob类型数据的大小
通过本文的介绍,希望您能深入理解如何查询MySQL中 `LONG BLOB`类型数据的大小,并结合优化技术提升查询性能,以满足实际业务需求。
194 6
|
3月前
|
SQL 关系型数据库 MySQL
mysql分页读取数据重复问题
在服务端开发中,与MySQL数据库进行数据交互时,常因数据量大、网络延迟等因素需分页读取数据。文章介绍了使用`limit`和`offset`参数实现分页的方法,并针对分页过程中可能出现的数据重复问题进行了详细分析,提出了利用时间戳或确保排序规则绝对性等解决方案。
151 1
|
4月前
|
缓存 NoSQL 关系型数据库
Redis和Mysql如何保证数据⼀致?
在项目中,为了解决Redis与Mysql的数据一致性问题,我们采用了多种策略:对于低一致性要求的数据,不做特别处理;时效性数据通过设置缓存过期时间来减少不一致风险;高一致性但时效性要求不高的数据,利用MQ异步同步确保最终一致性;而对一致性和时效性都有高要求的数据,则采用分布式事务(如Seata TCC模式)来保障。
102 14
|
4月前
|
关系型数据库 MySQL 数据库
GBase 数据库如何像MYSQL一样存放多行数据
GBase 数据库如何像MYSQL一样存放多行数据