最近看到这篇文章 《小伙伴们手滑集》,觉得感慨很多,强烈推荐大家阅读。比如这样的例子:
UPDATE 没有 WHERE 条件
而我则经历过 delete 没有写 where 条件的惨剧,这个惨剧是某些 case 下面代码调用触发的,不是手动执行 SQL 发生的。
还有臭名昭著的,我没有经历过,但是我有不止一个同事干过这样的事情:
rm -rf
都只是手稍稍地温柔地 “滑了一下” 而已嘛……
这些事情我觉得一下子很亲切,似乎全世界的软件工程师都是如此得同一。
出的事故多了以后,变得战战兢兢,如履薄冰,尤其是回车键这样的敲击,似乎总是带着颤抖落指。
还有这篇文章 《让自家系统瘫痪,这事我也干过》,讲了一个关于使用 truncate 语句清空数据库数据的故事。及时报告老大,但是领导给了这样一个反馈:
赶紧恢复数据,最迟明天早上必须要解决,不要让用户感觉到。
其实这样的话是非常给程序员压力的,我可以想象当时那种场景。线上数据丢失是如何惊心动魄。
作者给了这位老大一个很高的评价,但是我不这么认为。这件事情最终大事化小、小事化了的做法是很不错的,但是给出时间点压力这样的事情其实对当时火烧眉毛的情况解决并没有帮助。
谁都会有手滑的时候,我最大的感受是,在 “线上系统维护” 这样的事情上,“人” 远没有 “机器” 可靠。
造成的恶劣后果多半为 “服务停止” 或者 “数据丢失” 两种,尤其是后者,有时难以挽回,损失惨重。
我经历过的 “手滑” 惨剧也有一些,当然没有那么恐怖。
- 比如在杀 Hadoop job 的时候,有一个重要的线上 job 还在跑,被我杀掉了,当时吓了一跳,赶紧找熟悉这些 job 的 oncall 来看,还好这个 job 是幂等的,重跑就行了。如果运气不好,干掉一些特殊的 job,结果或许就糟糕了。前年年底就有一个组内 job 的问题因为维护的工程师的操作触发了 sev 1(最高级别)的线上问题。
- 再比如我曾经有过 “手滑” 把一个造成服务不可访问的问题留到版本中发布出去了,结果测试同学们也没法发现该问题,最后导致线上服务无法使用,被迫连夜赶补丁打上去。
- 再再比如有不止一次,想把线上 log 之类的文件给删掉,但是手滑,删错了目录,把一些线上重要数据或者服务文件夹给干掉了……
看那些 manager 们,还有公司们对工程师们操作线上数据和服务手滑以后的严重后果,基本上有这样几种反应,后三种我都见过,第一种有同事经历过:
- 当即批评,事后追责。这时最差的公司和领导。
- 对外道歉平息风波,对内查清问题追究操作人员责任,绩效差评。这是中庸的公司和领导。
- 对外冷处理,对内以鼓励为主,但是评估问题根因和改进。这种做法就好得多了。
- 内外一致,详细分析问题,包括连续问几个 why,问题责任主体只定位到团队,不追究个人。这个做法也不错。
我想对于这样的问题,有一个原则就是,我相信责任主体工程师早就懊悔万分了,再责怪他,对解决问题只能起到反面的效果。
没有手滑的人生,是不完整的。
没有手滑经历的程序员,是不成熟的。
我相信关于这样的问题发生之后的后续改进,不同人会有不同的看法,我先说一说那些最不靠谱的办法:
- 公开批评和个人责任落实。事实上绝大多数情况下,犯错的同学已经心有余悸,良心惴惴不安了。更大的批评砸头上只能带来消极的结果。最消极的结果就是减少工作产出,正所谓,“不做不错”,不让我犯错,我不干活就是了。
- 把问题的检查写到文档,比如 checklist 里面去,等到类似场景的时候拿着 checklist 排查。这也是一种比较不好的做法,也许会好过什么都不做,但是:(1)这样的问题要确保足够的可重复性,否则只会导致这个 checklist 越来越复杂,直到最后根本无法实行;(2)这始终是个笨办法,工程师被条条框框牵着鼻子走只会让工作氛围和积极性越来越差。
- 强化 “人” 的管理和监督流程,这也是一个好不到哪去的办法,比如对线上操作需要得到领导审批,最大的问题在于这会大大降低效率,降低工作热情。而这样的效率降低,很多职位高的人却看不到。
反过来,也有好的实践,大多数实践都能够做到,规避了问题,并且在 “不知不觉”,或者是没有明显代价的情况下实现的。
比如说,Linux 下,建立和使用不同权限用户的习惯,可以很大程度上避免手滑删文件悲剧的发生。
当然,这在有些情况下只是理想状态,多数团队都要做好足够充分的备份和容错,毕竟手滑难以避免,来势凶猛,如何脱身和保全数据并不容易。
今天的行文风格有点奇怪,啰嗦倒是依旧,只是文字如此稀疏。
最后,我想说,我写这些文字的初衷,仅仅是发发感慨,这样的事情看起来如此之亲切。
尤其是意识到手滑的那一刻,身后那凉飕飕的感觉,肌肉抽搐,浑身颤抖,如鬼抚背,难以忘记……
呃,还是说多了。
文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》
update/delete 没有 where 是 sql 的设计缺陷。有些数据库系统设置成默认不允许没有 where 子句,才是正解。
评论里的 if (…); 用 coding style 检查即可解决。
其实大部分的手滑都是可以通过技术手段减少发生可能的。不过许多所谓管理者往往只会用非技术的蠢办法。
看了你的文,我乐死了。从你在 ITEYE“ 一些中文编程语言” 的文章跑过来的。
我手滑了一下 过来看看
以前手底下有个程序员 if (…) { … … } 结果在 .) {中间写了个; 结果就成了 if (…); { … … } 然后死活两天都不知道为啥 if 语句没效果