百万分之一漏洞的对立面:驯服恶魔般的不确定性

这篇文章主要讨论了在像 CockroachDB 这样的分布式系统中出现的“百万分之一”级别的 bug,以及用于调试和重现此类 bug 的工具和方法,包括ptracerr、Antithesis 等。

背景:非确定性

  • 非确定性在计算机科学中用于管理状态空间的复杂性,最早出现在[Chomsky, 1959]和[Rabin and Scott, 1959]中,如简洁的上下文无关文法和非确定性有限自动机。
  • 在软件验证中,非确定性允许在无法进行详尽状态枚举的情况下使用符号模型检查等技术,但也会导致分布式系统难以调试,这种类型的非确定性被称为“恶魔般的”。

确定性调试的思路

  • 确定性调试的想法并不新鲜,目标是重现相同的失败和根本原因,但在实践中很难实现。
  • 对于像 CockroachDB 这样的有状态分布式系统,非确定性的来源很多,如网络延迟、线程定时、磁盘故障等,导致难以可靠地重现、诊断和修复 bug。
  • ptrace是一个系统调用,可以拦截和修改系统调用的结果,用于确定性调试,但会带来显著的开销。

Antithesis 平台

  • Antithesis 平台受 FoundationDB 启发,使用确定性虚拟机实现确定性模拟测试,能够模拟网络和磁盘 I/O 以及注入故障。
  • 它不仅是一个确定性模拟器,还使用模糊测试来寻找“有趣”的场景,并通过代码覆盖工具为模糊测试提供指导。
  • Antithesis 平台通过监控进程失败和日志错误来捕获错误,运行许多短实验来探索代码的不同分支。

“百万分之一”bug 的调查与修复

  • 2021 年出现的“百万分之一”bug 未被客户报告,仅由 Sentry 的崩溃报告模块自动提交。
  • 经过调查和分析,发现该 bug 与并行提交协议中的事务恢复机制和竞争条件有关,具体是由于网络故障导致事务协调器与事务的正确状态不同步,以及 RPC 失败引起的模糊状态。
  • 修复方法是明确跟踪可能的非幂等重放,当重放失败时,事务协调器向 SQL 客户端返回“结果模糊”错误,将非幂等事务重放的负担转移到 SQL 客户端。

结论

  • 分布式系统中的 bug 很难发现和修复,需要新的测试和调试方法。
  • Antithesis 平台虽然有一些不足之处,如不支持回放时的单步调试,但仍有潜力消除难以检测的隐藏 bug,确定性调试是未来的发展方向。

附录:根本原因鸟瞰

  • 该 bug 的关键是一个“模糊写入”,由于网络故障导致事务协调器不知道写入是否成功,随后的事务恢复过程引发了竞争条件,导致事务协调器出现异常。
  • 深入研究 CockroachDB 的并行提交协议,包括事务恢复机制和竞争条件,解释了导致 bug 的原因。
  • 固定幂等性的方法是在事务协调器处于模糊状态时,返回“SQL 错误 40003 statement_completion_unknown”,让客户端决定如何处理 RPC 失败。
阅读 30
0 条评论