为什么MySQL查询会在“发送数据”状态中堆积?

Modified on: Mon, 19 Aug 2019 02:20:02 +0800

我们使用InnoDB表作为Web应用程序的后端,在几周前我们不得不重新启动MySQL之前,一切都很好。 (我们没有禁用反向DNS查找,即使我们没有真正使用它们,但我们的托管系统突然停止响应这些请求。它们现在已被禁用。)不幸的是,配置文件已经改变了,我们不知道t有一份原始状态的副本进行比较。

在解决了最重要的问题之后,我们留下了一个真正的益智游戏:在高负载下,数据库查询开始花费的时间比平时长得多。在这段时间里,我们的七个apache服务器有几百个打开的连接。运行SHOW PROCESSLIST显示这些连接的一半或多个处于“发送数据”状态,通常是几百秒的时间。几乎所有的查询都是SELECT,类似的查询倾向于聚集在一起。实际上,列表中最低的聚类往往是完全相同的查询(我希望它在查询缓存中),每个返回1104行两个整数。其他常见的违规者是几百个单整数行,几个单整数行或甚至一个COUNT(*)结果的列表。

我们尝试在其中一个时段关闭Web服务器,但问题在重新启动后一分钟内返回。但是,完全重启mysqld解决了问题,直到第二天。问题是什么,我们如何验证和/或修复它?

作者:eswald

最佳答案

这结果是innodb_file_per_tabledefault-storage-engine = innodb,以及创建临时表的频繁访问的页面。每次连接关闭时,它都会丢弃表,从缓冲池LRU中丢弃页面。这会导致服务器暂停一段时间,但从不在实际导致问题的查询上。

更糟糕的是,innodb_file_per_table设置已经在我们的my.cnf文件中徘徊了几个月,之后服务器必须重新启动才出于完全不相关的原因,在此期间我们一直在使用这些临时表没有问题。 (NOC突然取消DNS服务器,导致每个新连接都挂起,因为我们没有启用skip-name-resolve,并且几个小时都不会承认任何事情发生了变化。)

幸运的是,我们能够重写有问题的页面,使用更快的查询集,将大部分工作加载到前端Web服务器上,并且从那时起就没有出现问题。

作者:eswald

相关问答

添加新评论