我们的一个复制主生产服务器表现出了一些非常奇怪的行为,我似乎找不到解决方案。
此服务器上的某些线程卡在“结束”状态。这种情况纯属随机发生,但发生这种情况时,线程始终在表中更新或插入行。运行查询的表不同,但始终位于 MyISAM 表上,并且位于三个不同的表范围内。
当一个线程进入终止状态时,所有其他线程都会卡在锁定状态。当我说所有线程时,我指的是所有线程,甚至包括不查询同一数据库或表的线程。
Web 服务器不断将查询排队到数据库服务器,却得不到响应。这最终导致 Web 服务器耗尽套接字。此时,所有对域的请求都被拒绝。在线程处于“结束”状态期间,数据库服务器没有显示 I/O 或处理器活动。当出现此问题时,我必须手动终止线程。即使这样,除了命令状态更改为“已终止”之外,也没有任何作用。大多数线程在大约 100 秒后消失。
线程在进入最终状态时运行查询的表大小各不相同,但大约为 20 到 100 MB。在出现此问题时,这些表经常更新,但更新方式并不极端。我认为更新频率为每秒 3 到 10 次。
有关服务器的一些规格。操作系统是 CentOS 5.4,带有 MySQL 5.0.77-log。处理器是 AMD Opteron 2378,硬盘是 Corsair X32 32GB SSD 的 RAID 1+0 阵列。
我认为 SSD 可能是导致问题的部分原因,但我找不到任何数据来证实这一点。一段时间以来,驱动器的性能一直很稳定。
我已阅读有关常规线程状态的 MySQL 参考指南中的文档,其中指出在最终状态期间二进制日志和查询缓存会更新。也许这与问题的原因有关?我不知道哪些配置指令可以提供可行的解决方案。
我没有尝试禁用查询缓存,而且由于这是一台正在运行的生产服务器,因此我无法禁用复制。由于这是一台正在运行的生产服务器,因此我在更改查询缓存设置等参数时必须小心谨慎,除非我确信这可以解决问题。
我无法用我的一些测试脚本重现该问题。在读取、写入和更新导致严重问题的表时,不会发生该问题。该问题的发生纯属偶然。
答案1
经过进一步调查,似乎查询缓存导致了这个问题。由于查询缓存太大,MySQL 在清理缓存时似乎会感到困惑。将查询缓存从几 GB 减少到大约 512 MB 解决了这个问题。有关详细信息,请参阅:http://bugs.mysql.com/bug.php?id=39091