起因
最近搞xxx管理平台的部署,遇到这样一个问题:
一开始使用mariadb安装完成之后使用默认的配置,没有改动过/etc/my.cnf中任何参数。结果有一天同事告诉我说数据库一直提示一个错误:
ERROR 1040 (HY000): Too many connections
原因的话,字面上看嘛,很简单,就是连接数太多了,数据库默认的数据连接数设置的太小了。
那么,问题来了,现在系统占用的连接数是多少呢,数据库默认的最大连接数又是多少呢?
查看当前连接数:
使用mysql自带的控制查询语句。
mysql -e "show processlist;" | wc -l
209
查询最大连接数:
MariaDB [(none)]> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 214 |
+-----------------+-------+
1 row in set (0.00 sec)
于是就在 mariadb 的配置文件 /etc/my.cnf 中设置了最大连接数(max_connections)这个参数:
[mysqld]
bind-address = 0.0.0.0
max_connections = 1024
...
但是,重启之后没有卵用,还是报上边的那个错!
再次查看一下最大可用连接数,发现还是214:
MariaDB [(none)]> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 214 |
+-----------------+-------+
1 row in set (0.00 sec)
于是,找到了一个老外的文章:Increasing MySQL 5.5 max_connections on RHEL 5。说明了原因:
The problem is that the maximum number of open files allowed is too
small, by default 1024, to increase max_connections beyond 214.
解决办法
这里边介绍了那篇文章的作者尝试过几种方式:
第一种方法:
修改内核配置项: fs.file-max
There are plenty of online guides that explain how to handle this, including increasing the kernel fs.file-max setting, which may be necessary by editing /etc/sysctl.conf, in this example to double the default:
fs.file-max = 2459688
Then run sysctl -p to make the change take immediate effect. (It’ll remain after reboot too.)
然后执行 sysctl -p
使上边的配置立即生效。
第二种方法:
修改配置文件中/etc/security/limits.conf
中关于mysql的选项:
There are also many guides that say you need to change etc/security/limits.conf along these lines:
mysql soft nofile 4096
mysql hard nofile 4096
但是,作者发现这种方式有个问题,就是使用init脚本启动mysql或者使用service命令启动时,上边的参数不生效。
标准的RHEL的mysql-server(5.1)包,提供了/etc/init.d/mysqld (而不是Oracle和Percona 版本上的init.d/mysql)启动脚本, 你可以创建/etc/sysconfig/mysqld
文件,里边包含 ulimit -n 4096
这样一行,重启mysql守护进程之后这个配置就会生效。
However, the /etc/security/limits.conf change does not actually work when mysqld is started via the init script in /etc/init.d/mysql or via service mysql restart.
With standard Red Hat mysql-server (5.1) package that provides /etc/init.d/mysqld (not /etc/init.d/mysql as the Oracle and Percona versions do), you could create a file /etc/sysconfig/mysqld containing ulimit -n 4096 and that setting will take effect for each restart of the MySQL daemon.
第三种方法:
不用像上面那两种hack方式那么麻烦,因为你只需要简单地修改/etc/my.cnf
中的 open_files_limit
选项
But the ulimit -n setting hacked into the init script or put into /etc/sysconfig/mysqld isn’t really needed after all, because you can simply set open_files_limit in /etc/my.cnf:
示例:
[mysqld]
open_files_limit = 8192
max_connections = 1024
# etc.
此后需要重启mariadb:
systemctl restart mariadb
再次查询时,发现最大连接数已经改变,至此问题解决。
MariaDB [(none)]> show variables like 'max_connections';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 1024 |
+-----------------+-------+
1 row in set (0.00 sec)
总结:
由于第一种方式需要修改内核参数,第二种又要修改启动脚本比较麻烦,因此,我采用的是这里第三种方式,也推荐大家采用这种方式,修改灵活,改动的影响最小 :) 。