如何解决在vps上运行的mysql中的过多连接和致命错误


9

我在linode服务器上运行一个应用程序PHPlist,同时运行12个PHP脚本,每个脚本均打开一个MySQL连接。现在,当我访问PHPlist时,通常会显示此错误:

致命错误:抱歉,服务器当前太忙,请稍后再试。

当我尝试访问phpMyAdmin时,它显示了#1040错误。运行cron作业的我的PHP脚本的输出显示:

PHP警告:mysqli_connect():(HY000 / 1040):太多连接

我正在使用phpMyAdmin在服务器上使用LAMP堆栈;top终端中的输出显示mysqld使用100-130%CPU。当我尝试解决此问题时,我得到了一些提示:

  • 增加max_connection变量:我正在使用200(默认为100)
  • 打开表缓存:512(默认为400)

有很多变量需要设置,但我无法确定具体的变量,我从中获得了一些参考: 太多的连接http://dev.mysql.com/doc/refman/5.5/en/table-cache。 html

但是根据我的用法,如何增加内存以及对我来说最大的内存困难是什么。

在我的服务器上,我正在使用大约12个PHP脚本,用于发送电子邮件的PHPlist应用程序以及用于用户注册的主要数据库。

请帮助我解决这个问题。

Answers:


12

首先,您需要执行以下查询:

SELECT user,host FROM mysql.user
WHERE super_priv='Y' AND
CONCAT(user,'@',host) <> 'root@localhost';

这将列出所有具有SUPER特权的用户。执行与应用程序相关的数据库处理的大多数用户不需要此特权。根据MySQL文档,具有SUPER特权的用户可以执行以下操作:

  • 运行CHANGE MASTER TO以控制复制坐标
  • 杀死或mysqladmin kill杀死属于其他帐户的线程
  • 清除二进制日志以系统地删除二进制日志
  • 使用SET GLOBAL进行配置更改以修改全局系统变量
  • mysqladmin调试命令
  • 启用或禁用日志记录
  • 即使启用了* read_only *系统变量也执行更新
  • 在从属服务器上启动和停止复制
  • 在存储的程序和视图的DEFINER属性中指定任何帐户
  • 这是您的问题中最重要的一个:即使达到max_connections系统变量控制的连接限制,也可以使您连接(一次)。

您将需要以root @ localhost身份登录并撤销SUPER权限,如下所示:

UPDATE mysql.user SET super_priv='N'
WHERE super_priv='Y' AND
CONCAT(user,'@',host) <> 'root@localhost';
FLUSH PRIVILEGES;

完成此操作后,只要所有用户都淹没mysql连接,就只能root@localhost登录。毕竟,如果每个人和他的祖母都拥有SUPER特权,那么这将root@localhost永远无法与其他人保持联系。如果max_connections为200,并且您需要将其提高到300,而不必重新启动mysqld,则可以使用以下命令动态增加max_connections

mysql> SET GLOBAL max_connections = 300;

这样一来,更多的连接将立即生效,但不要随心所欲地任意增加连接数。您必须确保mysql有足够的RAM来容纳增加的内存。

注意:如果将max_connections动态更改为300,请放在/etc/my.cnf中

[mysqld]
max_connections=300

您可以在MySQL数据库服务器上运行mysqltuner.pl。如果没有,请运行以下命令:

cd
wget mysqltuner.pl
perl mysqltuner.pl

绩效指标下的第三行有

-------- Performance Metrics -------------------------------------------------
[--] Up for: 8d 20h 46m 22s (8M q [10.711 qps], 129K conn, TX: 90B, RX: 19B)
[--] Reads / Writes: 4% / 96%
[--] Total buffers: 2.1G global + 5.4M per thread (2000 max threads)
[OK] Maximum possible memory usage: 12.6G (80% of installed RAM)

看到每个线程5.4M吗?这是max_connections的倍数。在此示例中,最大RAM约为10.8G。因此,每次增加max_connections时,都应运行mysqltuner.pl并检查是否按OS占用了太多内存。

无论如何,限制谁拥有SUPER特权将使此类用户有机会减轻数据库连接对mysqld的洪灾。


我在尝试perl mysqltuner.pl时遇到此错误。“试图使用来自debian维护帐户的登录凭证,但是它们失败了。”
沙申克

我正在我的本地ubuntu服务器上尝试此操作,它显示了最大的内存使用量,但是在我的vps上,它显示了失败,并且我无法登录phpmyadmin但在mysql终端中成功登录
Shashank 2012年

这个cmd wget mysqltuner.pl,下载了index.html,但是它是一个perl文件,因此我将其重命名为mysqltuner.pl,下一个cmd可以正常perl mysqltuner.pl工作。
MotsManish

2
  1. 全局变量max_connections确定到MySQL的最大并发连接数。确保此变量的值很高。您可以将该值增加到300或400,然后尝试在执行此设置后重新启动MySQL。
  2. 设计应用程序时,要使MySQL连接在很短的时间内保持打开状态。
  3. 您还应检查客户端代码未正确使用持久连接(例如mysql_pconnect())。

还要Flush status;在MySQl服务器上执行命令以减小此值。

希望这些建议对您有所帮助。


0

检查磁盘是否已满,这可能导致相同的错误:

df -h

将显示每个分区上的剩余空间,您可能必须检查根分区/(或/ var /,以防有多余的分区):

df -h /
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.