MySql过程列表填充"睡眠"条目导致"连接太多"?

edo*_*ian 58 php mysql

我想就php/mysql连接的长期问题向你提供帮助.

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

从来没有出现太多问题(我没有找到快速的解决方案),直到最近流量数量增加,从那时起MySQL反复报告"到多个连接"的问题,即使这样的350多个连接处于"睡眠"状态.即使存在与同一服务器的睡眠连接,服务器也无法获得MySQL连接.

重新启动Apache服务器时,所有这些连接都会消失.

用于创建数据库连接的PHP代码使用普通的"mysql"模块,"mysqli"模块,PEAR :: DB和Zend Framework Db适配器.(不同的项目).没有项目使用持久连接.

提高连接限制是可能的,但似乎不是一个好的解决方案,因为它现在是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
Run Code Online (Sandbox Code Playgroud)

Pas*_*TIN 68

基本上,在以下情况下,您将处于睡眠状态:

  • PHP脚本连接到MySQL
  • 一些查询被执行
  • 然后,PHP脚本做了一些需要时间的东西
    • 无需断开与DB的连接
  • 最后,PHP脚本结束
    • 这意味着它与MySQL服务器断开连接

因此,当您有许多保持连接的PHP进程而没有在数据库端实际执行任何操作时,通常会在休眠状态下结束许多进程.

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


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

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

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

  • 这很奇怪......哦,也许是一个想法:你使用永久连接吗?(例如,使用`mysql_pconnect`函数) (4认同)
  • 我认为你需要再次寻找持久连接,Zend和PDO都不会在其中使用带有'*pconnect*'的语法来实现持久连接. (2认同)

小智 7

在增加 max_connections 变量之前,您必须通过运行 show processlist 命令检查有多少个非交互式连接。

如果您有很多睡眠连接,则必须减小“wait_timeout”变量的值以在等待一段时间后关闭非交互式连接。

  • 显示 wait_timeout 值:

显示会话变量,例如“wait_timeout”;

+---------------+--------+

| 变量名 | 价值|

+---------------+--------+

| 等待超时| 28800 |

+---------------+--------+

该值以秒为单位,表示非交互式连接仍长达 8 小时。

  • 要更改“wait_timeout”变量的值:

设置会话 wait_timeout=600; 查询正常,0 行受影响(0.00 秒)

10 分钟后,如果睡眠连接仍在睡眠,则 mysql 或 MariaDB 会删除该连接。


小智 6

增加最大连接数并不能解决问题。

我们在我们的服务器上遇到了同样的情况。这就是发生的事情

用户打开一个页面/视图,连接到数据库,查询数据库,仍然查询(查询)没有完成,用户离开页面或移动到其他页面。因此,如果有更多用户与数据库连接并执行类似操作,则打开的连接将保持打开状态并保持连接数量不断增加。

你可以设置interactive_timeout MySQL,默认是28800(8小时)到1小时

SET interactive_timeout=3600
Run Code Online (Sandbox Code Playgroud)


Mar*_*vel 5

上述解决方案如运行查询

SET session wait_timeout=600;
Run Code Online (Sandbox Code Playgroud)

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

wait_timeout=300
interactive_timeout = 300
Run Code Online (Sandbox Code Playgroud)

其中 300 是您想要的秒数。