必须修改systemd的limitnofile,否则其他设置无效;mysql由systemd管理时不读/etc/security/limits.conf等配置,需通过systemctl edit mysqld设置limitnofile=65536,并同步调整fs.file-max和my.cnf中的open_files_limit。

必须改 systemd 的 LimitNOFILE,否则所有其他操作都白忙。 MySQL 由 systemd 管理时,/etc/security/limits.conf、ulimit -n 命令、/etc/profile 里的设置全无效——它压根不读这些。
查清 MySQL 进程当前真实的文件句柄限制
别猜,直接看内核给它的值:
- 先拿到 PID:
pidof mysqld或systemctl show --property MainPID mysqld | cut -d'=' -f2 - 再查实际生效限制:
cat /proc/<code>PID/limits | grep "Max open files" - 如果 Soft Limit 和 Hard Limit 都是
1024或4096,说明没配对;即使显示65536但仍有Too many open files报错,就得继续查fs.file-max和open_files_limit是否匹配
正确修改 systemd 服务的 LimitNOFILE
这是唯一可靠的方式,适用于 Ubuntu/CentOS/Rocky 等所有主流发行版:
- 运行
sudo systemctl edit mysqld(若服务名是mysql,请替换为mysql) - 在打开的编辑器中写入:
[Service] LimitNOFILE=65536
- 保存后执行:
sudo systemctl daemon-reload && sudo systemctl restart mysqld - 验证是否加载成功:
systemctl show mysqld | grep LimitNOFILE;再查进程:cat /proc/$(pidof mysqld)/limits | grep "Max open files" - 注意:
LimitNOFILE=infinity在某些内核版本下会 fallback 到4096,不建议用
同步调整系统级 fs.file-max 和 MySQL 内 open_files_limit
LimitNOFILE 是单个进程上限,但整个系统能分配的文件描述符总数由 fs.file-max 控制。如果它太小(比如默认的 84576),多个高并发服务一起开就可能耗尽:
- 永久生效:往
/etc/sysctl.conf追加fs.file-max = 2097152,再运行sudo sysctl -p -
open_files_limit是 MySQL 自己向上申请的值,不会自动等于LimitNOFILE。在/etc/my.cnf的[mysqld]段里显式设为相近值,例如:open_files_limit = 65536 -
innodb_open_files建议设为LimitNOFILE的 70% 左右(如40000),留余量给 binlog、socket 等其他文件
最容易被忽略的是:改完 LimitNOFILE 后没重载 systemd 配置,或忘了调 fs.file-max。这两个缺一不可,否则哪怕进程限制调到了 65536,系统总池子不够,MySQL 还是会在高并发时突然卡住或报错。











