V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
moonchild
V2EX  ›  数据库

操作数据库 update 忘了加 where

  •  2
     
  •   moonchild · 2022-01-21 09:46:25 +08:00 via iPhone · 9229 次点击
    这是一个创建于 797 天前的主题,其中的信息可能已经有所发展或是发生改变。

    处理一个很不合理的测试需求,需要手动修改数据库若干条记录,平时用惯了 orm ,真在终端写 sql 语句的机会非常少。也是由于基本功太生疏,导致在 select 找到要修改的记录之后直接 update 一敲忘了加 where ,结果把所有数据都更新了,影响是相关所有数据变的不可用,并且影响了前端组件的加载。现在回滚数据库就只能损失一天的数据了,还好是集成环境,如果是生产环境,真不敢想是什么后果。

    90 条回复    2022-02-09 09:32:13 +08:00
    gosidealone
        1
    gosidealone  
       2022-01-21 09:50:16 +08:00   ❤️ 1
    数据库线上执行的 sql 还是 dba 审核下吧
    zhoudaiyu
        2
    zhoudaiyu  
       2022-01-21 09:50:35 +08:00
    CI 中不会检测这种 SQL 吗?
    zhangchongjie
        3
    zhangchongjie  
       2022-01-21 09:52:03 +08:00
    🐮回滚吧
    sadfQED2
        4
    sadfQED2  
       2022-01-21 09:52:16 +08:00 via Android   ❤️ 1
    我们线上数据库审核要求 update 不但必须有 where 还必须有 limit
    ersic
        5
    ersic  
       2022-01-21 09:53:46 +08:00 via Android
    拿不准就先备份再执行命令
    Kontinue
        6
    Kontinue  
       2022-01-21 09:55:36 +08:00   ❤️ 6
    这个时候要讲讲 jb 家的 datagrip 了,基本上风险操作都会提示的。。。
    ---
    Unsafe query: 不带 'where' 的 'Update' 语句会同时更新所有表行
    murmur
        7
    murmur  
       2022-01-21 09:56:20 +08:00   ❤️ 2
    测试数据不就是这样么,我们都是要在测试环境执行一遍,再把语句给别人发布
    lwldcr
        8
    lwldcr  
       2022-01-21 09:57:34 +08:00   ❤️ 61
    出来工作第一年的时候我干过一模一样的事情

    最后的结果就是领导陪我修数据修到十一点半,更绝的是当时领导还一只手受伤打着石膏,一只手在敲命令

    往事不堪回首啊,曾经的自己真是又年轻又菜,虽然现在年轻都没有了只剩下菜
    wolfie
        9
    wolfie  
       2022-01-21 09:58:00 +08:00
    盲猜 navicat 。
    一般 GUI 要么提醒没有 where ,要么自动开启事务。
    nonoyang
        10
    nonoyang  
       2022-01-21 09:58:46 +08:00
    这时候就体现出 autocommit 是 off 的好处了,我每次都得手动 commit 。
    MiniGhost
        11
    MiniGhost  
       2022-01-21 10:00:57 +08:00
    记得是有个配置可以配的,限制 update 必须带 where ,可以避免这种疏忽大意的问题
    securityCoding
        12
    securityCoding  
       2022-01-21 10:00:59 +08:00   ❤️ 4
    更新 sql 习惯性的会先 select 一下
    FawkesV
        13
    FawkesV  
       2022-01-21 10:01:51 +08:00
    之前在小公司的时候, 也有过直接命令行执行 SQL update 处理数据的经历. 每次在执行前都要重复看三次才能执行. 执行的时候心都是悬的.
    后来到大了点的公司,生产环境就只有 DBA 才有权限了,都是发邮件去通知执行. 虽然操作上麻烦了,但是有人帮你审核就好多了.
    huihuiHK
        14
    huihuiHK  
       2022-01-21 10:02:04 +08:00
    前段时间本人在生产上执行了一个没有 where 的 update 语句,还好是新功能还在灰度,影响不大
    ahsjs
        15
    ahsjs  
       2022-01-21 10:03:38 +08:00   ❤️ 1
    执行 sql 要两个人一起还是有效果的
    jjww
        16
    jjww  
       2022-01-21 10:04:40 +08:00
    出来工作第一年的时候我干过一模一样的事情 +1
    onhao
        17
    onhao  
       2022-01-21 10:05:51 +08:00
    大兄弟 推荐你用 mysqlworkbench https://wuhao.pw/archives/291/
    执行 update 都是要 where 和 limit 来限制的,否则会提示安全风险。
    Jooooooooo
        18
    Jooooooooo  
       2022-01-21 10:06:35 +08:00
    所以说生产环境一般会开启没有 where 不让 update 的设置, 防这种情况.
    didididididi
        19
    didididididi  
       2022-01-21 10:12:35 +08:00
    哈哈哈,我实习第一年也这样弄过,还好废了九牛二虎之力,给恢复了
    Veneris
        20
    Veneris  
       2022-01-21 10:15:20 +08:00 via iPhone
    经历过,还好是开发环境,后来另一个同事生产环境来了一次,用阿里云的秒级备份恢复了
    cheng6563
        21
    cheng6563  
       2022-01-21 10:15:45 +08:00
    维护过一个屎山,里面的 deleteById 方法里面没有 where 。。
    hidemyself
        22
    hidemyself  
       2022-01-21 10:15:54 +08:00
    我们线上要三方确认,才能执行
    imherer
        23
    imherer  
       2022-01-21 10:16:35 +08:00
    以前公司有一天上班内部系统所有人都登录不上去了,提示密码错误。后来一看 发现所有账号的密码都是摸一样,结果是一个实习生 update 秘密没加条件,还好是公司内部系统。 从那以后所有开发人员只有查看权限了
    jy02201949
        24
    jy02201949  
       2022-01-21 10:17:58 +08:00
    update 是 DML 怎么会直接更新呢,除非直接带 commit 上去,兄弟这么勇的啊,不都是先检查一番再提交吗
    lawsiki
        25
    lawsiki  
       2022-01-21 10:18:49 +08:00
    之前线上有个 update 未拼接上查询条件,跑了一天才发现问题,还好用的 RDS 支持数据恢复
    weiwenhao
        26
    weiwenhao  
       2022-01-21 10:26:03 +08:00
    golang 的 gorm

    db.Where(User{})
    weiwenhao
        27
    weiwenhao  
       2022-01-21 10:27:08 +08:00
    几年前遇到的
    golang 的 gorm

    db.Where(User{
    id: 0
    }).Update("nickname", "1234)

    会直接去掉 where 执行 update
    darksword21
        28
    darksword21  
       2022-01-21 10:28:59 +08:00 via iPhone
    mycli 手动挡人集合!
    b1ackjack
        29
    b1ackjack  
       2022-01-21 10:38:49 +08:00
    我司只允许主键匹配的 update
    Alchemistboy
        30
    Alchemistboy  
       2022-01-21 11:32:37 +08:00
    打着石膏还工作?啥公司这么狠啊
    messi110
        31
    messi110  
       2022-01-21 11:33:01 +08:00
    有的时候操作 大意就是会犯各种低级错误
    所以生产环境一定要 按规范来
    icewent
        32
    icewent  
       2022-01-21 11:38:17 +08:00
    没关系,这种事干一次就能记住,损失越大越深刻。
    Rache1
        33
    Rache1  
       2022-01-21 11:39:41 +08:00
    下次注意,MySQL 可以设置一下有安全提示。

    https://dev.mysql.com/doc/refman/8.0/en/mysql-tips.html#safe-updates
    yuanhuaqiang
        34
    yuanhuaqiang  
       2022-01-21 11:51:09 +08:00
    oracle flashback 挺好用
    seanzxx
        35
    seanzxx  
       2022-01-21 12:10:44 +08:00 via iPhone
    曾经一家公司是卖软件给保险公司的,有时候出 bug 了就登录到客户的数据库改改数据,听说一个新人需要删除一批数据,再添加一些新数据,但远程数据库比较慢,他就 Google 了下怎么快速删除记录,查到了 truncate 这个命令,而且他还真敢用,结果导致了一个重大事故
    meiyoumingzi6
        36
    meiyoumingzi6  
       2022-01-21 12:10:48 +08:00
    害 我们小伙伴还有删表的呢
    seers
        37
    seers  
       2022-01-21 12:18:57 +08:00 via Android
    你直接断掉 update 不就行了,直接回滚无事发生,不带条件的 update 一般跑很久够你断掉了
    sansanhehe
        38
    sansanhehe  
       2022-01-21 12:37:48 +08:00
    我一般会把要执行的 SQL 写在 sublime text 上,自己 review 一遍再执行(即使是本地测试环境),生产环境的 SQL 要写进文档里让其他同事一起 review 。养成好习惯,保护好自己的年终奖 😂
    eggshell
        39
    eggshell  
       2022-01-21 12:45:12 +08:00
    我司的 SQL 工单后台提交之前会计算一个大概的影响行数,虽然不太准
    zhoudaiyu
        40
    zhoudaiyu  
       2022-01-21 12:45:41 +08:00
    @zhoudaiyu #2 没读题,没看到是命令行
    dallaslu
        41
    dallaslu  
       2022-01-21 12:47:39 +08:00
    至少要把 select 的语句复制一下,留着 where 呀
    IvanLi127
        42
    IvanLi127  
       2022-01-21 12:51:13 +08:00 via Android
    我操作数据库,都先备份整个库。还好生产环境和我没啥关系,不然太刺激了,受不了,也备份不动
    Hanggi
        43
    Hanggi  
       2022-01-21 12:51:53 +08:00
    咦?我用的 ORM 如果不写 Where 的话 Update 会报错,所以所有 Update 都有 Where 。
    换个 ORM 吧。
    xuanbg
        44
    xuanbg  
       2022-01-21 12:52:32 +08:00
    不要回滚,用备份恢复数据到新表,然后根据 ID 从新表更新数据到原表即可。这样损失最小。
    ClericPy
        45
    ClericPy  
       2022-01-21 12:55:21 +08:00
    这个情况... 没什么规范的情况下, 只要是改库都是先 select 吧

    反正我吐槽现公司让非开发人员有数据库权限这事一年多了, 都不当回事我也没办法, 开发人员手写 SQL 都那么危险, 还让运营人员直连, 真是没在社会挨过打
    CallMeReznov
        46
    CallMeReznov  
       2022-01-21 12:58:21 +08:00
    牛的,10 年前有幸干了一次.
    我直接执行了开发传过来的升级脚本.
    刚开始执行就听到他人墩墩墩吨的跑来大喊"别执行别执行!"
    好家伙把我所有用户的资料全 update 了. 当时我双手都在颤抖...
    没办法影响面太大只能直接回滚到一个小时之前.
    fanyingmao
        47
    fanyingmao  
       2022-01-21 13:01:58 +08:00
    每次线上执行语句,我都要测试服先试下,就怕出现这种事故。
    feiyangenator
        48
    feiyangenator  
       2022-01-21 13:12:41 +08:00   ❤️ 1
    先执行 begin 命令,然后 update ,确保没问题,再执行 commit 命令。
    imdong
        49
    imdong  
       2022-01-21 13:30:44 +08:00 via iPhone
    我们生产的一个脚本里 update 没有 where 好久了,一直没人提,我发现了但我也没提。

    最近年底全面测试,被人作为 BUG 提了出来,我才改了的
    trcnkq
        50
    trcnkq  
       2022-01-21 13:39:29 +08:00
    CLI 手敲 SQL ,习惯先敲 where ,再移到前面敲 update ,防止手抖。。
    akira
        51
    akira  
       2022-01-21 13:41:06 +08:00
    上 archery ,不要让开发人员直接连数据库去执行 sql
    laicanwen
        52
    laicanwen  
       2022-01-21 13:48:58 +08:00
    我也干过,还是在生产环境……好在不是什么重要数据,而且刚刚备份完。
    SmiteChow
        53
    SmiteChow  
       2022-01-21 13:52:28 +08:00
    怕什么,又没爆头。
    onionKnight888
        54
    onionKnight888  
       2022-01-21 13:53:12 +08:00
    update xxxx where 1=1
    haohong725
        55
    haohong725  
       2022-01-21 13:55:18 +08:00
    update 和 delete 我一般后面都会加上 limit
    Asuka0947
        56
    Asuka0947  
       2022-01-21 13:57:29 +08:00
    现在我都生产环境设置为大红色了,有点警示作用。
    photon006
        57
    photon006  
       2022-01-21 14:01:07 +08:00
    用 dbeaver ,update 不加 where 会有危险警告,确认才会继续执行。
    abccccabc
        58
    abccccabc  
       2022-01-21 14:26:53 +08:00
    我有幸也干过两次,不过都是在测试环境
    zhhqiang
        59
    zhhqiang  
       2022-01-21 14:30:23 +08:00 via Android
    与 rm -rf 执行差不太多
    yogogo
        60
    yogogo  
       2022-01-21 14:45:32 +08:00
    @securityCoding
    #12 这是好习惯,我也是这样,哈哈哈哈
    pengtdyd
        61
    pengtdyd  
       2022-01-21 14:47:55 +08:00
    不要怕啊,赶紧执行 rm -rf 恢复一下,快!!!!
    aeli
        62
    aeli  
       2022-01-21 14:54:04 +08:00
    遇到过一次 navi 的坑,查询 where 是中文字符,结果拷贝到正式环境执行的时候,中文字符被过滤掉了,变成了 where xx like '%%'
    creanme
        63
    creanme  
       2022-01-21 15:03:15 +08:00
    我朋友在生产环境犯了同样的错,被全集团通报了。
    zakokun
        64
    zakokun  
       2022-01-21 15:10:02 +08:00
    @feiyangenator #47 这个办法确实好,严谨
    jessun1990
        65
    jessun1990  
       2022-01-21 15:55:39 +08:00
    生产环境上 sql ,建议用一些 sql 审核工具吧?
    ryd994
        66
    ryd994  
       2022-01-21 15:58:51 +08:00 via Android   ❤️ 1
    只要是人就一定会出错,靠自觉是没用的。生产环境的命令一定要 code review 。即使有 review 也不能保证安全,因为可能俩人都犯傻了。所以还要限速限量,然后规模从小到大,执行一批检查一遍。
    这都是无数事故总结出来的经验。
    uiosun
        67
    uiosun  
       2022-01-21 16:07:38 +08:00
    update 忘了加 where

    大哥,你们平台就没个提醒的?这都能直接提交?就离谱,这哪能靠人自觉啊!
    Mac
        68
    Mac  
       2022-01-21 16:11:22 +08:00 via Android
    我用 heidisql ,如果没 where 执行前会提示你
    tabrye
        69
    tabrye  
       2022-01-21 16:29:58 +08:00
    敏感操作前先备份是好习惯
    话说 测试库 不是随便玩
    junphe
        70
    junphe  
       2022-01-21 16:31:40 +08:00
    rm -rf / 这个操作我还真干过,不过立马反映过来,中止了!只是损失了一些数据,系统没有受影响!想想都后怕🐶
    eric6699
        71
    eric6699  
       2022-01-21 16:48:44 +08:00
    @weiwenhao 哈哈,用 0 当成没传参数了吧
    neptuno
        72
    neptuno  
       2022-01-21 17:00:19 +08:00
    一般提交这种 sql 需要多叫几个人 check 一下。
    MonkeyJon
        73
    MonkeyJon  
       2022-01-21 17:00:29 +08:00
    线上数据库除了查询操作,其他都需要发公文让领导知道,哪怕是一条 sql ,目前公司政策
    RRRoger
        74
    RRRoger  
       2022-01-21 17:01:58 +08:00
    教训:在做 update/delete 之前 一定要先 select 一下
    wxboy
        75
    wxboy  
       2022-01-21 17:05:24 +08:00
    先写查询 /匹配语句,检查语句没有问题后,再写操作命令(update/delete)
    labulaka521
        76
    labulaka521  
       2022-01-21 17:18:56 +08:00
    update table set delete_time='xxxxx' where (order_id)
    这种语句竟然不报错
    815979670
        77
    815979670  
       2022-01-21 17:21:28 +08:00   ❤️ 1
    我们一般就是先查询有多少条 然后再 update limit 查询条数 ,如果只处理 1 条 就是 limit 1
    chevalier
        78
    chevalier  
       2022-01-21 17:48:07 +08:00
    线上都是先敲好 where 语句,然后再补 update ... set ...
    就怕手抖提交了
    liuxu
        79
    liuxu  
       2022-01-21 17:56:08 +08:00
    领导:问题不大。这小伙子永远不要再碰数据库了。
    ilylx2008
        80
    ilylx2008  
       2022-01-21 18:34:39 +08:00
    程序员的必经过程之一。
    mywind
        81
    mywind  
       2022-01-21 19:55:37 +08:00
    今天一样的经历,好在是测试数据库,binglog 也是 row 。很快就修复了。以后说什么终端打 sql 要加 begin 了。
    retrocode
        82
    retrocode  
       2022-01-21 20:01:09 +08:00 via Android
    妈耶 看到这标题我血压就开始升高了 敏感操作前备份是个好习惯 好歹能回滚下
    documentzhangx66
        83
    documentzhangx66  
       2022-01-21 20:12:06 +08:00
    1.无论是 SQL 、程序代码、甚至在服务器上安装程序,或者在服务器上执行 shell ,请都先在相同的测试环境下,进行测试。执行后,确认业务任然正常,确认压测结论没有太大性能变化,再去服务器上执行。

    而且 SQL 这种执行前,对服务器做个数据备份,还是很有必要的。

    2.这种方案,不仅能避免自己写错导致的问题,甚至连一些软件的 bug ,也能避开一部分。

    3.千万别偷懒,请做好测试,请在正式环境中执行危险操作前做好备份!
    WilliamYang
        84
    WilliamYang  
       2022-01-21 21:36:37 +08:00
    @weiwenhao gorm 这个特性,害了很多公司,很多人
    viator42
        85
    viator42  
       2022-01-21 21:47:08 +08:00 via Android
    以前我也办过这种事,干活的时候没看清把公司 OA 生产环境的数据库清空了。突然嗷的一嗓子整层楼乱成一团,我赶紧把昨天的备份导进去才安静下来
    AlexaZhou
        86
    AlexaZhou  
       2022-01-21 22:10:06 +08:00
    手动执行 update 是比较危险,最好 begin transaction ,然后 update 再 commit ;
    为了保险起见,我还有个习惯是先敲 where 条件, 再退回来敲 set xx=xxx
    ajaxfunction
        87
    ajaxfunction  
       2022-01-22 01:02:24 +08:00
    这种事情都会经历的,不经历记不住,就看影响大小了。
    当年我在小公司做的项目数据库都没备份的,直到有一次 本以为在操作测试环境, 结果操作了生产环境,把所有人昵称都改成统一的了,反正就是头皮发麻,现在那种感觉现在都记得,估计当时高血压了。
    后来才养成了习惯 每个项目无论用哪种手段每天 必须备份数据库,虽然后来一次也没用的上。
    rookien
        88
    rookien  
       2022-01-22 11:33:30 +08:00
    想起来我前年入职第一家公司的时候,也是忘了加 where ,当时心里是真的慌得一 p 啊,只能说还好是测试环境
    UN2758
        89
    UN2758  
       2022-01-22 19:17:05 +08:00   ❤️ 1
    @lwldcr #8 同病相怜啊,我也是写的修数据脚本有 bug ,在生产环境上跑,结果把数据全清掉了,害得 cto 陪我一起修数据修到 11 点
    qyvlik
        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
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   951 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 21:05 · PVG 05:05 · LAX 14:05 · JFK 17:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.