我如何解决了一个罕见的 MySQL 缓存 Bug

调参侠小美 初级 58分钟前 127 浏览 3 点赞 约 3 分钟

Hyperdrive 对 MySQL 的支持现已正式发布。Hyperdrive 是 Cloudflare 为 Workers 提供的数据库连接池器,最初仅支持 Postgres。自去年我们宣布 MySQL 协议支持 Beta 版以来,我们一直在努力使 MySQL 的处理方式与 Postgres 的支持一样可靠。
在开发和运行 MySQL 连接池器于 Cloudflare 网络上的过程中,我们学到了一些东西。事实证明,从 Beta 到正式发布之间,只是一个披着外衣的 20 个 Bug 修复。
在 Beta 版期间,我们的目标是验证真实世界客户的使用是否达到了我们生产环境的可用性目标 99.99%。我们知道我们的可靠性存在差距,因为我们跟踪了来自 Worker 的客户端连接以 Hyperdrive 结束错误的情况。此外,我们还收到了 Beta 版客户的反馈,这导致了在生产环境中发现了一个罕见且微妙的 Bug。为了传达这个特定 Bug 的复杂性,我们首先需要解释 Hyperdrive 的工作原理。
什么是 Hyperdrive?
Hyperdrive 是一个分布式数据库连接池器,它将 Cloudflare Workers 连接到 SQL 数据库。Hyperdrive 在我们的全球网络上保持温暖的 SQL 连接开放,并将这些连接共享给许多 Worker 请求。除了连接池,Hyperdrive 还可以在我们的全球 CDN 缓存中缓存常见查询,从而减少延迟和源数据库的负载。
连接到 SQL 数据库是昂贵的,至少需要五个网络往返。在像 Workers 这样的无服务器计算平台上,为每个请求建立连接是不切实际的,不仅因为每个请求增加了大量延迟,而且因为大量打开的连接会产生高每连接资源成本。虽然 MySQL 在这方面比 Postgres 更好,因为 MySQL 不使用每个连接一个完整的 OS 进程,但典型部署在大量连接的情况下仍然可能会遇到资源问题。
有关更多详细信息,请参阅我们的博客文章介绍 Hyperdrive。
稳定性的旅程
我们遇到的一些问题一旦报告就很容易修复。Beta 版期间报告的第一个问题是写入数据库的表情符号没有被正确返回。这是一个与字符集编码相关的 Bug。Hyperdrive 在启动握手中协商连接的编码,我们协商 utf8 作为编码。事实证明,utf8 是 utf8mb3 的一个过时别名,它不是全部的 UTF-8:它只支持 1-3 字节每个 Unicode 代码点,而完整的 UTF-8 最多支持 4 字节每个代码点。为了获得全部的 UTF-8,我们需要将握手更改为使用 utf8mb4,这解决了表情符号问题。
当我们添加通过 COM_RESET_CONNECTION 进行连接清理时,发生了另一个与编码相关的 Bug。这是一个轻量级的 MySQL 命令,用于清除给定连接中的任何会话状态,这正是 Hyperdrive 需要确保在借用之间不会泄露任何会话级状态。但是,添加这个连接清理步骤再次导致了编码问题!事实证明,COM_RESET_CONNECTION 并不会将连接状态重置为我们连接启动时协商的字符集编码;相反,它会将连接重置为服务器默认值。这意味着在默认为 latin1 的 MySQL 服务器实例上协商 utf8mb4 后,一旦我们运行 COM_RESET_CONNECTION,我们的连接现在具有 latin1 编码。修复方法是在每次连接重置后始终运行一个命令将编码设置为 utf8mb4。
一个难以找到的 Bug
在 Beta 版期间,我们最高流量的 MySQL 客户报告了少量但一致的空查询响应,而这些查询总是预期会有非空响应。我们通过检查所有遥测数据并理解用户的逻辑开始了调查。然后我们还增加了这个 Hyperdrive 实例的跟踪率,希望能看到执行
这些条件同时成立时,下一步会通过检查所有遥测数据并理解用户的逻辑来调查,或者通过增加跟踪率来查看执行情况。

我如何解决了一个罕见的 MySQL 缓存 Bug
求助

全部回复 (0)

想当场把话说完?进全球 AI 聊天室,登录就能开口。

还没有回复,来发第一条吧!

发表回复

支持 Markdown 格式