MySql Proccesslist充满了“睡眠”条目,导致“连接太多”?

2022-08-30 08:21:55

我想请您帮助解决php / mysql连接的长期问题。

每次我执行“SHOW PROCESSLIST”命令时,它都会向我显示大约400个空闲(状态:睡眠)连接到从我们的5个Web服务器出现的数据库服务器。

这从来都不是一个大问题(我没有找到快速的解决方案),直到最近流量增加,从那时起,MySQL反复报告“到许多连接”问题,即使如此,其中350多个连接处于“睡眠”状态。此外,即使与同一服务器存在睡眠连接,服务器也无法获得MySQL连接。

当apache服务器被重述时,所有这些连接都会消失。

用于创建数据库连接的PHP代码使用普通的“mysql”模块,“mysqli”模块,PEAR::D B和Zend Framework Db Adapter。(不同的项目)。所有项目都不使用持久连接。

提高连接限制是可能的,但似乎不是一个好的解决方案,因为它现在是450,而且一次只有20-100个“真实”连接。

我的问题:

为什么有这么多连接处于睡眠状态,我该如何防止这种情况?

-- 更新:

一次运行的Apache请求数量永远不会超过50个并发请求,所以我猜关闭连接或apache在没有附加phpscript或其他东西的情况下保持端口打开存在问题(?

my.cnf 以防万一它有帮助:

innodb_buffer_pool_size = 1024M

max_allowed_packet = 5M
net_buffer_length = 8K

read_buffer_size = 2M
read_rnd_buffer_size = 8M

query_cache_size = 512M
myisam_sort_buffer_size = 128M

max_connections = 450
thread_cache = 50
key_buffer_size = 1280M
join_buffer_size = 16M

table_cache = 2048
sort_buffer_size = 64M
tmp_table_size = 512M
max_heap_table_size = 512M

thread_concurrency = 8

log-slow-queries = /daten/mysql-log/slow-log
long_query_time = 1
log_queries_not_using_indexes

innodb_additional_mem_pool_size = 64M
innodb_log_file_size = 64M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 2
innodb_file_per_table

答案 1

基本上,在以下情况下,您将获得处于睡眠状态的连接:

  • 一个PHP脚本连接到MySQL
  • 执行一些查询
  • 然后,PHP脚本会做一些需要时间的事情
    • 不断开与数据库的连接
  • 最后,PHP 脚本结束
    • 这意味着它与MySQL服务器断开连接

因此,当您有很多PHP进程保持连接时,通常最终会有许多进程处于睡眠状态,而无需在数据库端实际执行任何操作。

一个基本的想法,所以:确保你没有运行太长时间的PHP进程 - 或者强制它们在不再需要访问数据库时断开连接。


另一件事,当服务器上有一些负载时,我经常看到:

  • 有越来越多的请求来到Apache
    • 这意味着要生成许多页面
  • 每个PHP脚本,为了生成一个页面,连接到数据库并执行一些查询
  • 随着数据库服务器上的负载增加,这些查询需要越来越多的时间
  • 这意味着更多的流程不断堆积如山

一个可以提供帮助的解决方案是减少查询所需的时间 - 优化最长的查询。


答案 2

上述解决方案类似于运行查询

SET session wait_timeout=600;

只有在重新启动 mysql 之前才会起作用。对于持久化解决方案,请编辑 mysql.conf 并在 [mysqld] 之后添加:

wait_timeout=300
interactive_timeout = 300

其中 300 是所需的秒数。


推荐