Allen 2023-10-25 0 6485 0 0 0 0
Mysql错误,服务器管理,很多开发人员都会遇见”MySQL: ERROR 1040: Too many connections”的异常情况,造成这种情况的一种原因是访问量过高,MySQL服务器抗不住,这个时候就要考虑增加从服务器分散读压力;另一种原因就是MySQL配置文件中max_connections值过小

今天发现访问网站时报错:

Warning: mysqli::__construct(): (08004/1040): Too many connections in /www/wwwroot/xxx/function/xxx.php on line 119
Too many connections
Warning: mysqli::query(): Couldn't fetch mysqli in /www/wwwroot/xxx/function/xxx.php on line 868


Fatal error: Uncaught Error: Call to a member function fetch_assoc() on bool in /www/wwwrootxxx/function/xxx.php:870 Stack trace: #0 /www/wwwroot/xxx/xxx.php(144): xxx() #1 {main} thrown in /www/wwwroot/xxx/function/xxx.php on line 870

查询原因,应该是因为这个:

实际连接数超过了mysql 允许的最大连接数,访问量过高,MySQL服务器抗不住。


解决办法

1、修改max_connections,如果这个值已经很大,2、这个时候就要考虑增加从服务器分散读压力;

Windows 找到mysql.ini(Linux 修改/etc/my.cnf文件,在[mysqld]中新增max_connections=N)。修改允许最大连接数max_connections=N,默认是100 一般设置到500~1000比较合适(

这建立在机器能支撑的情况下,因为如果连接数越多,介于MySQL会为每个连接提供连接缓冲区,就会开销越多的内存,所以要适当调整该值,不能盲目提高设值。

),最后重启mysql,一定要重启。

+++

查看服务器状态,发现400G的硬盘居然满了。。。

查找发现大文件:

/www/server/data/ibtmp1,317.61 GB,2023/10/25 10:23:26

直接删除,清空回收站,也没见变化!

...

查看监控,发现10242132-202310250316之间,resource usage和cpu使用量达到了100%,Load detail,也经历了一个波峰。

+++

重启服务器

10:32 2023年10月25日

+++

参考:

很多开发人员都会遇见”MySQL: ERROR 1040: Too many connections”的异常情况,造成这种情况的一种原因是访问量过高,MySQL服务器抗不住,这个时候就要考虑增加从服务器分散读压力;另一种原因就是MySQL配置文件中max_connections值过小。

查看mysql的最大连接数:

mysql> show variables like '%max_connections%';

查看服务器响应的最大连接数:

mysql> show global status like 'Max_used_connections';

可以看到服务器响应的最大连接数为2,远远低于mysql服务器允许的最大连接数值。

对于mysql服务器最大连接数值的设置范围比较理想的是:服务器响应的最大连接数值占服务器上限连接数值的比例值在10%以上,如果在10%以下,说明mysql服务器最大连接上限值设置过高。

Max_used_connections / max_connections * 100% = 2/151 *100% ≈ 1%

我们可以看到占比远低于10%(因为这是本地测试服务器,结果值没有太大的参考意义,大家可以根据实际情况设置连接数的上限值)。

设置这个最大连接数值:

mysql> set GLOBAL max_connections=256;

连接数超过了 MySQL 设置的值,与 max_connections 和 wait_timeout 都有关系。wait_timeout 的值越大,连接的空闲等待就越长,这样就会造成当前连接数越大。

wait_timeout过大有弊端 默认值为28800(即8小时),其体现就是MySQL里大量的SLEEP进程无法及时释放,拖累系统性能,不过也不能把这个指设置的过小,否则你可能会遭遇到“MySQL has gone away”之类的问题,通常来说,我觉得把wait_timeout设置为10是个不错的选择,但某些情况下可能也会出问题,比如说有一个CRON脚本,其中两次SQL查询的间隔时间大于10秒的话,那么这个设置就有问题了(当然,这也不是不能解决的问题,你可以在程序里时不时mysql_ping一下,以便服务器知道你还活着,重新计算wait_timeout时间)

mysql> show global variables like 'wait_timeout';

mysql> set global wait_timeout=10;

生产服务器上数据库又不能随便重启,只好想办法手动去释放一些没用的连接。

mysql> show processlist;可以得到所有连接到这个服务器上的MySQL连接

你可以看到MySQL数据连接列表,而且每一个都会有一个进程ID号(在上表的第一列)。我们只要输入这样的命令:

mysql> kill 1180421;(其中1180421是进程列表里找到并且要杀掉的进程号)

为了防止发生too many connections时候无法登录的问题,mysql manual有如下的说明:

mysqld actually allows max_connections+1 clients to connect. The extra connection is reserved for use by accounts that have the SUPER privilege. By granting the SUPER privilege to administrators and not to normal users (who should not need it), an administrator can connect to the server and use SHOW PROCESSLIST to diagnose problems even if the maximum number of unprivileged clients are connected.

因此, 必须只赋予root用户的SUPER权限,同时所有数据库连接的帐户不能赋予SUPER权限。前面说到的报错后无法登录就是由于我们的应用程序直接配置的root用户

查看当前数据库的所有用户:

select user,host,password from mysql.user;

给用户赋予super权限(super和ALL PRIVILEGES都可以):

GRANT super ON *.* TO 'mysql'@'localhost';

GRANT ALL PRIVILEGES ON *.* TO 'mysql'@'localhost';

删除用户的super权限(super和ALL PRIVILEGES都可以):

REVOKE super ON *.* FROM 'mysql'@'localhost';

REVOKE ALL PRIVILEGES ON *.* FROM 'mysql'@'localhost';

查看赋予用户的权限

SHOW GRANTS FOR 'mysql'@'localhost';


【版權聲明】
本文爲原創,遵循CC 4.0 BY-SA版權協議!轉載時請附上原文鏈接及本聲明。
原文鏈接:https://tdlib.com/am.php?t=91fUC0cQI4u2
Tag: Mysql错误 服务器管理
我也要發一個   ·   返回首頁   ·   返回[Mysql]   ·   前一個   ·   下一個
相關內容
歡迎評論
未登錄,
請先 [ 註冊 ] or [ 登錄 ]
(一分鍾即可完成註冊!)
返回首頁     ·   返回[Mysql]   ·   返回頂部