这本是一个安静的星期六。
我收到了支持团队的一条消息,说我们一个客户遇到了问题。我认为这个问题很重要,值得开始调试。15 分钟后,我明白了问题所在 - 在数据库中有一些损坏的订单需要删除。
听起来小菜一碟。
如果你不给创业公司打工,请不要嘲笑我
有几百个订单需要删除,所以我决定不手动操作,而是编写一个简单的 SQL 查询语句(警告 )
实际上比这复杂一些,但这里简化一下:
UPDATE orders
SET is_deleted = true
WHERE id in (1, 2, 3)
你大概已经猜到这场灾难的规模了…
我按下了 CTRL + Enter 并运行了命令。当它花费超过一秒钟时,我明白发生了什么。我的客户端 DBeaver 看到空的第三行,并忽略了第四行。
是的,我删除了数据库中所有的订单
我整个人都不好了。
深吸一口气后,我知道我必须快速行动起来。不能犯更多错误浪费时间了。
恢复工作做得很好。
*我决定不还原整个数据库,因为无法停止所有系统,因为我们有多个独立的系统。我不想在恢复过程中丢失所做的更改。我们用 GCP 提供的托管 PostgreSQL,所以我从更新之前创建了一个新的克隆。然后,我只导出了克隆中的 id
和 is_deleted
列,并将结果导入到生产数据库中。之后,就是简单的 update + select 语句。
所以显然本可以很容易避免这 45 分钟的停机时间…
这可能听起来像是一个你永远不会犯的愚蠢错误(甚至在大公司中,根本不能犯)。确实。问题不在于错误的 SQL 语句。**一个小小的人为失误从来都不是真正的问题。**我运行那个命令只是整个失败链条的终点。
错误一层层叠加,其中任何一个被避免了 - 整件事就不会发生。大多数问题答案都很简单:我太自信了。
不过还好通过有章法的恢复程序,阻止了连锁反应。想象一下如果无法将数据库恢复到正确状态会发生什么灾难……
几个月前,我阅读了「切尔诺贝利:一部悲剧史」。那里发生的一系列错误使我想起了那个被诅咒的周末(并不是要低估或与切尔诺贝利灾难相比较)。
谁应该负责?
反应堆设计师?其他电厂团队未能传达他们遇到的问题?切尔诺贝利团队?苏联政府?
所有人都有责任。灾难从来不是由单一错误引起的,而是由一连串错误造成的。我们的工作就是尽早打断这条链条,并做到最好。
我对周一与老板的谈话本没有什么期待。
但他让我惊讶:「确保不再发生这种情况。但是我更喜欢这样 - 你犯了错误是因为你专注并且喜欢快速行动。做得越多,砸得越多。」
那正是我需要听到的。如果以过于「亲切」的方式说:没关系,别担心,谢谢你修复它!我反而会感觉虚伪。另一方面,我已经感觉很糟糕了,所以没有必要进一步吐槽我。
从那时起:
事发后,我和团队详细分享了过程,没有隐瞒任何事情,也没有淡化我的过错。
在责备他人和不追究责任之间有一个微妙的平衡。当你犯错误时,这是一个传递正确信息的好机会。
如果你道歉 1000 次,他们会认为你期望当事情发生在他们身上时,他们也需要给出同样的回应。
如果你一笑了之,并忽视其影响,他们会认为这是可以接受的。
如果你承担责任、学习并改进自己 - 他们也会以同样的方式行事。
顺便说一句,如果团队采用了 Bytebase 的话,这个事故是大概率可以被避免的,因为 Bytebase 有好几道防线:
更多资讯,请关注 Bytebase 公号:Bytebase