处理一个很不合理的测试需求,需要手动修改数据库若干条记录,平时用惯了 orm ,真在终端写 sql 语句的机会非常少。也是由于基本功太生疏,导致在 select 找到要修改的记录之后直接 update 一敲忘了加 where ,结果把所有数据都更新了,影响是相关所有数据变的不可用,并且影了前端组件的加载。现在回滚数据库就只能损失一天的数据了,还好是集成环境,如果是生产环境,真不敢想是什么后果。
![]() | 1 gosidealone 2022-01-21 09:50:16 +08:00 ![]() 数据库线上执行的 sql 还是 dba 审核下吧 |
![]() | 2 zhoudaiyu PRO CI 中不会检测这种 SQL 吗? |
3 zhangchongjie 2022-01-21 09:52:03 +08:00 回滚吧 |
![]() | 4 sadfQED2 2022-01-21 09:52:16 +08:00 via Android ![]() 我们线上数据库审核要求 update 不但必须有 where 还必须有 limit |
![]() | 5 ersic 2022-01-21 09:53:46 +08:00 via Android 拿不准就先备份再执行命令 |
![]() | 6 Kontinue 2022-01-21 09:55:36 +08:00 ![]() 这个时候要讲讲 jb 家的 datagrip 了,基本上风险操作都会提示的。。。 --- Unsafe query: 不带 'where' 的 'Update' 语句会同时更新所有表行 |
![]() | 7 murmur 2022-01-21 09:56:20 +08:00 ![]() 测试数据不就是这样么,我们都是要在测试环境执行一遍,再把语句给别人发布 |
![]() | 8 lwldcr 2022-01-21 09:57:34 +08:00 ![]() 出来工作第一年的时候我干过一模一样的事情 最后的结果就是领导陪我修数据修到十一点半,更绝的是当时领导还一只手受伤打着石膏,一只手在敲命令 往事不堪回首啊,曾经的自己真是又年轻又菜,虽然现在年轻都没有了只剩下菜 |
![]() | 9 wolfie 2022-01-21 09:58:00 +08:00 盲猜 navicat 。 一般 GUI 要么提醒没有 where ,要么自动开启事务。 |
![]() | 10 nonoyang 2022-01-21 09:58:46 +08:00 这时候就体现出 autocommit 是 off 的好处了,我每次都得手动 commit 。 |
![]() | 11 feeeei 2022-01-21 10:00:57 +08:00 记得是有个配置可以配的,限制 update 必须带 where ,可以避免这种疏忽大意的问题 |
12 securityCoding 2022-01-21 10:00:59 +08:00 ![]() 更新 sql 习惯性的会先 select 一下 |
![]() | 13 FawkesV 2022-01-21 10:01:51 +08:00 之前在小公司的时候, 也有过直接命令行执行 SQL update 处理数据的经历. 每次在执行前都要重复看三次才能执行. 执行的时候心都是悬的. 后来到大了点的公司,生产环境就只有 DBA 才有权限了,都是发邮件去通知执行. 虽然操作上麻烦了,但是有人帮你审核就好多了. |
![]() | 14 huihuiHK 2022-01-21 10:02:04 +08:00 前段时间本人在生产上执行了一个没有 where 的 update 句,还好是新功能还在灰度,影响不大 |
15 ahsjs 2022-01-21 10:03:38 +08:00 ![]() 执行 sql 要两个人一起还是有效果的 |
16 jjww 2022-01-21 10:04:40 +08:00 出来工作第一年的时候我干过一模一样的事情 +1 |
17 onhao 2022-01-21 10:05:51 +08:00 大兄弟 推荐你用 mysqlworkbench https://wuhao.pw/archives/291/ 执行 update 都是要 where 和 limit 来限制的,否则会提示安全风险。 |
18 Jooooooooo 2022-01-21 10:06:35 +08:00 所以说生产环境一般会开启没有 where 不让 update 的设置, 防这种情况. |
![]() | 19 didididididi 2022-01-21 10:12:35 +08:00 哈哈哈,我实习第一年也这样弄过,还好废了九牛二虎之力,给恢复了 |
![]() | 20 Veneris 2022-01-21 10:15:20 +08:00 via iPhone 经历过,还好是开发环境,后来另一个同事生产环境来了一次,用阿里云的秒级备份恢复了 |
![]() | 21 cheng6563 2022-01-21 10:15:45 +08:00 维护过一个屎山,里面的 deleteById 方法里面没有 where 。。 |
![]() | 22 hidemyself 2022-01-21 10:15:54 +08:00 我们线上要三方确认,才能执行 |
![]() | 23 imherer 2022-01-21 10:16:35 +08:00 以前公司有一天上班内部系统所有人都登录不上去了,提示密码错误。后来一看 发现所有账号的密码都是摸一样,结果是一个实习生 update 秘密没加条件,还好是公司内部系统。 从那以后所有开发人员只有查看权限了 |
![]() | 24 jy02201949 2022-01-21 10:17:58 +08:00 update 是 DML 怎么会直接更新呢,除非直接带 commit 上去,兄弟这么勇的啊,不都是先检查一番再提交吗 |
![]() | 25 lawsiki 2022-01-21 10:18:49 +08:00 之前线上有个 update 未拼接上查询条件,跑了一天才发现问题,还好用的 RDS 支持数据恢复 |
![]() | 26 weiwenhao 2022-01-21 10:26:03 +08:00 golang 的 gorm db.Where(User{}) |
![]() | 27 weiwenhao 2022-01-21 10:27:08 +08:00 几年前遇到的 golang 的 gorm db.Where(User{ id: 0 }).Update("nickname", "1234) 会直接去掉 where 执行 update |
![]() | 28 darksword21 PRO mycli 手动挡人集合! |
![]() | 29 b1ackjack 2022-01-21 10:38:49 +08:00 我司只允许主键匹配的 update |
![]() | 30 Alchemistboy 2022-01-21 11:32:37 +08:00 打着石膏还工作?啥公司这么狠啊 |
31 messi110 2022-01-21 11:33:01 +08:00 有的时候操作 大意就是会犯各种低级错误 所以生产环境一定要 按规范来 |
![]() | 32 icewent 2022-01-21 11:38:17 +08:00 没关系,这种事干一次就能记住,损失越大越深刻。 |
33 Rache1 2022-01-21 11:39:41 +08:00 |
34 yuanhuaqiang 2022-01-21 11:51:09 +08:00 oracle flashback 挺好用 |
35 seanzxx 2022-01-21 12:10:44 +08:00 via iPhone 曾经一家公司是卖软件给保险公司的,有时候出 bug 了就登录到客户的数据库改改数据,听说一个新人需要删除一批数据,再添加一些新数据,但远程数据库比较慢,他就 Google 了下怎么快速删除记录,查到了 truncate 这个命令,而且他还真敢用,结果导致了一个重大事故 |
![]() | 36 meiyoumingzi6 2022-01-21 12:10:48 +08:00 害 我们小伙伴还有删表的呢 |
![]() | 37 seers 2022-01-21 12:18:57 +08:00 via Android 你直接断掉 update 不就行了,直接回滚无事发生,不带条件的 update 一般跑很久够你断掉了 |
38 sansanhehe 2022-01-21 12:37:48 +08:00 我一般会把要执行的 SQL 写在 sublime text 上,自己 review 一遍再执行(即使是本地测试环境),生产环境的 SQL 要写进文档里让其他同事一起 review 。养成好习惯,保护好自己的年终奖 |
![]() | 39 eggshell 2022-01-21 12:45:12 +08:00 我司的 SQL 工单后台提交之前会计算一个大概的影响行数,虽然不太准 |
![]() | 41 dallaslu 2022-01-21 12:47:39 +08:00 至少要把 select 的语句复制一下,留着 where 呀 |
![]() | 42 IvanLi127 2022-01-21 12:51:13 +08:00 via Android 我操作数据库,都先备份整个库。还好生产环境和我没啥关系,不然太刺激了,受不了,也备份不动 |
![]() | 43 Hanggi 2022-01-21 12:51:53 +08:00 咦?我用的 ORM 如果不写 Where 的话 Update 会报错,所以所有 Update 都有 Where 。 换个 ORM 吧。 |
![]() | 44 xuanbg 2022-01-21 12:52:32 +08:00 不要回滚,用备份恢复数据到新表,然后根据 ID 从新表更新数据到原表即可。这样损失最小。 |
![]() | 45 ClericPy 2022-01-21 12:55:21 +08:00 这个情况... 没什么规范的情况下, 只要是改库都是先 select 吧 反正我吐槽现公司让非开发人员有数据库权限这事一年多了, 都不当回事我也没办法, 开发人员手写 SQL 都那么危险, 还让运营人员直连, 真是没在社会挨过打 |
46 CallMeReznov 2022-01-21 12:58:21 +08:00 牛的,10 年前有幸干了一次. 我直接执行了开发传过来的升级脚本. 刚开始执行就听到他人墩墩墩吨的跑来大喊"别执行别执行!" 好家伙把我所有用户的资料全 update 了. 当时我双手都在颤抖... 没办法影响面太大只能直接回滚到一个小时之前. |
47 fanyingmao 2022-01-21 13:01:58 +08:00 每次线上执行语句,我都要测试服先试下,就怕出现这种事故。 |
48 feiyangenator 2022-01-21 13:12:41 +08:00 ![]() 先执行 begin 命令,然后 update ,确保没问题,再执行 commit 命令。 |
![]() | 49 imdong 2022-01-21 13:30:44 +08:00 via iPhone 我们生产的一个脚本里 update 没有 where 好久了,一直没人提,我发现了但我也没提。 最近年底全面测试,被人作为 BUG 提了出来,我才改了的 |
![]() | 50 trcnkq 2022-01-21 13:39:29 +08:00 CLI 手敲 SQL ,习惯先敲 where ,再移到前面敲 update ,防止手抖。。 |
![]() | 51 akira 2022-01-21 13:41:06 +08:00 上 archery ,不要让开发人员直接连数据库去执行 sql |
52 laicanwen 2022-01-21 13:48:58 +08:00 我也干过,还是在生产环境……好在不是什么重要数据,而且刚刚备份完。 |
![]() | 53 SmiteChow 2022-01-21 13:52:28 +08:00 怕什么,又没爆头。 |
![]() | 54 onionKnight888 2022-01-21 13:53:12 +08:00 update xxxx where 1=1 |
55 haohong725 2022-01-21 13:55:18 +08:00 update 和 delete 我一般后面都会加上 limit |
![]() | 56 Asuka0947 2022-01-21 13:57:29 +08:00 现在我都生产环境设置为大红色了,有点警示作用。 |
57 photon006 2022-01-21 14:01:07 +08:00 用 dbeaver ,update 不加 where 会有危险警告,确认才会继续执行。 |
![]() | 58 abccccabc 2022-01-21 14:26:53 +08:00 我有幸也干过两次,不过都是在测试环境 |
![]() | 59 zhhqiang 2022-01-21 14:30:23 +08:00 via Android 与 rm -rf 执行差不太多 |
![]() | 60 yogogo 2022-01-21 14:45:32 +08:00 @securityCoding #12 这是好习惯,我也是这样,哈哈哈哈 |
![]() | 61 pengtdyd 2022-01-21 14:47:55 +08:00 不要怕啊,赶紧执行 rm -rf 恢复一下,快!!!! |
62 aeli 2022-01-21 14:54:04 +08:00 遇到过一次 navi 的坑,查询 where 是中文字符,结果拷贝到正式环境执行的时候,中文字符被过滤掉了,变成了 where xx like '%%' |
![]() | 63 creanme 2022-01-21 15:03:15 +08:00 我朋友在生产环境犯了同样的错,被全集团通报了。 |
![]() | 64 zakokun 2022-01-21 15:10:02 +08:00 @feiyangenator #47 这个办法确实好,严谨 |
![]() | 65 jessun1990 2022-01-21 15:55:39 +08:00 生产环境上 sql ,建议用一些 sql 审核工具吧? |
![]() | 66 ryd994 2022-01-21 15:58:51 +08:00 via Android ![]() 只要是人就一定会出错,靠自觉是没用的。生产环境的命令一定要 code review 。即使有 review 也不能保证安全,因为可能俩人都犯傻了。所以还要限速限量,然后规模从小到大,执行一批检查一遍。 这都是无数事故总结出来的经验。 |
![]() | 67 uiosun 2022-01-21 16:07:38 +08:00 update 忘了加 where 大哥,你们平台就没个提醒的?这都能直接提交?就离谱,这哪能靠人自觉啊! |
![]() | 68 Mac 2022-01-21 16:11:22 +08:00 via Android 我用 heidisql ,如果没 where 执行前会提示你 |
![]() | 69 tabrye 2022-01-21 16:29:58 +08:00 敏感操作前先备份是好习惯 话说 测试库 不是随便玩 |
![]() | 70 junphe 2022-01-21 16:31:40 +08:00 rm -rf / 这个操作我还真干过,不过立马反映过来,中止了!只是损失了一些数据,系统没有受影响!想想都后怕 |
![]() | 72 neptuno 2022-01-21 17:00:19 +08:00 一般提交这种 sql 需要多叫几个人 check 一下。 |
![]() | 73 MonkeyJon 2022-01-21 17:00:29 +08:00 线上数据库除了查询操作,其他都需要发公文让领导知道,哪怕是一条 sql ,目前公司政策 |
![]() | 74 RRRoger 2022-01-21 17:01:58 +08:00 教训:在做 update/delete 之前 一定要先 select 一下 |
![]() | 75 wxboy 2022-01-21 17:05:24 +08:00 先写查询 /匹配语句,检查语句没有问题后,再写操作命令(update/delete) |
![]() | 76 labulaka521 2022-01-21 17:18:56 +08:00 update table set delete_time='xxxxx' where (order_id) 这种语句竟然不报错 |
![]() | 77 815979670 2022-01-21 17:21:28 +08:00 ![]() 我们一般就是先查询有多少条 然后再 update limit 查询条数 ,如果只处理 1 条 就是 limit 1 |
![]() | 78 chevalier 2022-01-21 17:48:07 +08:00 线上都是先敲好 where 语句,然后再补 update ... set ... 就怕手抖提交了 |
![]() | 79 liuxu 2022-01-21 17:56:08 +08:00 领导:问题不大。这小伙子永远不要再碰数据库了。 |
80 ilylx2008 2022-01-21 18:34:39 +08:00 程序员的必经过程之一。 |
81 mywind 2022-01-21 19:55:37 +08:00 今天一样的经历,好在是测试数据库,binglog 也是 row 。很快就修复了。以后说什么终端打 sql 要加 begin 了。 |
![]() | 82 cvooc 2022-01-21 20:01:09 +08:00 via Android 妈耶 看到这标题我血压就开始升高了 敏感操作前备份是个好习惯 好歹能回滚下 |
![]() | 83 documentzhangx66 2022-01-21 20:12:06 +08:00 1.无论是 SQL 、程序代码、甚至在服务器上安装程序,或者在服务器上执行 shell ,请都先在相同的测试环境下,进行测试。执行后,确认业务任然正常,确认压测结论没有太大性能变化,再去服务器上执行。 而且 SQL 这种执行前,对服务器做个数据备份,还是很有必要的。 2.这种方案,不仅能避免自己写错导致的问题,甚至连一些软件的 bug ,也能避开一部分。 3.千万别偷懒,请做好测试,请在正式环境中执行危险操作前做好备份! |
![]() | 84 WilliamYang 2022-01-21 21:36:37 +08:00 @weiwenhao gorm 这个特性,害了很多公司,很多人 |
![]() | 85 viator42 2022-01-21 21:47:08 +08:00 via Android 以前我也办过这种事,干活的时候没看清把公司 OA 生产环境的数据库清空了。突然嗷的一嗓子整层楼乱成一团,我赶紧把昨天的备份导进去才安静下来 |
![]() | 86 AlexaZhou 2022-01-21 22:10:06 +08:00 手动执行 update 是比较危险,最好 begin transaction ,然后 update 再 commit ; 为了保险起见,我还有个习惯是先敲 where 条件, 再退回来敲 set xx=xxx |
![]() | 87 ajaxfunction 2022-01-22 01:02:24 +08:00 这种事情都会经历的,不经历记不住,就看影响大小了。 当年我在小公司做的项目数据库都没备份的,直到有一次 本以为在操作测试环境, 结果操作了生产环境,把所有人昵称都改成统一的了,反正就是头皮发麻,现在那种感觉现在都记得,估计当时高血压了。 后来才养成了习惯 每个项目无论用哪种手段每天 必须备份数据库,虽然后来一次也没用的上。 |
88 rookien 2022-01-22 11:33:30 +08:00 想起来我前年入职第一家公司的时候,也是忘了加 where ,当时心里是真的慌得一 p 啊,只能说还好是测试环境 |
![]() | 89 UN2758 2022-01-22 19:17:05 +08:00 ![]() @lwldcr #8 同病相怜啊,我也是写的修数据脚本有 bug ,在生产环境上跑,结果把数据全清掉了,害得 cto 陪我一起修数据修到 11 点 |
90 qyvlik 2022-02-09 09:32:13 +08:00 上线 SQL 用 https://github.com/hhyo/Archery ,这个工具使用 goinception 做 SQL 的执行和备份,可以检查不安全的语句,以及执行 SQL 后回滚的 SQL 都会给你自动生成。 archery 的同类品还有如下: https://github.com/jly8866/archer https://github.com/cookieY/Yearning |