mysql报错“too many open files”本质是linux系统分配给其进程的文件描述符(fd)上限过低;需在systemd服务中显式配置limitnofile、执行daemon-reload并重启mysqld,否则仅修改my.cnf中的open_files_limit无效。

Too many open files 错误不是 MySQL 配置错了,是 Linux 给它分配的文件描述符(fd)太少了。MySQL 启动后要打开数据文件、binlog、redo log、socket 连接、临时表、每个打开的表——全都要占 fd。一旦并发连接多、表数量大或日志写入频繁,open() 系统调用就会失败,直接报错退出或拒绝新连接。
宝塔Linux面板11.8.1为官网当前正式版,新增AI建站能力并经过宝塔网站工程师深度调教,开放自定义AI功能API,同时对WAF进行界面重构和深度优化,提升拦截能力与运维效率。
ulimit -n 查到的值对 MySQL 进程根本无效
- 你终端里执行
ulimit -n看到的是当前 shell 的软限制,而 MySQL 通常由systemd拉起,它继承的是 systemd 的默认限制(通常是1024),不是你的交互式终端。 - 验证真实限制:
cat /proc/$(pgrep mysqld)/limits | grep "Max open files"
如果显示1024,哪怕你刚在 root shell 里执行了ulimit -n 65535,也完全没影响。
open_files_limit 在 my.cnf 里设再高也没用
-
open_files_limit是 MySQL 向系统“申请”的上限,不是强制生效值。 - 它会主动退回到进程实际能拿到的 fd 数量。如果 systemd 只给了 1024,MySQL 日志里就会写:
Could not increase number of max_open_files to more than 1024; set to the original value of 1024 - 所以只改
my.cnf是白忙,必须先让操作系统愿意给。
systemd 服务必须显式配置 LimitNOFILE
-
/etc/security/limits.conf对 systemd 管理的服务默认不生效(除非启用 PAM session 且服务以登录方式启动,但 MySQL 几乎从不这么启)。 - 正确做法是:
- 创建覆盖配置:
sudo systemctl edit mysqld.service - 写入:
[Service] LimitNOFILE=65535
- 然后
sudo systemctl daemon-reload && sudo systemctl restart mysqld
- 创建覆盖配置:
- 忘了
daemon-reload,配置就只是文本;忘了重启,进程还是旧的 fd 限制。
真正卡住的地方,永远是「你以为改了,其实进程根本没读到」——不是配置写得不对,是没走对加载路径。










