前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >真·MySQL误操作差点删库跑路

真·MySQL误操作差点删库跑路

作者头像
素履coder
发布2022-11-12 14:50:12
6230
发布2022-11-12 14:50:12
举报
文章被收录于专栏:素履coder

1. 背景#

最近有一个需求,需要根据业务需求更新数据库中某张表的state字段数据,这其实是一个很简单的需求,sql语句就一行更新语句:update table set state = ? where sn = ?,表示对table表根据不同sn去修改state的值,state是tinyint类型,sn是varchar类型且sn是唯一的,然后for循环这个操作。

当时我犯的错误非常低级,我写成了update table set state = ? and sn = ?,想当然的把where写成了and,然后还没有发现问题,最终执行的结果就是整张表的state的值变成了0,这张表一共有5千多万条数据,造成了一段时间的锁表,导致线上停了一个多小时,直到服务器报警我们才收到通知。

2. 原因分析#

现在我建一个表来复现这个情况

代码语言:javascript
复制
CREATE TABLE `testupdate` (
  `id` int(11) NOT NULL,
  `state` tinyint(4) NOT NULL DEFAULT '0',
  `sn` varchar(64) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  UNIQUE KEY `sn_UNIQUE` (`sn`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

插入一些数据

接下来我执行这个语句update testupdate set state = 10 and sn = "aaa";,得到的结果如下

为什么会得到这个结果呢?其实是state = 之后的语句做了逻辑运算,首先看第一行,为什么这一行的state的值会变成1呢?因为10 and sn = "aaa"运算得出的结果为true,true转化成int类型为1,所以结果就是1;而后面的5行因为sn对不上,所以都为false,即值为0

更新语句正确的写法是:

代码语言:javascript
复制
update table set col = ?, col = ? where [条件]

3. 解决办法#

我们的解决办法是在阿里云下载故障发生前最新的备份,然后编写脚本,根据id一一对应的把state字段的数据修改过来,故障期间造成了一些数据的丢失,不过好在不多,只能根据他们的反馈然后把数据补上

最后,经过分析可以知道,开头提到的写法本身就是错误的,但是mysql并没有报语法错误,所以我运行完上面那个语句之后,结果线上出现了问题,一时之间还找不出究竟是什么引起的,隔了一段时间在同事的提醒下我才反应过来,如果不能及时知道问题的起因,那么排查问题的方向就会出错,拖得时间长了,造成的经济损失不可估量,幸好这个故障发生在国庆放假期间,不然真的就要跑路了😂

我的反省是要更加的细心,我本身是知道更新语句怎么写的,但是有时候脑子一热就会写错,而且我是在国庆期间写的,没有做到全神贯注

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-10-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 背景#
  • 2. 原因分析#
  • 3. 解决办法#
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档