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

操作数据库 update 忘了加 where

  •  2
     
  •   moonchild · 310 天前 via iPhone · 8754 次点击
    这是一个创建于 310 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    db.Where(User{})
    weiwenhao
        27
    weiwenhao  
       310 天前
    几年前遇到的
    golang 的 gorm

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

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

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

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

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

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

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

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

    3.千万别偷懒,请做好测试,请在正式环境中执行危险操作前做好备份!
    WilliamYang
        84
    WilliamYang  
       310 天前
    @weiwenhao gorm 这个特性,害了很多公司,很多人
    viator42
        85
    viator42  
       310 天前 via Android
    以前我也办过这种事,干活的时候没看清把公司 OA 生产环境的数据库清空了。突然嗷的一嗓子整层楼乱成一团,我赶紧把昨天的备份导进去才安静下来
    AlexaZhou
        86
    AlexaZhou  
       310 天前
    手动执行 update 是比较危险,最好 begin transaction ,然后 update 再 commit ;
    为了保险起见,我还有个习惯是先敲 where 条件, 再退回来敲 set xx=xxx
    ajaxfunction
        87
    ajaxfunction  
       310 天前
    这种事情都会经历的,不经历记不住,就看影响大小了。
    当年我在小公司做的项目数据库都没备份的,直到有一次 本以为在操作测试环境, 结果操作了生产环境,把所有人昵称都改成统一的了,反正就是头皮发麻,现在那种感觉现在都记得,估计当时高血压了。
    后来才养成了习惯 每个项目无论用哪种手段每天 必须备份数据库,虽然后来一次也没用的上。
    rookien
        88
    rookien  
       309 天前
    想起来我前年入职第一家公司的时候,也是忘了加 where ,当时心里是真的慌得一 p 啊,只能说还好是测试环境
    UN2758
        89
    UN2758  
       309 天前   ❤️ 1
    @lwldcr #8 同病相怜啊,我也是写的修数据脚本有 bug ,在生产环境上跑,结果把数据全清掉了,害得 cto 陪我一起修数据修到 11 点
    qyvlik
        90
    qyvlik  
       291 天前
    上线 SQL 用 https://github.com/hhyo/Archery ,这个工具使用 goinception 做 SQL 的执行和备份,可以检查不安全的语句,以及执行 SQL 后回滚的 SQL 都会给你自动生成。

    archery 的同类品还有如下:
    https://github.com/jly8866/archer
    https://github.com/cookieY/Yearning
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1163 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 65ms · UTC 19:40 · PVG 03:40 · LAX 11:40 · JFK 14:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.