两周前,我们将数据库从托管在 Web 服务器上的 postgres 实例迁移到托管在 Amazon RDS 上的 mysql 实例。
迁移后,大约 0.5% 的请求开始出现“查询期间丢失连接”错误,导致 Web 请求失败。在迁移之前(当我们在 Postgres 上时),我们以前从未见过这个问题。
mysql 以及其他在线社区有很多关于“查询期间丢失连接”错误的文档。该问题在开发或登台中不可重现,只能在生产中重现。该问题在生产中相对很少发生,但在 ActiveAdmin 中访问一个相当复杂的页面时似乎更频繁地发生,该页面在一个页面上运行多个查询(管理仪表板)。
这是我迄今为止尝试过的事情的列表,但无济于事:
1) 'wait_timeout' 变量 - 这似乎不适用,因为它与连接池连接在 8 小时后死亡无关。我可以通过点击活动的管理仪表板页面重新启动数据库和 Rails 应用程序并在 50 个请求内重现该问题。也就是说,我增加了 mysql 上的 wait_timeout 并重新启动了 Amazon RDS 实例,但无济于事。
2) database.yml 中的'reconnect = true'。我怀疑这有助于掩盖问题,因为 Aborted_clients 有时会增长,而 Rails 前端没有相应的故障,我认为是因为连接池在某些情况下会在失败时重试连接并正常恢复。
3) disabled delayed_job - 认为延迟的工作可能会破坏条目,我将其禁用并再次重现该问题。
4) 将 Amazon RDS 实例从小型升级到中型 - 数据库负载非常轻,但我认为这可能是一个因素,所以我将 Amazon RDS 实例从“小型”升级到“中型”,但没有成功。
5) 简化仪表板页面上的查询使该页面不太可能重现错误,但并没有完全消除错误。
6)在发生错误的情况下,错误会立即发生 - 而不是在 3-5 秒后发生,这让我相信这不是读/写/连接超时。
7) 重启 EC2 Web 服务器没有帮助
8) 重启 Amazon RDS 数据库实例没有帮助
9) Web 服务器和 Amazon RDS 实例均未承受任何重大负载
10) Web 服务器和 RDS 数据库实例都在同一个可用区
我觉得 Rails 中的连接池条目可能会因先前的查询而处于不良状态,导致该连接的下一次尝试立即失败,但无法证明这一点。
我还看到 Rails 4.0 有一个新的 Reaper 概念,它似乎会定期检查池条目是否存在死连接——这让我认为这可能是他们现在在 Rails 4.0 中修复的一个更广泛的问题。
因为此时这只能在我们的生产环境中重现,所以我无法将 mysql 实例从 RDS 移至 Web 服务器以将其隔离为 RDS(远程数据库实例)。
Stack Overflow 社区对接下来要尝试什么的想法?