ExpressJs视频上传应用遇ENOSPC错误,清理tmp文件仍无法解决
看起来你遇到的这个问题有点棘手——明明已经切换到AWS存储,却还是碰到了磁盘空间不足的报错,而且清理tmp文件也没效果。我来帮你梳理几个可能的原因和对应的排查、解决方法:
1. 检查inode是否耗尽
有时候磁盘的实际空间还剩不少,但inode(文件索引节点)用完了也会触发ENOSPC错误。你可以用这个命令快速排查:
df -i
如果某个分区的IUse%显示100%,那就是inode耗尽了。解决办法是删除目录里的大量细碎文件(比如日志缓存、临时生成的小文件),如果是临时目录的问题,也可以考虑挂载一个新的分区专门用于临时文件存储。
2. 确认Express上传中间件的临时存储配置
如果你用的是multer这类主流上传中间件,默认会先把视频缓存到本地临时目录,再处理上传到AWS的逻辑——哪怕最终文件存在AWS,这个本地缓存步骤没配置对,还是会占满磁盘。
检查你的multer配置:
- 是不是用了
diskStorage却没指定空间充足的临时目录? - 上传完成后有没有自动删除本地缓存文件?
可以改成指定大空间目录存储缓存,并且在上传完成(或失败)后手动清理:
const multer = require('multer'); const fs = require('fs'); // 指定空间充足的临时目录 const storage = multer.diskStorage({ destination: (req, file, cb) => cb(null, '/path/to/large-storage/temp'), filename: (req, file, cb) => cb(null, `${file.fieldname}-${Date.now()}`) }); const upload = multer({ storage }); app.post('/upload', upload.single('video'), async (req, res) => { try { // 执行AWS上传逻辑 await uploadToAWS(req.file.path); // 上传成功后删除本地缓存 fs.unlinkSync(req.file.path); res.send('上传成功'); } catch (err) { // 出错也要清理缓存,避免残留 if (req.file?.path) fs.unlinkSync(req.file.path); res.status(500).send(err.message); } });
如果视频体积不大,也可以尝试用内存存储替代磁盘缓存(multer.memoryStorage()),但要注意服务器内存容量限制。
3. 排查系统临时目录的实际使用情况
你清理了tmp文件,但可能系统的临时目录不是/tmp?或者有些进程在占用临时文件没释放?
先查看临时目录的空间使用:
df -h /tmp
如果还是满的,找一下里面的大文件:
find /tmp -type f -size +100M | sort -n -r
确认这些大文件是不是上传残留的,手动删除即可。如果你的应用跑在容器里,还要注意容器的tmp目录是否有配额限制,必要时调整容器的存储配置。
4. 检查AWS上传环节的本地缓存
有些AWS SDK的分片上传功能,默认会把分片文件存在本地磁盘——如果上传的视频很大,这些分片会快速占满空间。建议改成流式上传,直接把文件流传到AWS,避免本地缓存整个文件:
const { S3Client, PutObjectCommand } = require("@aws-sdk/client-s3"); const fs = require('fs'); const s3Client = new S3Client({ region: '你的AWS区域' }); // 流式上传,无需本地缓存整个文件 const uploadToAWS = async (filePath, bucketName, objectKey) => { const fileStream = fs.createReadStream(filePath); const command = new PutObjectCommand({ Bucket: bucketName, Key: objectKey, Body: fileStream }); await s3Client.send(command); };
5. 检查服务器其他挂载分区
有时候根目录空间充足,但其他挂载分区(比如/var、/home)满了?用df -h查看所有分区的使用率,确认有没有其他分区达到100%。比如/var/log目录如果堆满了旧日志,也会导致磁盘空间不足,这时候需要清理旧日志或者配置日志自动轮转。
内容的提问来源于stack exchange,提问作者Yinka

