两周前,我们将数据库从托管在Web服务器上的postgres实例迁移到托管在Amazon RDS上的mysql实例。
迁移后,我们开始在大约0.5%的请求中遇到“查询期间丢失连接”错误,导致Web请求失败。在迁移之前(当我们使用Postgres时),我们之前从未见过这个问题。
有很多关于mysql以及其他社区在线的“查询时丢失连接”错误的文档。这个问题在dev或staging中是不可重现的,只有生产。该问题在生产中相对较少发生,但在ActiveAdmin中遇到一个在一个页面上运行大量查询(管理仪表板)的相当复杂的页面时,似乎更频繁地发生。
以下是迄今为止我尝试过的事情清单无效:
1)'wait_timeout'变量 - 这似乎不适用,因为它与8小时后死亡的连接池连接无关。我可以重新启动数据库和rails应用程序,并通过点击活动的管理仪表板页面在50个请求中重现该问题。也就是说,我增加了mysql上的wait_timeout并重新启动了Amazon RDS实例无济于事。
2)database.yml中的'reconnect = true'。我怀疑这有助于掩盖问题,因为Aborted_clients有时会在rails前端没有相应的故障而增长,我假设因为连接池在某些情况下重试故障连接并正常恢复。
3)禁用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社区关于下一步尝试的想法?