mysql安装报“no space left on device”90%是/tmp或/var/tmp分区小或被tmpfs限制,需用df和lsof定位并迁移tmpdir、datadir及tmpdir至大分区。

MySQL安装失败报“No space left on device”,90%以上不是磁盘真没空间,而是/tmp或/var/tmp所在分区太小,或安装器临时解压路径被卡死。
为什么安装时突然爆满 /tmp?
MySQL 安装包(deb/rpm)本身不大,但安装过程要解压、初始化系统表、生成 ibdata1/ib_logfile*、写 binlog 等,中间大量依赖临时目录。默认行为如下:
- Debian/Ubuntu 的
apt默认用/tmp解压 deb 包,再拷贝到目标路径; - CentOS/RHEL 的
yum或rpm默认走/var/tmp,且rpm --showrc | grep tmp可确认; - 源码编译时,
cmake若未指定-DCMAKE_INSTALL_PREFIX,可能落在/usr/local,而该分区常较小; - 很多云主机或容器环境的
/tmp是tmpfs(内存挂载),大小仅为 RAM 的一半,几 GB 就撑爆。
怎么快速定位是哪个分区在拖后腿?
别猜,直接执行这三行命令:
df -h | grep -E '(tmp|var|usr)' df -h $(dirname $(mysql -Nse "SELECT @@datadir" 2>/dev/null || echo "/var/lib/mysql")) ls -ld /tmp /var/tmp
重点关注输出中 Use% ≥95% 的挂载点。特别注意:/tmp 显示为 tmpfs 类型时,容量就是硬上限,删文件也无效——必须换路径。
不重装、不扩容,立刻绕过限制的实操方法
核心思路:把安装器和 MySQL 启动时的临时落脚点,挪到有空间的地方。
- 安装前设置环境变量:
export TMPDIR=/data/tmp(确保该目录存在、权限为mysql:mysql、且不在tmpfs上); - APT 安装时强制指定临时目录:
sudo apt -o DPkg::Install::TempDir=/data/tmp install mysql-server; - RPM 安装前建软链(慎用):
sudo ln -sf /data/tmp /var/tmp,但需在rpm执行前完成,且重启后可能失效; - 安装完成后**必须立刻改配置**:编辑
/etc/mysql/my.cnf,在[mysqld]下加:datadir = /data/mysql<br>tmpdir = /data/mysql-tmp
,然后迁移数据、同步权限、检查ProtectHomesystemd 保护项是否拦住了新路径。
清理 /tmp 里残留的 MySQL 临时文件(安装失败后)
安装中断后,/tmp 下可能留着 #sql_*、mysql_install_db.*、ibtmp1 碎片等,它们不显示在普通 ls 中(因被进程占用或已删未释放)。
- 先查“幽灵文件”:
lsof +L1或lsof | grep deleted; - 确认无活跃 MySQL 进程后再清理:
sudo find /tmp -name "#sql_*" -mmin +30 -delete; - 不要
rm -rf /tmp/*—— 会误删systemd-private-*.tmp、mysql.sock等关键文件,导致后续服务起不来; -
ibtmp1不在/tmp,而在datadir下,它不能手动删除非停服,且删完必须重启 MySQL 才重建。
真正麻烦的从来不是空间本身,而是 tmpdir 和 datadir 路径混用、权限错配、或 systemd 沙箱限制了新路径访问——这些不会报错,但会让 MySQL 启动失败,且日志里只字不提。











