我想就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
答案 0 :(得分:61)
基本上,在以下情况下,您将获得处于睡眠状态的连接:
因此,当您有许多保持连接的PHP进程而没有在数据库端实际执行任何操作时,通常会在休眠状态下结束许多进程。
一个基本的想法,所以:确保你没有运行太长时间的PHP进程 - 或者在他们不再需要访问数据库时强制他们断开连接。
另一件事,我经常看到服务器上有一些负载:
可以提供帮助的解决方案是减少查询所需的时间 - 优化最长的查询。
答案 1 :(得分:2)
在增加max_connections变量之前,您必须通过运行show processlist命令来检查您有多少个非交互式连接。
如果您有许多睡眠连接,则必须减小“ wait_timeout”变量的值,以等待一段时间后关闭非交互式连接。
SHOW SESSION VARIABLES类似于“ wait_timeout”;
+ --------------------- + ------- +
|变量名|值|
+ --------------------- + ------- +
| wait_timeout | 28800 |
+ --------------------- + ------- +
该值以秒为单位,这意味着非交互式连接仍可长达8小时。
SET会话wait_timeout = 600; 查询正常,受影响的0行(0.00秒)
10分钟后,如果睡眠连接仍在睡眠,则mysql或MariaDB断开该连接。
答案 2 :(得分:1)
增加最大连接数不能解决问题。
我们在服务器上遇到了同样的情况。这就是发生的情况
用户打开一个页面/视图,该页面/视图连接到数据库,查询数据库,仍然没有完成查询(查询),并且用户离开页面或移至其他页面。 因此,如果有更多的用户连接数据库并执行类似的操作,则打开的连接将保持打开状态,并保持连接数量增加。
您可以设置MySQL的Interactive_timeout,默认为28800(8小时)到1小时
SET interactive_timeout=3600
答案 3 :(得分:0)
所以我同时运行了300个PHP进程并且速度达到每秒60-90之间(我的进程涉及3x查询)。我将它提高到400,这下降到每秒40-50左右。我把它降到200,然后回到60到90之间!
因此,对于遇到此问题的任何人,我的建议是尝试运行 less 而不是更多,并查看它是否有所改进。将使用更少的内存和CPU,因此运行的进程将具有更强的能力,并且速度可能会提高。
答案 4 :(得分:0)
上述解决方案,例如运行查询
SET session wait_timeout=600;
仅在重新启动mysql之前有效。对于持久解决方案,请编辑mysql.conf并在[mysqld]之后添加:
wait_timeout=300
interactive_timeout = 300
您想要的秒数是300。
答案 5 :(得分:-1)
好吧,所以在尝试了每个解决方案以解决wordpress博客上的确切问题之后,我可能做了一些非常愚蠢或天才的事情......不知道为什么Mysql连接有所增加,我在我的标题中使用下面的PHP脚本来杀死所有正在进行的进程..
因此,我网站的每位访问者都有助于消除睡眠过程..
<?php
$result = mysql_query("SHOW processlist");
while ($myrow = mysql_fetch_assoc($result)) {
if ($myrow['Command'] == "Sleep") {
mysql_query("KILL {$myrow['Id']}");}
}
?>