mysql 5.7崩溃或启动失败主因是open_files_limit系统级限制不足,需先查cat /proc/$(pgrep mysqld)/limits | grep "max open files"确认实际额度,若为1024等低值则配置无效;超128个分区会直接触发error 23,须用alter table remove partitioning降级;systemd环境下必须显式配置limitnofile并reload重启,否则/etc/security/limits.conf无效。

MySQL 5.7 崩溃或启动失败,只要看到 ERROR 23、Out of resources when opening file 或日志里反复出现 Too many open files,基本就是 open_files_limit 卡死导致的——不是配置没写,是系统根本没给够。
查进程实际能打开多少文件
SHOW VARIABLES LIKE 'open_files_limit' 返回的值只是 MySQL “声称”的上限,不等于它真能用到。关键要看操作系统到底给了 mysqld 进程多少额度:
- 先找到 mysqld 进程 PID:
pgrep mysqld - 再查该进程被系统允许打开的最大文件数:
cat /proc/$(pgrep mysqld)/limits | grep "Max open files" - 如果输出显示
1024或4096,哪怕 my.cnf 里写了open_files_limit = 65535,也白搭
确认崩溃是否由分区表触发
MySQL 5.7 对每个分区都单独持有一个 .ibd 文件句柄,不复用。一旦分区数超 128,open_files_limit 很快耗尽,直接报 ERROR 23 启动失败,或运行中某分区突然不可访问:
- 查当前表分区数量:
SELECT COUNT(*) FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA = 'your_db' AND TABLE_NAME = 'your_table'; - 检查是否接近或超过 128:超过就必须退化,用
ALTER TABLE your_table REMOVE PARTITIONING在线降级 - RANGE 分区单区行数别超 1500 万,否则 B+ 树深度涨、IO 次数翻倍,性能反而下降
验证 systemd 是否真正放行了 LimitNOFILE
Ubuntu/CentOS 7+ 默认用 systemd 管理 mysql 服务,/etc/security/limits.conf 对服务进程完全无效,必须显式配置 service 单元限制:
- 运行
sudo systemctl edit mysql(或mariadb),添加: [Service] LimitNOFILE=65535
- 执行
sudo systemctl daemon-reload && sudo systemctl restart mysql - 重启后立刻再跑一遍
cat /proc/$(pgrep mysqld)/limits | grep "Max open files",确保软硬限制都到了 65535 - 注意:如果
my.cnf中open_files_limit设得比 systemd 的LimitNOFILE小,MySQL 会按小的那个生效
为什么改了配置还是卡在 214 或 1238?
MySQL 启动时会根据 max_connections 和 table_open_cache 自动估算所需文件描述符,并取三者最大值作为请求值:10 + max_connections + table_open_cache * 2、max_connections * 5、open_files_limit 配置值。如果系统只给了 1024,它就只能凑出约 214(预留 ~800 给日志、表缓存等内部使用):
- 查当前估算逻辑是否生效:进 MySQL 执行
SELECT @@open_files_limit, @@max_connections, @@table_open_cache; - 若
@@open_files_limit明显低于你设的值,且/proc/$(pgrep mysqld)/limits也低,说明系统限制仍是瓶颈 -
open_files_limit = 0是最危险写法——MySQL 会自己“猜”,结果往往极度保守
真正卡住的地方从来不在 MySQL 配置文件里,而在 /proc/$(pgrep mysqld)/limits 这一行输出里。没看到 65535,其他所有调优都是空中楼阁。











