Python引起了:IOError: [Errno 28] No space left on device: '../results/32766.html',尽管磁盘上有很多空间。

56

我正在运行一个Python脚本,导致出现上述错误。不寻常的是,这个脚本在另一台机器上运行,并且没有任何问题。

不同之处在于,在引起问题的机器上,我正在写入外部硬盘。更奇怪的是,这个脚本已经在有问题的机器上运行,并且已经写入了超过30,000个文件。

一些相关信息(引起错误的代码):

nPage = 0
while nPage != -1:
    for d in data:
        if len(d.contents) > 1:
            if '<script' in str(d.contents):
                l = str(d.contents[1])
                start = l.find('http://')
                end = l.find('>',start)
                out = get_records.openURL(l[start:end])
                print COUNT

                with open('../results/'+str(COUNT)+'.html','w') as f:
                    f.write(out)
                COUNT += 1

    nPage = nextPage(mOut,False)
我正在写入的目录:
10:32@lorax:~/econ/estc/bin$ ll ../
total 56
drwxr-xr-x 3 boincuser boincuser  4096 2011-07-31 14:29 ./
drwxr-xr-x 3 boincuser boincuser  4096 2011-07-31 14:20 ../
drwxr-xr-x 2 boincuser boincuser  4096 2011-08-09 10:38 bin/
lrwxrwxrwx 1 boincuser boincuser    47 2011-07-31 14:21 results -> /media/cavalry/server_backup/econ/estc/results//
-rw-r--r-- 1 boincuser boincuser 44759 2011-08-09 10:32 test.html

证明有足够的空间:

10:38@lorax:~/econ/estc/bin$ df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda1             9.0G  5.3G  3.3G  63% /
none                  495M  348K  495M   1% /dev
none                  500M  164K  500M   1% /dev/shm
none                  500M  340K  500M   1% /var/run
none                  500M     0  500M   0% /var/lock
none                  9.0G  5.3G  3.3G  63% /var/lib/ureadahead/debugfs
/dev/sdc10            466G  223G  244G  48% /media/cavalry

我尝试过的一些事情:

  • 将写入路径更改为直接位置,而不是通过链接
  • 重新启动机器
  • 卸载和重新挂载驱动器

“/media/cavalry” 是什么类型的文件系统?也许您可以发布来自“/proc/mounts”的相关行。您是否只是用完了索引节点? - Sven Marnach
4
如果您包含完整的回溯信息(错误发生在哪一行?),文件系统类型和空闲inode计数(df -i),将会很有帮助。在这种情况下,我怀疑文件系统是vfat,并且您已经超过了目录中文件的最大数量限制。 - Rosh Oxymoron
1
32766 + "." + ".." 可以用于生成 32768 个目录条目。嗯... - wberry
@Rosh 是的,没有更多的索引节点了。有趣。如果你把你的评论发布为一个答案,我可以将其列为选择之一。但我也想知道我能做些什么来纠正这个问题,在vfat系统中如何获取更多关于索引节点的信息。谢谢! - josh
好的,我是想在上一条评论中发布这个:<br>文件系统 Inodes IUsed IFree IUse% 挂载点<br>/dev/sdc10 0 0 0 - /media/cavalry<br>看起来很奇怪,它说根本没有Inodes。肯定是vfat:<br>/dev/sdc10 /media/cavalry vfat rw,nosuid,nodev,noexec,relatime,uid=1001,gid=1001,fmask=0113,dmask=0000,allow_utime=0022,codepage=cp437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro 0 0 - josh
显示剩余2条评论
9个回答

71
ENOSPC(“设备上没有剩余空间”)错误将在任何情况下被触发,其中I/O操作的数据或元数据由于缺少空间而无法写入任何地方。这并不总是指磁盘空间-它可能意味着物理磁盘空间,逻辑空间(例如最大文件长度),某个数据结构中的空间或地址空间。例如,如果目录表(vfat)中没有空间,或者已经没有索引节点,则可能会出现此问题。它大致意味着“我找不到在哪里写下这个”。
特别是在Python中,这可能会发生在任何写入I/O操作中。它可能会在f.write期间发生,但也可能会在openf.flush甚至f.close期间发生。它发生的位置为发生原因提供了重要线索-如果它发生在open上,表示没有足够的空间来写入条目的元数据,如果它在f.writef.flushf.close期间发生,则表示没有足够的磁盘空间或已超过最大文件大小。
如果给定目录中的文件系统是vfat,则您将在大约相同时间达到最大文件限制。该限制应为2^16个目录条目,但如果我记得正确,其他一些因素也可能会影响它(例如某些文件需要多个条目)。
最好避免在一个目录中创建太多的文件。很少有文件系统可以轻松处理如此多的目录条目。除非您确定文件系统可以很好地处理目录中的许多文件,否则可以考虑另一种策略(例如创建更多目录)。
附:也不要相信剩余磁盘空间-一些文件系统为root保留了一些空间,而其他一些文件系统错误计算了可用空间并给出一个不真实的数字。

首先,这是发生在“open”行上的。其次,我的意思是在我的最后一条评论中发布此内容:文件系统Inodes IUsed IFree IUse%已安装 /dev/sdc10 0 0 0 - /media/cavalry。所以,看起来我没有任何Inodes,但也没有使用任何Inodes。至于创建更多目录,那不是有点自相矛盾吗?假设我的树是/estc/results30000/和estc/results60000/。如果我将前30000个放入results30000中,将下一个30000个放入results60000中,则estc/目录仍将拥有太多文件。我也对可用空间感到自信。 - josh
1
我在Python脚本中进行文件写入操作(下载)时遇到了相同的错误。inode和磁盘空间都非常充足。我已经成功地在另一台机器上运行了Python脚本,当我手动将其复制到第一台机器时,复制也成功了。如果问题与超过最大文件大小、最大目录/文件计数或任何其他物理磁盘限制有关,我不明白为什么这样做可以起作用。如果有更多信息,将会帮助我解决这个问题。因为我可能会再次遇到这个问题。 - gvas
2
我遇到了类似的错误,使用Python 3、Jupyter Notebooks、sklearn和RandomForestRegressor(n_jobs=-2)。我认为这是因为一个函数经常使用pickle,但不确定真正的原因。根据这个答案,在Python笔记本中写入%env JOBLIB_TEMP_FOLDER=/tmp,一切都好了。我不确定它在这里是否有用或者是否有人可以扩展。 - Rafael Valero
这是一个很久以前的答案,但我仍然想问一下(不想开一个重复的问题)。在一个循环遍历大量情况的设置中,我在np.save()期间遇到了相同的错误。在大约1.5k次迭代后出现了错误,并且磁盘上还剩下150GB,所以我不知道该怎么处理它。 - Puff
我想添加另一个我遇到的ENOSPC潜在原因。我在托管的Linux实例上工作,并且'home'目录有一个硬限制的配额。Conda使用/.conda存储软件包。最终,我无法使用'conda create ...',因为它会给出“设备上没有剩余空间”的消息,但没有指示出错的原因。磁盘空间、inode等都看起来很好。只有当我尝试'conda init'时,我的/.bashrc被截断时,我才弄清楚这一点。清除~/.conda软件包可以解决问题。 - Wesley R. Elsberry
那么我该如何解决这个问题呢? - Byusa

24

尝试删除临时文件

rm -r /tmp/

35
危险的cd命令后紧跟着rm的用法。 - Gert van den Berg
11
这个答案并没有得到足够的重视。其他答案基本上在说:“垃圾太多了?换个大垃圾桶!” 而这个答案则是在清理垃圾。 - Benjamin James
1
有没有一种方法可以回答所有询问我是否确定的问题,说“是”的呢? - Akin Hwan
这是所有答案中最好的。注意:在Ubuntu中,最好的做法是为每个Temp目录提供yes/no y或n,以避免删除其他用户的文件/目录! - Vetrivel PS

10

事实证明,对我来说最好的解决方案就是重新格式化驱动器。一旦重新格式化,所有这些问题都不再存在。


5
我有同样的问题。如果人们能在他们的负评中留下解释就好了。 - josh
8
这里问题的原因似乎在于i节点/目录项...(并且似乎是vfat特有的)。如果不看评论,这在问题中并不明显。(此答案主要提供了一种解决方法,但在许多情况下并不实用...)您还没有指定它是否再次使用vfat格式化,还是使用了其他文件系统... - Gert van den Berg
3
你不能总是重新格式化。重新格式化总是一个显而易见的解决方案。难道你不需要保留设备上的数据吗?这就是downvote的原因。 - georgesjeandenis
1
@josh 请解释一下你如何“重新格式化”驱动器。 - DialFrost

8
  1. 显示内存分配情况:sudo du -x -h / | sort -h | tail -40
  2. 如果 /tmp/home/user_name/.cache 占用了大量内存,可以通过运行 sudo rm -R /path/to/folder 来从这些文件夹中删除文件。

步骤2概述了常见的要删除的文件夹(/tmp/home/user_name/.cache)。 如果第一个命令返回其他占用大量内存的文件夹,则建议在删除这些位置的文件时更加谨慎。


5
在我的情况下,当我运行df -i时,它显示我的索引节点数量已满,然后我必须删除一些小文件或文件夹。否则,一旦inode占满,就无法创建文件或文件夹。
你所需要做的就是删除未占用全部空间但填充了inodes的文件或文件夹。

4

在某个有效的目录(非/tmp)中执行命令"export TEMPDIR=/someDir"。在运行Python命令之前,请在提示符上运行此命令。在我的情况下,是"pip install rasa[spacy]",之前它一直失败。

export命令允许您临时使用指定的目录作为临时目录。


6
我认为应该是TMPDIR,而不是TEMPDIR,参考https://docs.python.org/3/library/tempfile.html#tempfile.mkstemp - 另外,显然也会检查TEMP和TMP。 - Gord Stephen

0
我有同样的问题,但最终发现根本原因是“打印太频繁”。在我的代码中,我有一些在循环中运行的“print(...)”逻辑。当我注释掉这些代码时,“设备上没有剩余空间”的错误消失了。也许这是Python实现的问题。你可以尝试这个解决方案。
更详细的信息,示例描述性代码将如下所示:
loop:
    do some logic 
    call "print" to check result

当你的逻辑代码运行非常快时,你会非常频繁地调用“print”函数。有时候会出现“[Errno 28] No space left on device”的错误。
我认为这是Python“print”代码的实现限制,尽管我还没有阅读过代码。我的Python版本是3.9.7。
感谢社区的回复。

3
您的答案可以通过添加更多支持信息来改进。请[编辑]以增加进一步的细节,例如引用或文档,以便其他人可以确认您的答案是否正确。您可以在帮助中心找到有关如何撰写好答案的更多信息。 - Community

0

在运行测试时,我遇到了这个问题。我正在运行的Django应用程序位于docker容器内,因此我必须以root身份登录到容器中,运行rm -r /tmp/,然后问题得到解决。


0

我遇到了类似的问题。上述删除 /tmp 目录的解决方案对我有用。

我将 /tmp 目录移动到用户的主目录中,使用 TMPDIR 环境设置来执行 pip install --user ... 命令,而不是使用默认的 /tmp 位置(如果遵循最佳实践并不使用 sudo 安装 Python 包,则服务帐户可能没有完全访问权限)。

如上所述,我遇到了空间不足的问题,这很可能是由于创建了太多的文件/目录而不是实际上用尽了卷存储空间。对我有效的解决方案是每次运行我的持续部署流水线时删除 /home/<some_domain>/$USER/tmp 目录并重新创建它。rm -rf /tmp


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接