打破WAL
嗨,我又是卡尔。你可能记得我,是教克劳德使用Antithesis的那个人。今年早些时候,SQLite发布了3.51.3版本,修复了其写前日志(WAL)子系统中的一个长期存在的bug,称为WAL重置bug。该bug自2010年以来一直存在,但SQLite团队显然直到今年早些时候才意识到它的存在(关于这一点稍后再说)。他们当时写道:“这个bug是一个具有严格时序约束的数据竞争。它不太可能在常规使用中出现。开发人员从未能够自发地重现这个bug,只能向SQLite添加特殊的测试逻辑,以故意触发bug出现的情况,以验证问题已被修复。” 实际上,我在与女朋友的公路旅行中阅读到这个消息,但我也是个数据库狂热者,所以我立刻被这个事情深深吸引。毕竟,SQLite中的bug是传奇般的少。而且,这听起来就像是一个完美的棕色M&M:一个已知的、具有挑战性的bug,我们可以用Antithesis追踪(我们在POC中做过很多这样的事情)。更重要的是,我最近刚刚发布了我们为克劳德开发的技能。因此,我坐在阳光海岸的山坡上,掏出手机,叫克劳德开始工作。我让它在Antithesis中设置SQL 3.51.2——仍然有bug,然后用一堆Antithesis断言对代码进行了检测。你可以在这里查看仪器化的版本。在这里,我要对我那无与伦比美丽的家省不列颠哥伦比亚省表示致敬。然后,我让它编写一个简单的工作负载,来测试WAL插入和检查点代码。值得注意的是,这是一个完全通用的工作负载。它只是在进行写入和检查点时并发运行——你会期望在生产环境中会频繁发生的事情。断言也是与bug通用的,都是你会添加到任何数据库中的标准断言,比如“没有丢失的已提交写入”和“数据库没有损坏”(在sqlite中称为完整性检查)。在我的第一次运行中,Antithesis在15分钟内捕捉到了此bug。这是报告。你要找的部分是:然后我用相同的工作负载和Antithesis检测,重复了3.51.3的测试。果然,这次运行结果是绿色的。今天我想到了这一点,因为Tailscale刚刚写了一篇出色的博客文章,谈到了他们在2025年经历的上线时间问题。这些问题就是SQLite团队发现WAL重置bug的原因。Tailscale经历了六个月的不稳定上线,然后他们与SQLite团队花了几周的时间寻找bug,推出了修复并滚回了修复,导致另一个问题出现,然后又不得不等待两个月,看看“真正的”修复(3.51.3)是否有效。为了找出问题的根本原因,他们不得不在Tailscale中编写一个新的事务日志记录管道,然后在SQLite的虚拟文件系统层中添加一个新的调试工具。在Antithesis中,这个过程虽然还不是“一键完成”,但一键可以提供因果分析,能够在几分之一秒内定位到问题,并提供确定性的时间旅行调试,让你可以进行假设分析和破坏性分析。正如Tailscale团队所写的:“没有人希望我们花六个月时间寻找SQLite中的bug。这对我们的客户和员工来说都是一次极其令人沮丧的经历。”找到像WAL重置bug这样的bug是极其困难的(或许就像在破碎的玻璃上爬行一样)——但对于这些罕见而困难的bug,真正的折磨是你在等待看看你的修复是否真的有效。我处理过足够多的数据库,也亲身经历过很多次这种情况。因此,意识到这个bug在实际情况下是多么痛苦,真是让人清醒又振奋。通过赋予代理使用Antithesis的技能,我在一个小时内就找到了并验证了这个bug,从我坐在阳光下的云杉树下的手机上完成。我知道我们的代理技能有效,但我不知道它们能如此有效。如果你有麻烦的数据库问题,给我打电话。
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡