mysql启动失败主因是权限不足或selinux拦截,需确保mysql用户对新tmpdir有读写执行权限、打selinux标签、禁用nfs/fuse路径,动态设置仅对新连接生效且不能替代配置文件修改。

tmpdir 路径修改后 MySQL 启动失败怎么办
改完 tmpdir 重启服务就挂,八成是权限或 SELinux 拦着了。MySQL 启动阶段就要往新路径写临时文件(比如 ALTER TABLE 重建表的中间文件),此时动态设置无效,必须确保配置即刻可用。
-
chown mysql:mysql /data/mysqltmp和chmod 700 /data/mysqltmp是底线,不能只给755或漏掉执行权限 - CentOS/RHEL 系统跑
sestatus看到Current mode: enforcing就必须打 SELinux 标签:semanage fcontext -a -t mysqld_tmp_t "/data/mysqltmp(/.*)?",再restorecon -Rv /data/mysqltmp - 别把
tmpdir设在 NFS、CIFS、FUSE 挂载点上——MySQL 明确不支持,日志里会报Operation not supported - 用
lsof -u mysql | grep /data/mysqltmp验证进程是否真能访问该路径,而不是靠猜
tmpdir 多路径写法(/path1:/path2)到底有没有用
Linux 下支持冒号分隔多个路径,但实际生效逻辑很朴素:MySQL 每次创建临时文件时,轮询取第一个**可用且可写**的路径。它不会做负载均衡,也不会自动跳过已满的路径。
- 如果你写了
tmpdir = /tmp:/data/mysqltmp,而/tmp空间还有 2GB,MySQL 就永远只往/tmp写,直到填满或权限出错才切到第二个 - 真正想分流 IO,得手动控制——比如把不同业务库的从库实例分别指向不同
tmpdir,或配合innodb_tmpdir(MySQL 8.0+)拆开 InnoDB 内部临时表路径 - Windows 不支持冒号分隔,只认分号
;,且行为更不可控,生产环境建议单路径
为什么 SHOW VARIABLES LIKE 'tmpdir' 显示对了,但临时文件还是出现在 /tmp
不是配置没生效,而是你看到的是“当前连接读到的值”,不代表所有线程都在用它。MySQL 启动时加载的 tmpdir 才决定内部排序、复制线程、崩溃恢复等关键路径的行为。
- 执行
SET GLOBAL tmpdir = '/data/mysqltmp'只影响后续新建连接的用户临时表和部分排序操作,对已连连接、IO/SQL 线程、ALTER TABLE这类 DDL 无感 - 确认真正生效,得看 MySQL 错误日志(
log-error指向的文件)里启动时有没有类似Using tmpdir '/data/mysqltmp'的提示行 - 用
lsof -p $(pgrep mysqld) | grep -E "(MYD|MYI|ibtmp)"直接抓进程打开的临时文件句柄,比查变量更真实
MyISAM 临时文件暴增时,除了换磁盘还能做什么
把 tmpdir 挪到 SSD 只是兜底手段。MyISAM 临时文件多,本质是查询没走索引或内存不够撑住排序,治标更要治本。
- 调高
tmp_table_size和max_heap_table_size(两者取小值生效),比如设为512M,让小一点的 GROUP BY/ORDER BY 尽量留在内存 - 检查
Created_tmp_disk_tables / Created_tmp_tables比值,持续高于 15% 就得优化 SQL:加复合索引覆盖ORDER BY + WHERE字段,避免SELECT *带出大字段触发磁盘落表 - MyISAM 表本身不支持在线 DDL,
ALTER TABLE必然生成临时文件,这类操作尽量避开高峰,并确保tmpdir所在磁盘 inode 也充足(df -i看)
tmpdir 下创建的临时文件名形如 SQL_abc123.MYD,但这些文件即使被查询结束也不会立刻删除——要等整个连接断开。长连接多的场景下,tmpdir 目录可能堆满“已关闭但未清理”的残留文件,光靠重启 MySQL 不一定能清干净,得结合 lsof | grep deleted 定位并 kill 对应进程。











