一尘不染

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

mysql

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

Fatal Error: Sorry, the server is currently too busy, please try again later.

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

PHP Warning: mysqli_connect(): (HY000/1040): Too many connections

我正在使用带有 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 应用程序以及用于用户注册的主要数据库。

请帮我解决这个问题。


阅读 47

收藏
2022-10-17

共1个答案

一尘不染

首先你需要做的是运行这个查询:

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

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

  • 运行 CHANGE MASTER TO 以控制复制坐标
  • KILL 或mysqladmin kill杀死属于其他帐户的线程
  • PURGE BINARY LOGS 系统地删除二进制日志
  • 使用 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登录。毕竟,如果每个人和他的祖母都拥有超级特权,这将root@localhost永远无法与其他人联系。如果 max_connections 为 200 并且您需要将其提高到 300 而无需重新启动 mysqld,则可以使用以下命令动态增加max_connections :

mysql> SET GLOBAL max_connections = 300;

这将允许更多的连接立即生效,但不要一时兴起就随意增加数量。您必须确保 mysql 有足够的 RAM 来容纳增加的内存。

CAVEAT : 如果您将 max_connections 动态更改为 300,请将其放入 /etc/my.cnf

[mysqld]
max_connections=300

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

cd
wget mysqltuner.pl
perl mysqltuner.pl

Performance Metrics 下的第 3 行有这个

-------- 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 并检查是否按操作系统占用太多内存。

在任何情况下,限制拥有 SUPER 权限的用户都可以让这些用户有机会减轻数据库连接对 mysqld 的泛滥。

2022-10-17