V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
kankana
V2EX  ›  程序员

程序犯了好些小错误,出事了,现在坐立不安

  •  
  •   kankana · 2015-02-13 20:59:36 +08:00 · 7085 次点击
    这是一个创建于 3606 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有个feature是要求用户suspended 30天后,将此用户的所有数据给删掉. 30天内是可以恢复的。

    我直接队列,将该任务延迟到一个月后。

    现在才发现用户提前被删除了。

    原来,延迟参数,我传递的是30*24*60, 实际上,时间单位是秒。。。

    现在用户要恢复,结果数据全没了。。。

    很对不起老板。。。搞砸了。。。


    lessons learned:

    1, 加强测试。

    2, 定时备份数据库。

    55 条回复    2015-02-16 03:14:13 +08:00
    sumhat
        1
    sumhat  
       2015-02-13 21:03:23 +08:00 via Android
    其实标记成已删即可,不用真的删掉的
    weisoo
        2
    weisoo  
       2015-02-13 21:08:20 +08:00
    楼上正解,我们老板不会看数据库,老板要求删除东西,我都是打个标记,不是真的删除
    chinafeng
        3
    chinafeng  
       2015-02-13 21:08:31 +08:00
    老板没有怪你或者做出相应的处罚措施?

    人无完人,谁能保证不出Bug,谁敢说自己程序Perfect

    尽到自己能力做到最好即可
    lsmgeb89
        4
    lsmgeb89  
       2015-02-13 21:10:56 +08:00
    单位是秒,相当悲剧。。。
    blacktulip
        5
    blacktulip  
       2015-02-13 21:15:01 +08:00
    if suspended_time < 1.month.ago
    shiny
        6
    shiny  
       2015-02-13 21:16:01 +08:00
    没有单元测试?
    kankana
        7
    kankana  
    OP
       2015-02-13 21:17:00 +08:00
    @chinafeng

    每当我犯错了,我向他表达我的歉意。他总是这样回复我

    I knew there would be a few hiccups to work through - these are just bumps in the road and we'l get them resolved - its all good.

    像你所说,人无完人。不过,我还是感觉很不好意思。 发个帖子吐口气。
    kankana
        8
    kankana  
    OP
       2015-02-13 21:18:05 +08:00
    @shiny

    队列是外部的库,我直接mock了,判断有接到相关参数就没了。。。。。。。。
    roychan
        9
    roychan  
       2015-02-13 21:18:28 +08:00
    加油,马上就要过年了
    br00k
        10
    br00k  
       2015-02-13 21:19:16 +08:00
    多测试吧。做这种我一般都会改系统时间来测试。
    Dongdong36
        11
    Dongdong36  
       2015-02-13 21:37:03 +08:00
    添加标记删除是个好办法。尽量不要直接进行数据删除操作
    Vedar
        12
    Vedar  
       2015-02-13 21:40:09 +08:00   ❤️ 1
    一般不是都是设置失效位 或者将记录移到历史表么。。。
    kankana
        13
    kankana  
    OP
       2015-02-13 21:43:46 +08:00
    @Dongdong36

    你们说的标记删除,应该就是soft delete吧。

    suspend的实现就是soft delete.

    只是,有些敏感数据,是属于我们的,不希望用户退款后,能够再利用到这些数据.

    所以就有了这个30天的决策
    lincanbin
        14
    lincanbin  
       2015-02-13 21:45:39 +08:00   ❤️ 1
    添加个删除时间的时间戳标记,默认为4294967296。
    定时任务运行个脚本,先检测硬盘剩余,剩余不足10%了,再把到了永久删除时间的数据删除。
    ETiV
        15
    ETiV  
       2015-02-13 21:49:39 +08:00
    只是,有些敏感数据,是属于我们的,不希望用户退款后,能够再利用到这些数据.

    那也别删, 移动到别的表里, 然后再删用户用到的那个表~
    abelyao
        16
    abelyao  
       2015-02-13 21:54:54 +08:00
    正式运行的项目,99% 的情况都不能物理删,这个不是什么退款不退款、敏感不敏感到问题
    hst001
        17
    hst001  
       2015-02-13 21:55:54 +08:00
    数据库里面的数据,无论出于什么需求,都是不会真正删除的
    gamexg
        18
    gamexg  
       2015-02-13 21:56:19 +08:00   ❤️ 2
    >>我直接队列,将该任务延迟到一个月后。

    仔细检查下逻辑,别用户30天内恢复了,队列里面还有,到时候数据又空了...
    Dongdong36
        19
    Dongdong36  
       2015-02-13 21:59:09 +08:00
    标记删除应该是比如一个用户,他的一个字段表示他的状态,0 - 正常,1 - 封禁,2 - 删除
    在程序处理时根据这个字段的状态判断这个用户是否存在,如果标记为2,则表示用户已经被删除,不提供给前端数据,但是数据库中是存在的,如果信息比较多,实在磁盘空间没有了,那么用脚本跑一遍,删除即可,这样出错的概率还是蛮小的
    kankana
        20
    kankana  
    OP
       2015-02-13 22:38:48 +08:00
    我没接触过复杂的项目. 所以,非常感谢各位的经验和建议.

    当前方案:

    1, 删除时, 再加了一条验证是否超过30天. 之前就是验证状态是否suspended

    2, 只删除属于我们的数据.用户的其他数据保留.

    接下来, 我会再研究下,最好做到不删除数据. 因为需要与其他平台的一些协作, 一时半会也搞不定.
    evlos
        21
    evlos  
       2015-02-13 22:54:39 +08:00 via iPhone
    >> 只是,有些敏感数据,是属于我们的,不希望用户退款后,能够再利用到这些数据.

    为什么不直接禁止用户访问呢?
    aaronlam
        22
    aaronlam  
       2015-02-13 22:54:58 +08:00 via iPad
    过个好年,有错就改
    873681136
        23
    873681136  
       2015-02-13 22:56:05 +08:00 via Android
    我自己也在维护一个OJ,我的做法是添加一个锁定字段,删除操作并不实际删除,而是在锁定字段打个标记,其它数据查询都优先查询非锁定的标记,这样到时恢复数据就好办多了。
    overflow
        24
    overflow  
       2015-02-13 23:01:33 +08:00
    永远不要轻易删除
    chinafeng
        25
    chinafeng  
       2015-02-13 23:02:13 +08:00
    @kankana 如果按照你这种心理,那我觉得我都能天台见了,最高纪录10分钟编译正式生产3次...调整好自己的心态,就算是国家的天河计算机,前几天都还有漏洞能控制大部分超算,更何况这些小产品小公司(相对国家来说,这些应该都算小了吧)
    sb
        26
    sb  
       2015-02-13 23:05:44 +08:00 via Android
    摸摸…学习下各种教训
    zungmou
        27
    zungmou  
       2015-02-13 23:20:26 +08:00 via iPhone
    对于运行的系统,从不去删除数据,只有空间不足时通过数据维护的功能对距离时间最久的数据进行删除。
    Felldeadbird
        28
    Felldeadbird  
       2015-02-13 23:38:20 +08:00
    尽量逻辑删除。免得到时候出问题就麻烦大了。
    surewen
        29
    surewen  
       2015-02-13 23:42:23 +08:00
    在我司,这种错误犯两次就得走人。
    Phariel
        30
    Phariel  
       2015-02-13 23:46:55 +08:00 via Android
    learned => learnt
    kankana
        31
    kankana  
    OP
       2015-02-13 23:59:30 +08:00   ❤️ 1
    @Phariel 欢迎歪楼,欢迎google
    kankana
        32
    kankana  
    OP
       2015-02-14 00:03:12 +08:00
    @chinafeng 标题说"好些",但内容我只写了一个. 唉,太马虎了老实说. 完全没经验. 代码部署前, 生产环境得做调整,完全没考虑到...
    Elethom
        33
    Elethom  
       2015-02-14 00:10:32 +08:00 via iPhone
    想問問 po 主在哪家公司⋯⋯
    realityone
        34
    realityone  
       2015-02-14 00:39:41 +08:00 via iPhone
    我是把记录移到另一个表里,专门记录被标记删除的数据
    juneszh
        35
    juneszh  
       2015-02-14 00:43:55 +08:00
    *个毛线啊 3600 86400 这些“常量”都不记还怎么当程序员的 回去打屁股吧
    kmvan
        36
    kmvan  
       2015-02-14 00:48:40 +08:00 via Android
    楼主是无证编程还是酒后编程?
    palytoxin
        37
    palytoxin  
       2015-02-14 00:52:20 +08:00
    以前公司自己的框架,数据库curd操作都做了封装,所有表都有个is_deleted字段
    服务器的数据不可能也千万不要真的删除。
    老板人挺好,新年加油
    sharpnk
        38
    sharpnk  
       2015-02-14 03:35:28 +08:00   ❤️ 2
    "30*24*60" code review is for shit like this. If senior members of your team failed to spot errors like this during the code review, they should be partially responsible too.
    qw7692336
        39
    qw7692336  
       2015-02-14 03:53:59 +08:00
    @sumhat 或许比较机密的数据,真的要删除
    msg7086
        40
    msg7086  
       2015-02-14 08:16:28 +08:00
    @Phariel
    ‘Learnt’ or ‘learned’?
    These are alternative forms of the past tense and past participle of the verb learn. Both are acceptable, but learned is often used in both British English and American English, while learnt is much more common in British English than in American English. [1]

    [1]: http://www.oxforddictionaries.com/words/learnt-vs-learned

    @kankana
    这就是测试不到位啦。
    每次完成一个功能就要写对应的测试。
    比如写完这个「30天后删除」,就必须要测试它。

    Timecop.travel(29.days.ago) do
    @u = User.new
    @u.suspend
    end
    User.clean_suspended
    expect(User.find(@u).count).to eq(1)

    Timecop.travel(31.days.ago) do
    @u = User.new
    @u.suspend
    end
    User.clean_suspended
    expect(User.find(@u).count).to eq(0)

    另外,如果mysql有做binlog的话,是可以重放还原的。
    simo
        41
    simo  
       2015-02-14 09:08:10 +08:00   ❤️ 1
    这是每个老程序员的必经之路吧,我删掉过所有客户一天的库存,然后一个一个的找客户联系,手动重新上传,还算有的补救。 比我早一年的一个程序员更厉害,把整站数据库删掉过,备份是一个月之前的,这件事儿教训他每天定时备份。我俩现在所有的程序删除都是假删,标记一下。
    这种情况楼上的各位说的很清楚了,基本的意识无非是:定时备份 + 假删
    akstrom
        42
    akstrom  
       2015-02-14 09:26:27 +08:00
    删除数据是一个最不明智的操作..............标记或移动
    lijingyu68
        43
    lijingyu68  
       2015-02-14 10:11:55 +08:00
    今天又学了一招
    dempire
        44
    dempire  
       2015-02-14 10:34:09 +08:00   ❤️ 3
    在老板面前真删除是幼稚的,以老板反复无常的心理,必须留下数据随时等待恢复
    kankana
        45
    kankana  
    OP
       2015-02-14 10:37:18 +08:00
    @juneszh

    这两个常量当然记得. 小时和一天. 当时写这行代码时, 我记得我特地思考了下,"这个延迟参数是分钟为单位的".............

    @sharpnk

    现在,我是直接传了个datetime, Carbon::now()->addMonth(1); 这样应该会好一点了吧?

    一万多行代码的项目,就我一个人...

    @msg7086

    你们ror 测试这么方便啊!!!! 真心羡慕
    qxli
        46
    qxli  
       2015-02-14 10:45:06 +08:00
    加油,我以前也遇到过,不过没这么严重,现在写任何一句代码或任何比较危险的操作都要反复测试验证。
    msg7086
        47
    msg7086  
       2015-02-14 11:58:44 +08:00
    @kankana RoR里测试驱动开发是常态啊,赶紧来把玩Ruby吧 (安利脸
    coderlu
        48
    coderlu  
       2015-02-14 13:46:10 +08:00
    标记删除
    kaneg
        49
    kaneg  
       2015-02-14 18:54:32 +08:00 via iPhone   ❤️ 1
    http://blog.jobbole.com/35922/
    看看这位老兄的“杰作”你就知道自己的过失小巫见大巫了
    angelface
        50
    angelface  
       2015-02-14 21:15:50 +08:00 via iPad
    技术上不说了,前面说的不少了,从你的这份责任心上看应该能成为一个不错的程序员,加油,骚年!
    RaymondYip
        51
    RaymondYip  
       2015-02-14 23:45:25 +08:00
    标记已删除正解
    kankana
        52
    kankana  
    OP
       2015-02-15 00:14:40 +08:00
    @RaymondYip

    如果你仔细看, 就能发现我已经用了soft delete.

    这里跟soft delete没啥大关系, 主要是一些我们的数据比较敏感, 涉及到一些外部平台.

    用户还在的话, 明文给他们, 没关系. 退出的话, 我们得删除这些东西, 并联系外部平台做相应的反应.

    所以, 还真跟soft delete没啥打关系. 当然,也怪我没提供足够信息.

    其实呢, 发个帖子, 主要还是缓解下不安的情绪. 没想到还能学到一些实际运营的经验.

    老板也没说啥, 他也知道我是个有责任心的人, 会吸取教训的.
    9999999999999999
        53
    9999999999999999  
       2015-02-15 01:07:23 +08:00 via Android
    我总是会建一个deleted 的库来备份
    caoyue
        54
    caoyue  
       2015-02-15 09:45:20 +08:00 via iPhone   ❤️ 1
    涉及到物理删除的,还是传时间且没有在参数写明时间单位的,要是我估计得测试加检查好多遍才能安心
    有些语言的文档注释和智能提示也能避免一些问题

    这种错误早犯也好,我就是犯过一次就老实了 :doge:
    jiejieup
        55
    jiejieup  
       2015-02-16 03:14:13 +08:00
    功能没测过你也敢提交?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2739 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 79ms · UTC 09:11 · PVG 17:11 · LAX 01:11 · JFK 04:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.