记一次程序 Bug 导致数据删除的恢复过程

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
简介: 使用RDS、DMS进行数据恢复实践

场景

数据库中有张企业表,这个表里的删除字段 isdelete 给了默认值0,但开发在处理代码时编写的插入语句中带了这个 isdelete 字段,并且给了 Null 值,导致用户填写企业信息时失败,从而导致更新用户关联企业时这个用户的企业被更新为 Null。

与此同时后台操作人员又进行了一个操作,这个操作的大致步骤是,按照这个用户的所在企业查询相关用户并进行删除,但由于这个用户的企业是 Null 同时查询处理是个通用的方法对 Null 处理进行了跳过,最终导致查询结果是所有用户,接着令人恐怖的一幕发生了,这张表中的所有用户都被删除。

发现这个问题后,我的第一想法是,因为这张数据表的写入并不多,可以先按照更新时间来进行数据恢复,然而由于这张表历史比较久远,当时并没有对这个表的更新时间字段做变更自动更新,导致这个方法行不通。所以只能通过 binlog 来恢复。

基于数据库使用的是阿里云的 RDS 所以恢复过程还是比较顺畅的。

操作

1、创建数据追踪工单

选择对应的数据库、数据表,输入被误删的数据表表名,追踪类型选择更新,再根据报异常的时间设置时间范围。

生成后在工单详情可看到该时间范围内的变更数据记录,在变更时间列发现大量数据都在同一个时间范围内出现更新,因为该表的更新频次很低,所以我们可以根据这个变更时间来确定恢复数据的范围。

点击上图中的查看详情,可以看到具体变更的字段是哪些:

由此即可确定误删数据了。

2、修复数据

在工单内点击导出回滚脚本,然后根据脚本进行数据回滚。以下简单举例下脚本的内容:

UPDATE `database`.`table` SET `id`=5510 ,
  #...此处省略若干表中的字段... 
  `isdelete`=0 WHERE  (`id`=5510);

回滚的脚本就是按照数据表中的主键来将数据恢复到修改之前的样子,从上面的语句可以看到,在恢复的语句中已经将 isdelete 这个字段设置为 0 了。这个语句中还会包含其他的字段,此处我在恢复数据时,并没有将其他字段也放到 update 语句中,只做了 isdelete 字段的恢复。

使用修改后的 SQL 提交数据变更工单即可将数据恢复。

总结

1、线上问题处理思路

碰到线上问题,我们应该第一时间去用最快并且质量有保障的办法解决问题,然后再追查原因,定责。比如本次事故中,优先恢复数据,再确定产生问题的原因,解决 bug 并发布。

  • 确定出现问题的时间
  • 根据业务的情况,确定数据恢复方案
  • 根据问题时间查找接口访问日志,确定问题接口
  • 由问题接口确认业务影响的范围,改正问题

2、开发设计思路

  • 数据表的创建时间、更新时间、是否删除字段设置为插入默认值,更新时间为根据当前时间戳更新

  • 设计到数据删除的代码,需要做严格的校验,当数量超过一定范围时需要进行提示阻断
  • 开发在开发环境调试时,应该做数据 sql 自检查
相关文章
|
4月前
|
存储 Windows
删除的视频怎样才能恢复?详尽指南
误删视频别慌,本文概览实用恢复技巧。首要行动:停用涉事存储以防数据覆盖。探索回收站,检索近期删除。备份是宝藏,搜寻云或外置硬盘。软件救星谨慎付费,试用验证。极端情况,专家服务可开盘恢复,代价高昂需权衡。
删除的视频怎样才能恢复?详尽指南
|
3月前
|
运维 监控 安全
自动恢复机制在哪些情况下可能无法正常工作
自动恢复机制在哪些情况下可能无法正常工作
|
安全 关系型数据库 MySQL
为什么延迟复制适用于备库数据的紧急恢复?底层原理是什么?
为什么延迟复制适用于备库数据的紧急恢复?底层原理是什么?
120 0
R代码忘记保存,系统崩溃了怎么办?
跑程序时电脑突然崩溃,程序被强制中断导致代码不见了怎么办? 这些糟心的情况想必每个打工人都不想经历,偏偏我就是那个倒霉蛋,今早打开电脑发现昨晚写的代码忘记保存,心态崩到想当场飙眼泪,冷静下来之后开始寻找解决方案
1383 0
R代码忘记保存,系统崩溃了怎么办?
|
开发工具 git
pull错代码起冲突,恢复到pull之前,切换历史版本 ---本地代码回退
pull错代码起冲突,恢复到pull之前,切换历史版本 ---本地代码回退
363 0
|
程序员
当你无法发现问题所在时,不要简单地把代码或者数据还原
这几天有一位同事需要做与我一样的功能,而这个功能是我已经开发好了的,他只需直接把我的代码拿去修改就可以。结果,我的代码可以正常运行,他的代码在开启服务之后,控制台就不断有日志输出,开发环境进入了死机状态。
1650 0