在协调世界时 (UTC) 2020年2月20日 21:28,我们收到了 crates.io 用户报告,称他们的 crate 在上传 10 分钟后仍无法在索引中找到。这是 crates.io Web 应用程序的一个 Bug,由 GitHub 中断暴露出来。
根源
在某些极端情况下,将新提交上传到索引 GitHub 仓库的代码即使在推送失败时也会返回成功状态。这个 Bug 导致作业调度器认为上传实际成功,从而将作业从队列中移除并导致数据丢失。
这次中断是由该 Bug 触发的,在同时发生的 GitHub 中断期间收到了意外响应。
解决方案
团队分析了将提交上传到索引的后台作业代码,找到了误报成功的可能原因。一名团队成员编写了修复程序,另一名成员进行了审查,然后我们直接将补丁部署到生产环境。
同时,一旦我们看到索引开始再次更新,我们手动删除了数据库中的损坏条目,并要求报告者重新上传他们的 crates。
受影响的 crates
kaze
0.1.6wasmer-runtime-core
0.14.0wasmer-win-exception-handler
0.14.0
事后分析
部署变更花费的时间比预期长得多:master 分支中已经合并了一些变更,但尚未部署到生产环境,这增加了构建过程的时长和部署的风险。将来,我们应该通过从当前部署的提交创建分支,并在其上挑选热修复程序来部署。我们还应该努力减少 PR 合并到 master 后未立即上线的时间。
没有人因本次事件被呼叫,因为我们的监控和警报系统未能捕捉到问题:我们对作业执行失败有监控,但在本次事件中,作业被错误地标记为正确。我们应该实现周期性检查,确保数据库和索引正确同步。
我们很幸运,两名能够访问支持邮件和生产环境的团队成员在中断期间在线:如果没有可用的呼叫系统,我们可能会比实际情况晚得多才注意到这个问题。
在事件调查期间,我们还发现日志记录不够完善,无法正确诊断问题:当提交推送到索引时没有日志消息,当后台作业执行时也没有。此外,用于发布新 crate 的 API 调用在其日志行中不包含 crate 名称。我们应该增强日志记录能力,以便在未来的事件中快速找到问题的根源。
事件时间线
从事件开始到部署修复程序共耗时 1 小时 31 分钟。
2020-02-20
- 协调世界时 (UTC) 21:17:
kaze
、wasmer-runtime-core
和wasmer-win-exception-handler
的作者在 crates.io 上发布了它们 - 协调世界时 (UTC) 21:28:
wasmer-runtime-core
和wasmer-win-exception-handler
的作者向 help@crates.io 报告了问题 - 协调世界时 (UTC) 21:31:GitHub 更新其状态页面报告中断
- 协调世界时 (UTC) 21:33:Pietro 注意到支持邮件,在 Discord 上通知 Sean,Sean 开始调查
- 协调世界时 (UTC) 21:35:Pietro 回复作者称团队正在调查
- 协调世界时 (UTC) 21:37:Sean 和 Pietro 发现了事件的症状
- 协调世界时 (UTC) 21:50:Sean 找到了 Bug 的可能原因
- 协调世界时 (UTC) 22:01:Sean 手动从数据库中删除了受影响的版本
- 协调世界时 (UTC) 22:09:Sean 开启了包含修复程序的 PR 2207
- 协调世界时 (UTC) 22:16:GitHub 更新其状态页面称问题已修复
- 协调世界时 (UTC) 22:17:Pietro 要求对 PR 进行修改
- 协调世界时 (UTC) 22:20:Sean 在 PR 中处理了 Pietro 的意见
- 协调世界时 (UTC) 22:23:PR 合并,Sean 将其直接部署到 master
- 协调世界时 (UTC) 22:48:修复程序部署到生产环境
2020-02-21
- 协调世界时 (UTC) 09:27:
kaze
的作者向 help@crates.io 报告他们的 crate 受到了影响 - 协调世界时 (UTC) 12:55:Pietro 从数据库中删除了受影响的
kaze
版本,并回复了该 crate 的作者 - 协调世界时 (UTC) 14:10:Pietro 分析了 crates.io 数据库,发现没有其他 crate 受影响