一名初级开发人员、一名中级开发人员和一名高级开发人员走进酒吧

2025-06-04

一名初级开发人员、一名中级开发人员和一名高级开发人员走进酒吧

大家围坐在一起,让我给你们讲述一下我和我的队友关闭该平台最重要的服务之一的情况。

为了叙述的方便,我将我的同事命名为 S(高级)和 M(中间),尽管我更改了日期和一些技术细节,以尽可能保持匿名。


七月底一个美好的星期四下午。天气比前几天温和得多,我和队友们刚刚搬进了办公室的新地方。

生活大部分时间都很美好。

前一周,我们最资深的开发人员虽然没有出席S,但M我和我们自己还是设法完成了一些任务。

我们引入的更改包含一些相当重要的内容(新的数据库字段、新的端点),因此我们决定等待 S 的审核后再合并它们。

数据库变更和迁移

与此同时,另一位开发人员审核了我们的变更,并指出迁移脚本中的操作可能会给数据库服务器带来很大的负担,并可能导致其暂时处于锁定状态。因此,他提出了一些替代方案。

如果您不知道数据库迁移是什么,它其实是一系列 SQL 脚本,这些脚本按顺序执行时会从头创建整个数据库架构(包括表、列、默认值、约束等)。通常,它们会在每次部署时运行,但前提是需要应用新的内容——也就是说,需要运行一个从未运行过的新迁移脚本。

我们不想将我们的变更作为迁移来运行,因为这样它将由我们的持续集成系统执行,如果出现问题,我们将完全无法控制。

我们必须手动运行它。

因此,我们坐下来,使用生产数据库的副本,开始尝试查询,试图找到最有效的替代方案。

这真是一段有趣的时光,我们三个人试着猜测一下,当我们分别运行每行脚本时会发生什么。它会花很长时间吗?还是会立即运行?为什么?我们应该在哪里设置默认值,以防止新条目破坏它?

表演时间!👯‍♀️

现在是下午5点,我们终于对查询感到满意了。它按正确的顺序执行了所有操作,并没有卡死太久。我们给基础设施团队发了一张工单,要求直接在我们的服务器上运行它,因为我们显然没有这方面的凭证。你马上就会明白为什么。

Infra在这方面确实很尽心尽力。我们知道他们很忙,处理事情需要一些时间也没关系。但这次不行,哦不,这次我还没来得及眨眼,工单就被关闭了。

一切似乎都还好。一天快要结束了,我们各自回到各自的办公桌前,完成了一些任务。

几分钟后,另一个团队的成员过来问我,是否要修改这个功能,因为它报了一些错误。这对我来说就像一个冰桶挑战:

哦不,我的意思是,是的......我们搞砸了。

你能猜到发生了什么吗?我知道找出遗漏比找出错误更难,但我认为即使你不了解具体的服务、功能或查询,也能知道我们需要做什么(以及没做什么)。

如果你这样做了,请滚动到底部并发表评论,我相信你不会偷看这张照片下面👇

_胡卓亨在 Unsplash 上拍摄_

好吧,如果你不知道会发生什么,也没关系。我觉得我应该知道,因为这种情况在开发过程中本地发生过无数次。而且那天我自己也启动了一个非常类似的功能,也遇到了同样的错误。

准备好了吗?

现实很残酷

我们在数据库中添加了该列,但从未合并处理这些新数据的代码。这导致应用程序不知道如何处理这些字段,并在所有 GET 请求中抛出错误😱

现在,在某些语言中可能不会发生这种情况,它们可能会丢弃多余的、未解析的数据并继续处理。我不应该透露更多关于这方面的信息,但我要说的是,我们使用的技术对数据库的“流氓列”处理得不那么严密,它要求你告诉它如何处理收到的所有数据。

不过,没有合并新字段的代码并不是问题所在。接下来,我们的小恶魔登场了:来见见*😈邪恶的回声笑声

瞧,我们所有的检索查询都使用了星号*(也称为星号),这意味着结果将包含表格中的所有字段。那天我意识到这是一个非常非常糟糕的主意。

如果我们当时有一个要检索的字段列表,*就不会发生任何糟糕的事情了。但我们没有。我们三个人都知道这一点。只是我们忘记了而已😰

真正的问题🤦🏻‍♀️

好吧,但我们是人,对吧?我们会犯错。没有人能把公司里所有的代码库都记在工作记忆里。这就是我们进行测试的原因。不是因为我们的代码脆弱易错,而是因为我们的思维。正是我们的思维创造了代码。

所以问题其实不在于我们把它弄坏了,而在于警报没有响。

我们进行了生产测试,但他们没有通知任何人。日志中记录了错误警报,但他们没有监控导致最多错误的环节。我们进行了端到端测试,但它们被禁用并被标记为“损坏”。这才是真正令人无法接受的。

结语📜

但最终,这对我来说是一个难得的学习机会:你永远不会像在搞砸事情时那样努力学习。这是一个你永远不会忘记的教训。

所以,对于你们这些孩子来说,这是我那天学到的东西的清单:

  • 永远,我的意思是永远不要在代码的查询中使用 *。即使你必须写一百个列名,最好也这样做。
  • 害怕数据库的变化,恐惧可能会引导你变得谨慎。
  • 迁移应该与部署分离,以便更好地控制它们。
  • 当您引入数据库更改时,请确保所有代码都已到位,并且可以处理以前的数据库状态以及更改后的数据库状态。
  • 对关键功能在生产环境中进行快乐路径测试,以便正常运行并通知合适的人员。
  • 一旦受到影响,就测试数据库更改,并在几分钟后监控日志(取决于您获得的流量)。
  • 睡觉前一定要刷牙😬

免责声明⚠️

这是一个由经验不足、知识匮乏的人物讲述的故事。如果您有任何意见,可以补充或纠正我的说法,我非常乐意阅读,但请保持礼貌。🙂


致谢

封面照片由Sebastian FröhlichUnsplash
上拍摄照片由胡卓亨Unsplash上拍摄

感谢Nicolas Grenié(又名 @picsoung)Eva Casado de Amezua 的评论和贡献。
本文最初发表于HackerNoon。

文章来源:https://dev.to/anabella/a-junior-a-mid-and-a-senior-dev-walk-into-a-bar-414f
PREV
我使用 CSS Flexbox 创建了 Red Onion 的《预言家日报》副本
NEXT
了解基本编码术语:行业基础知识✏️