MySQL错误1021的完整提示通常为 Can't create/write to file 'xxx' (errno: 28)。它并不只在建立连接时出现,更多发生在连接之后执行查询、排序、建索引、导入数据等操作中。错误本质是MySQL服务进程需要向文件系统写入数据,但操作系统拒绝了这个写入请求。被写入的文件可能是临时表、排序缓冲区溢出文件、二进制日志、InnoDB重做日志或备份文件。要处理这个错误,核心不是修改连接参数,而是找到无法写入的目录和文件,并解决操作系统层面的限制。

一、错误1021的触发场景与底层原因
MySQL错误1021通常伴随一个具体的文件路径和errno编号。理解errno的含义可以快速缩小排查范围。常见的errno值包括:13表示Permission denied,即权限不足;28表示No space left on device,即磁盘空间或inode耗尽;24表示Too many open files,即文件句柄打开过多;30表示Read-only file system,即文件系统只读;2表示No such file or directory,即父目录不存在。不同的errno对应完全不同的处理方向,因此第一步应该查看错误日志中的完整错误行,而不是只盯着1021这个代码。
从MySQL内部机制来看,很多SQL操作会隐式使用磁盘文件。比如执行带有ORDER BY的大结果集查询时,如果排序缓冲区放不下数据,MySQL会在tmpdir目录创建临时文件;使用GROUP BY或DISTINCT可能生成临时表;LOAD DATA INFILE会直接写数据文件;ALTER TABLE重建表时会创建.frm或.ibd中间文件。这些文件写入失败时,MySQL就会抛出错误1021。因此,错误可能在连接正常的情况下突然出现,并且通常与某类重量级SQL操作绑定。
还有一种场景是InnoDB表空间或redo log所在磁盘已满,此时事务提交、Checkpoint刷新脏页都可能触发写入失败。虽然提示中说Can't create/write to file,但实际无法写入的文件可能是ib_logfile0、ibdata1或某个.ibd文件。这种情况更严重,可能导致整个实例不可用。因此处理错误1021时,不能只盯着tmpdir,还要检查数据目录和日志目录所在分区。
二、排查步骤:从磁盘空间到文件权限
第一步是确认MySQL记录的具体文件路径和errno。可以通过查看错误日志获取完整信息。登录MySQL执行SHOW VARIABLES LIKE 'log_error'可以看到错误日志文件位置,再用tail命令查看最后几十行。如果错误日志里只有简化的Can't create/write to file,缺少文件路径,可以临时开启general_log或者通过strace跟踪MySQL进程的系统调用,但这属于进阶手段。对于大多数场景,直接检查常见目录通常能发现问题。
第二步检查磁盘空间和inode使用率。使用df -h查看各分区剩余容量,使用df -i查看inode使用情况。有些文件系统即使剩余空间充足,但inode耗尽也会导致无法创建新文件。例如一个小文件很多的/tmp分区,inode用完后会报errno 28。可以执行以下命令快速确认:
# 查看磁盘空间 df -h # 查看inode使用率 df -i # 查看MySQL数据目录占用 du -sh /var/lib/mysql # 查看tmp目录占用 du -sh /tmp
第三步检查MySQL运行账号对相关目录的写权限。MySQL服务通常以mysql用户运行,但容器或部分发行版可能使用其他账号。先执行ps aux | grep mysqld确认运行用户,再使用ls -ld /tmp /var/lib/mysql查看目录所有者与权限。如果tmpdir被错误设置为只有root可写的目录,或者数据目录权限被批量修改为不可写,MySQL就会报errno 13。可以用以下命令模拟写入测试:
# 确认MySQL运行用户 ps aux | grep mysqld # 查看目录权限 ls -ld /tmp /var/lib/mysql # 以mysql用户测试写入 sudo -u mysql touch /tmp/mysql_write_test # 测试后删除 sudo -u mysql rm -f /tmp/mysql_write_test
第四步检查挂载属性和系统安全策略。执行mount | grep -E ' /tmp | /var/lib/mysql '查看分区是否被挂载为只读,或者在磁盘故障时被内核切换为只读。对于SELinux或AppArmor环境,需要确认策略是否允许MySQL写入tmpdir和数据目录。可以执行getenforce查看SELinux状态,如果为Enforcing,可以临时执行setenforce 0测试是否恢复,但生产环境建议用audit2allow生成正确的策略,而不是直接关闭。
三、修复方案:快速恢复与长期预防
最直接的修复是释放磁盘空间。先定位大文件目录,比如du -h --max-depth=1 /var/lib/mysql | sort -rh | head -20可以找出数据目录下最大的目录。常见可清理对象包括过期的二进制日志、慢查询日志、错误日志、备份文件以及tmpdir下残留的临时文件。二进制日志可以通过PURGE BINARY LOGS BEFORE NOW() - INTERVAL 3 DAY删除三天前的日志,也可以使用expire_logs_days参数自动清理。删除文件后不需要重启MySQL,但若错误已经导致表损坏,需要执行CHECK TABLE和REPAIR TABLE确认数据一致性。
如果权限问题导致错误,需要修复目录所有者和权限。数据目录通常应归属MySQL运行用户,权限一般为750或755。tmpdir如果使用系统/tmp,权限应保持1777,或改为MySQL账号可写的专用目录。比如创建/data/mysql_tmp,执行mkdir -p /data/mysql_tmp && chown mysql:mysql /data/mysql_tmp && chmod 750 /data/mysql_tmp,然后在MySQL配置文件中设置tmpdir=/data/mysql_tmp。配置修改后需要重启MySQL生效。这样可以把临时文件从系统盘迁移到独立分区,避免根分区被占满影响整个操作系统。
长期预防方面,建议把tmpdir、数据目录、日志目录分别放在不同分区,并对磁盘空间和inode设置监控告警。MySQL提供了多个状态变量帮助判断临时表落盘情况,例如SHOW GLOBAL STATUS LIKE 'Created_tmp%'可以看到创建临时表的总数和落盘数量。如果落盘比例过高,可以增大tmp_table_size和max_heap_table_size,让更多临时表在内存中完成,但也不宜过大,否则会挤占Buffer Pool。更稳妥的做法是优化触发临时表落盘的SQL,比如为排序字段创建索引,避免SELECT *加ORDER BY组合。
四、实战示例:定位并处理tmpdir不可写引发的1021
下面通过一个典型场景展示完整处理过程。某台MySQL服务器在执行一张千万级表的统计查询时,应用日志出现错误:Can't create/write to file '/tmp/MYxxxx' (errno: 13 - Permission denied)。首先确认错误文件在/tmp目录,errno为13,说明是权限不足而非空间不足。接着查看/tmp目录权限,发现管理员之前为了安全将/tmp权限从1777改为755,所有者是root,导致mysql用户无法写入。
处理命令如下:
# 查看当前权限 ls -ld /tmp # 恢复系统临时目录标准权限 chmod 1777 /tmp # 验证mysql用户可写 sudo -u mysql touch /tmp/mysql_test_1021 # 清理测试文件 sudo -u mysql rm -f /tmp/mysql_test_1021
执行完成后,重新运行之前的统计查询,错误消失。但为了避免系统/tmp与业务争抢空间,进一步将MySQL临时目录迁移到专用分区。先创建目录并授权:
mkdir -p /data/mysql_tmp chown mysql:mysql /data/mysql_tmp chmod 750 /data/mysql_tmp
然后修改MySQL配置文件/etc/my.cnf,在[mysqld]段增加或修改:
[mysqld] tmpdir=/data/mysql_tmp
重启MySQL后,执行SHOW VARIABLES LIKE 'tmpdir'确认生效。此时再创建的大临时文件都会写入/data/mysql_tmp,不再影响根分区。该案例说明,错误1021的处理重点在于从errno和文件路径反推操作系统限制,而不是修改连接超时或重试参数。
五、总结与建议
处理MySQL错误1021时,最忌讳只看到Can't create/write to file就盲目重启服务或重装数据库。错误代码本身只是结果,errno和文件路径才是原因。先确认errno值,再按照磁盘空间、inode、权限、挂载只读、文件句柄、安全策略的顺序排查,可以在几分钟内定位问题。对于高频出现的大查询,建议从SQL优化角度减少临时文件生成,既提升响应速度也降低磁盘写入压力。
最后,如果MySQL运行在容器或云托管环境中,还需要关注容器基础镜像的tmpfs挂载限制、Kubernetes emptyDir容量限制以及云盘I/O配额。这些外部约束同样会以错误1021的形式表现出来。建立完善的监控和日志收集体系,配合定期清理和容量规划,才能从根本上减少文件写入失败带来的业务中断。
MySQL错误1021文件写入失败磁盘空间不足修改时间:2026-08-26 18:47:52