1、前言
最近使用mysql5.7的时候,总是出现mysql错误,提示too many connections,于是检查了mysql的配置文件,发现mysql的配置文件已经修改为max_connections=1000,但是还是提示该报错。
2、故障排查
1.登陆mysql查看
1.1检查mysql实际连接数
mysql> show variables like '%max_connections%';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 214 |
+-----------------+-------+
row in set (0.00 sec)
发现mysql的实际最大连接数只有214,和配置文件的1000不一致,也就是mysql的最大连接数设置并没有生效。
Linux一切皆文件,于是查看了下mysql的文件限制。
1.2 检查mysql可以打开的文件数量
mysql> show variables like '%open_files_limit%';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| open_files_limit | 1024 |
+------------------+-------+
发现mysql的open_files只有1024,于是我开始查看系统的文件设置。
1.3 检查系统文件
ulimit -a
root@jiajia:~# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 3824
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 3824
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
发现系统文件的open files 为65535,说明这个open file并没有被mysql使用。
3、查找原因
上网搜集了不少资料,发现在ubuntu16.04的操作系统中,使用Systemd替代了之前的SysV,因此 /etc/security/limits.conf 文件的配置作用域缩小了些。
limits.conf这里的配置,只适用于通过PAM认证登录用户的资源限制,它对systemd的service的资源限制不生效。
对于systemd service的资源限制,如何配置呢?全局的配置,放在文件 /etc/systemd/system.conf 和 /etc/systemd/user.conf。 同时,也会加载两个对应的目录中的所有.conf文件 /etc/systemd/system.conf.d/.conf 和 /etc/systemd/user.conf.d/.conf
其中,system.conf 是系统实例使用的,user.conf用户实例使用的。一般的sevice,使用system.conf中的配置即可。
systemd.conf.d/.conf中配置会覆盖system.conf。
4、解决办法
4.1 使用systemctl 命令编辑mysql.service
systemctl edit mysql.service
输入一下内容
[Service]
LimitNOFILE=infinity
LimitMEMLOCK=infinity
保存上边的输入,系统会自动文成下边的文件
/etc/systemd/system/mysql.service.d/override.conf
更改mysql配置文件
max_connections = 9999
重启这两个服务
systemctl daemon-reload #让 SystemD 重新加载配置文件
systemctl restart mysql.service
登陆mysql查看
mysql> show variables like '%max_connections%';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 9999 |
+-----------------+-------+
1 row in set (0.00 sec)
mysql> show variables like '%open_files_limit%';
+------------------+---------+
| Variable_name | Value |
+------------------+---------+
| open_files_limit | 1048576 |
+------------------+---------+
1 row in set (0.00 sec)
更改成功,以后更改配置文件也可以使用一下命令生效。
service mysql restart
4.2 直接更改mysql.service
在/etc/systemd/system 目录下我查看了下其他被systemctl 所管理的服务
ll redis.service
redis.service -> /lib/systemd/system/redis-server.service
发现其实这里服务通过软连接使用的是/lib/systemd/system下的服务,于是可以直接修改这个目录下的mysql服务
mysql.service服务在/lib/systemd/system下
cd /lib/systemd/system
vi mysql.service
修改mysql.service
# MySQL systemd service file
[Unit]
Description=MySQL Community Server
After=network.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
PermissionsStartOnly=true
ExecStartPre=/usr/share/mysql/mysql-systemd-start pre
ExecStart=/usr/sbin/mysqld
ExecStartPost=/usr/share/mysql/mysql-systemd-start post
TimeoutSec=600
Restart=on-failure
RuntimeDirectory=mysqld
RuntimeDirectoryMode=755
LimitNOFILE=infinity #新增
LimitMEMLOCK=infinity #新增
保存后,重启mysql服务
service mysql restart
登陆mysql查看,我的另一台服务器修改最大连接数为3000
mysql> show variables like '%max_connections%';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 3000 |
+-----------------+-------+
1 row in set (0.00 sec)
mysql> show variables like '%open_files_limit%';
+------------------+---------+
| Variable_name | Value |
+------------------+---------+
| open_files_limit | 1048576 |
+------------------+---------+
1 row in set (0.00 sec)
这样mysql的最大连接数就修改成功了。