当设备有足够的空间时,如何解决mv期间出现的间歇性“设备上没有剩余空间”错误?


21
  • 台式机上的Ubuntu 14.04
  • 源驱动器:/ dev / sda1:5TB ext4单
    驱动器卷
  • 目标卷:/ dev / mapper / archive-lvarchive:raid6(mdadm)带有lvm
    分区和ext4的18TB卷

大约有1500万个文件要移动,有些可能是重复的(我不想覆盖重复的文件)。

使用的命令(从源目录)为:

ls -U |xargs -i -t mv -n {} /mnt/archive/targetDir/{}

正如预期的那样,这种情况已经持续了几天,但是我在增加频率方面遇到了错误。启动时,目标驱动器已满约70%,现在已达到90%。它曾经是状态和错误的大约1/200,现在大约是1/5。没有文件超过100Mb,大多数文件都在10万左右

一些信息:

$ df -h
Filesystem                     Size  Used Avail Use% Mounted on
/dev/sdb3                      155G  5.5G  142G   4% /
none                           4.0K     0  4.0K   0% /sys/fs/cgroup
udev                           3.9G  4.0K  3.9G   1% /dev
tmpfs                          797M  2.9M  794M   1% /run
none                           5.0M  4.0K  5.0M   1% /run/lock
none                           3.9G     0  3.9G   0% /run/shm
none                           100M     0  100M   0% /run/user
/dev/sdb1                       19G   78M   18G   1% /boot
/dev/mapper/archive-lvarchive   18T   15T  1.8T  90% /mnt/archive
/dev/sda1                      4.6T  1.1T  3.3T  25% /mnt/tmp

$ df -i
Filesystem                       Inodes    IUsed     IFree IUse% Mounted on
/dev/sdb3                      10297344   222248  10075096    3% /
none                            1019711        4   1019707    1% /sys/fs/cgroup
udev                            1016768      500   1016268    1% /dev
tmpfs                           1019711     1022   1018689    1% /run
none                            1019711        5   1019706    1% /run/lock
none                            1019711        1   1019710    1% /run/shm
none                            1019711        2   1019709    1% /run/user
/dev/sdb1                       4940000      582   4939418    1% /boot
/dev/mapper/archive-lvarchive 289966080 44899541 245066539   16% /mnt/archive
/dev/sda1                     152621056  5391544 147229512    4% /mnt/tmp

这是我的输出:

mv -n 747265521.pdf /mnt/archive/targetDir/747265521.pdf 
mv -n 61078318.pdf /mnt/archive/targetDir/61078318.pdf 
mv -n 709099107.pdf /mnt/archive/targetDir/709099107.pdf 
mv -n 75286077.pdf /mnt/archive/targetDir/75286077.pdf 
mv: cannot create regular file ‘/mnt/archive/targetDir/75286077.pdf’: No space left on device
mv -n 796522548.pdf /mnt/archive/targetDir/796522548.pdf 
mv: cannot create regular file ‘/mnt/archive/targetDir/796522548.pdf’: No space left on device
mv -n 685163563.pdf /mnt/archive/targetDir/685163563.pdf 
mv -n 701433025.pdf /mnt/archive/targetDir/701433025.pd

我发现有很多关于此错误的帖子,但预后并不理想。诸如“您的驱动器实际上已满”或“您的inode耗尽”甚至“您的/ boot卷已满”之类的问题。不过,大多数情况下,它们处理的是第三方软件,因为它处理文件的方式会引起问题,而且它们都是恒定的,这意味着每次移动都会失败。

谢谢。

编辑:这是一个示例失败和成功的文件:

失败(仍在源驱动器上)

ls -lhs 702637545.pdf
16K -rw-rw-r-- 1 myUser myUser 16K Jul 24 20:52 702637545.pdf

成功(达到目标音量)

ls -lhs /mnt/archive/targetDir/704886680.pdf
104K -rw-rw-r-- 1 myUser myUser 103K Jul 25 01:22 /mnt/archive/targetDir/704886680.pdf

同样,虽然并非所有文件都失败,但是失败的文件将始终失败。如果我一遍又一遍地重试是一致的。

编辑:@mjturner每个请求的一些其他命令

$ ls -ld /mnt/archive/targetDir
drwxrwxr-x 2 myUser myUser 1064583168 Aug 10 05:07 /mnt/archive/targetDir

$ tune2fs -l /dev/mapper/archive-lvarchive
tune2fs 1.42.10 (18-May-2014)
Filesystem volume name:   <none>
Last mounted on:          /mnt/archive
Filesystem UUID:          af7e7b38-f12a-498b-b127-0ccd29459376
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr dir_index filetype needs_recovery extent 64bit flex_bg sparse_super huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              289966080
Block count:              4639456256
Reserved block count:     231972812
Free blocks:              1274786115
Free inodes:              256343444
First block:              0
Block size:               4096
Fragment size:            4096
Group descriptor size:    64
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         2048
Inode blocks per group:   128
RAID stride:              128
RAID stripe width:        512
Flex block group size:    16
Filesystem created:       Thu Jun 25 12:05:12 2015
Last mount time:          Mon Aug  3 18:49:29 2015
Last write time:          Mon Aug  3 18:49:29 2015
Mount count:              8
Maximum mount count:      -1
Last checked:             Thu Jun 25 12:05:12 2015
Check interval:           0 (<none>)
Lifetime writes:          24 GB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:           256
Required extra isize:     28
Desired extra isize:      28
Journal inode:            8
Default directory hash:   half_md4
Directory Hash Seed:      3ea3edc4-7638-45cd-8db8-36ab3669e868
Journal backup:           inode blocks

$ tune2fs -l /dev/sda1
tune2fs 1.42.10 (18-May-2014)
Filesystem volume name:   <none>
Last mounted on:          /mnt/tmp
Filesystem UUID:          10df1bea-64fc-468e-8ea0-10f3a4cb9a79
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              152621056
Block count:              1220942336
Reserved block count:     61047116
Free blocks:              367343926
Free inodes:              135953194
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      732
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         4096
Inode blocks per group:   256
Flex block group size:    16
Filesystem created:       Thu Jul 23 13:54:13 2015
Last mount time:          Tue Aug  4 04:35:06 2015
Last write time:          Tue Aug  4 04:35:06 2015
Mount count:              3
Maximum mount count:      -1
Last checked:             Thu Jul 23 13:54:13 2015
Check interval:           0 (<none>)
Lifetime writes:          150 MB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:           256
Required extra isize:     28
Desired extra isize:      28
Journal inode:            8
Default directory hash:   half_md4
Directory Hash Seed:      a266fec5-bc86-402b-9fa0-61e2ad9b5b50
Journal backup:           inode blocks

这些文件是否已被复制到多个目录,或者您正在尝试将1.5M文件写入单个目标目录?
史努比2015年

不是1.5m,15m,是的,都放在同一目录中。实际上,那里已经超过了4,000万,总共还有3000万。
克里斯·考德威尔(Chris.Caldwell)

哦,瞧,随机降落的巨魔再次袭击了。我猜你不会提起为什么投票?
克里斯·考德威尔(Chris.Caldwell)

1
投反对票的原因可能是您的问题更适合Unix.stackexchange或askubuntu,因为它与编程无关。如果您的代码中没有编程语言,则可能会遭到拒绝。
technosaurus

@克里斯-似乎类似于在SF这个问题: serverfault.com/questions/384541/...
史努比

Answers:


25

dir_index目标文件系统上使用的ext4功能实现中的错误。

解决方案:重新创建没有dir_index的filesytem。或使用tune2fs禁用功能(需要注意一些事项,请参阅相关链接Novell SuSE 10/11:在ext3文件系统上禁用H-Tree索引,尽管与ext3有关可能也需要类似的注意事项。

(get a really good backup made of the filesystem)
(unmount the filesystem)
tune2fs -O ^dir_index /dev/foo
e2fsck -fDvy /dev/foo
(mount the filesystem)

ext4具有默认情况下启用的名为dir_index的功能,该功能很容易受到哈希冲突的影响。

......

ext4可以散列其内容的文件名。这样可以提高性能,但是存在一个“小”问题:ext4开始填充时,不会扩展其哈希表。而是返回-ENOSPC或“设备上没有剩余空间”。


3
哦,废话,听起来很像,而且完全像是要​​解决的痛苦。它大约一个月要复制。可以做到而又不会丢失内容吗?明天我不得不研究dir_index等。哇,永远不会想到这一点。
克里斯·考德威尔(Chris.Caldwell)

添加了tune2fs命令以禁用索引,以备您尝试。
史蒂夫

6
好发现@steve。不幸的是,关闭该dir_index文件可能会破坏一个目录中70m文件的访问性能。
mjturner

3
是的 我不需要峰值性能,但是对每个文件进行fs搜索将是可怕的。因此,现在我正在查看xfs或10k左右的子文件夹数组。子文件夹是一个合理的解决方案,但是使用ext4,我仍然有发生冲突的风险。xfs是否会遇到相同的问题?我读过它使用的是B +树,但对我而言,这对确保永不发生冲突没有多大意义。那里存在着一个错误的信息世界,Ive听说它声称在超过一百万个文件时会大大降低速度,并声称不会。
克里斯·考德威尔(Chris.Caldwell),2015年

2
我认为这是一个很好的答案,我希望将其标记为这样,但是我认为如果我们能够解决问题,而不仅仅是诊断,那就太好了。有谁知道xfs是否患有这种疾病?香港专业教育学院阅读过的混合评论,它可以很好地缩放,或不超过1m。
克里斯·考德威尔(Chris.Caldwell),2015年

8

有关存储大量小文件的优于ext4的建议:

如果将文件系统用作对象存储,则可能需要考虑使用专门用于此目的的文件系统,这可能会损害其他特性。Google进行了快速搜索,发现Ceph似乎是开源的,可以作为POSIX文件系统挂载,也可以使用其他API进行访问。我不知道在不利用复制的情况下在一台主机上使用是否值得。

另一个对象存储系统是OpenStack的Swift。它的设计文档说,它将每个对象存储为一个单独的文件,元数据存储在xattrs中。这是一篇关于它的文章。 他们的部署指南说,他们发现XFS为对象存储提供了最佳性能。因此,即使工作负载不是XFS所擅长的,但它显然比RackSpace测试事物时的竞争对手要好。可能Swift赞成XFS,因为XFS对扩展属性具有良好/快速的支持。如果不需要额外的元数据(或者如果将其保存在二进制文件中),则ext3 / ext4可以在单个磁盘上作为对象存储后端正常运行。

Swift为您执行复制/负载平衡,并建议您为其提供在原始磁盘(而非RAID)上创建的文件系统。它指出,对于RAID5,它的工作量基本上是最坏的情况(如果我们谈论的是写小文件的工作量,这是有道理的。XFS通常不会完全将它们打包在一起,因此您不必RAID5需要进行全读操作以更新奇偶校验条带。Swift文档还讨论了每个驱动器使用100个分区。我认为这是一个Swift术语,并不是要在每个驱动器上创建100个不同的XFS文件系统。 SATA磁盘。

实际上,为每个磁盘运行单独的XFS会有很大的不同。每个磁盘将具有单独的XFS和单独的自由列表,而不是一个巨大的自由节点图。而且,它避免了小写操作对RAID5的影响。

如果您已经构建了将文件系统直接用作对象存储的软件,而不是通过诸如Swift之类的方法来处理复制/负载平衡,那么至少可以避免将所有文件放在一个目录中。(我没有看到Swift文档说他们如何将文件布置到多个目录中,但是我敢肯定他们会这样做。)

在几乎所有普通文件系统中,使用类似

1234/5678   # nested medium-size directories instead of
./12345678   # one giant directory

大约1万个条目可能是合理的,因此采用分布良好的4个字符的对象名称并将其用作目录是一个简单的解决方案。它不必非常平衡。奇数的100k目录可能不会引起明显的问题,某些空目录也不会。

XFS对于大量的小文件不是理想的选择。它会尽其所能,但针对流式传输较大文件进行了更优化。总体而言,这是非常好的。它ENOSPC的目录索引(AFAIK)没有冲突,并且可以处理一个包含数百万个条目的目录。(但最好至少使用一棵树。)

Dave Chinner 对XFS性能发表了一些评论,其中分配了大量的inode,导致touch性能缓慢。随着空闲索引节点位图的碎片化,找到要分配的空闲索引节点开始会花费更多的CPU时间。请注意,这不是一个大目录还是多个目录的问题,而是整个文件系统上许多已使用的inode的问题。将文件拆分为多个目录可以解决某些问题,例如ext4在OP中阻塞的目录,但对于跟踪可用空间的整个磁盘问题却无济于事。与RAID5上的巨型XFS相比,Swift的每个磁盘独立文件系统对此有所帮助。

我不知道btrfs是否擅长于此,但我认为可能是。我认为Facebook雇用其主要开发人员是有原因的。:P我见过的一些基准测试(例如,释放Linux内核源代码)显示btrfs效果很好。

我知道reiserfs已针对这种情况进行了优化,但几乎不再维护了。我真的不建议与reiser4一起使用。不过,进行实验可能会很有趣。但这是迄今为止最不适合未来的选择。我还看到过有关过时的reiserFS性能下降的报告,并且没有良好的碎片整理工具。(google filesystem millions of small files,并查看一些现有的stackexchange答案。)

我可能丢失了一些东西,所以最后建议:在serverfault上询问一下! 如果我现在必须选择一些东西,我会说尝试一下BTRFS,但要确保您有备份。(尤其是,如果您使用BTRFS的内置多磁盘冗余,而不是在RAID之上运行它,则性能优势可能很大,因为小文件对于RAID5来说是个坏消息,除非这是大部分工作量。)


1
非常感谢。我见过很多人使用子文件夹,事实上,几年前,我在不同的设置中使用了这种解决方案,但我希望避免使用另一种解决方案。这样做的开销似乎要比找到一个仅用于此目的的fs少得多。回复:XFS,令人惊讶的是,由于经常给出下跪的回答,因此它在处理大量文件方面如此糟糕。BTRFS,Wiki:“目录条目显示为目录项,其右键值为其文件名的CRC32C哈希值”。我们有同样的问题吗?
克里斯·考德威尔(Chris.Caldwell)

@ Chris.Caldwell:您必须检查一下,但我认为BTRFS通过支持同一哈希存储区(而不是ENOSPC)中的多个条目来处理哈希冲突。您是否考虑过将资料保存在数据库中,而不是在文件系统中保存单独的文件?我从来没有建立过处理此类数据的系统。我使用XFS,这非常适合我用于存储的内容(存储视频以及通用Unix源代码和东西。)
Peter Cordes

1
设计文件系统的方式,目录级别的开销较小。在小型表中进行两次快速查找要比在溢出表中进行一次慢速查找要快得多,该表存储的数据超出了优化的范围。就像我说的那样,您不必在目录之间完美地分布文件,因此您只需输入文件名的前4个字符,然后插入即可/。希望这不会影响您的代码中的太多地方。(如果创建新文件失败,则必须确保创建目录ENOENT)。询问serverfault是否还有其他文件系统。
彼得·科德斯

@ Chris.Caldwell:我真的应该将此答案复制到一个与之相关的问题上。有一些现有的。我很好奇应该将什么用于对象存储,并找到了一些有关Swift的文档。显然,它将对象存储为XFS上的单独文件(但每个磁盘都有一个单独的XFS,而不是RAID。它本身处理冗余)。
彼得·科德斯

1

对于此问题,以下是我所做的修复(以下步骤可能需要sudo访问):

  1. Inode的已用空间为100%,可使用以下命令检索

    df -i /

文件系统索引节点IUse IFree IUse%Mounted on

/dev/xvda1            524288   524288  o     100% /
  1. 需要释放iNoted,因此需要使用以下命令查找具有i个节点数量的文件:

尝试查找这是否是inode的问题:

df -ih

尝试查找具有大inode数量的根文件夹:

for i in /*; do echo $i; find $i |wc -l; done

尝试查找特定的文件夹:

for i in /src/*; do echo $i; find $i |wc -l; done
  1. 现在我们已经归零到其中包含大量文件的文件夹。一个接一个地运行以下命令以避免任何错误(在我的情况下,实际文件夹为/ var / spool / clientmqueue):
find /var/spool/clientmqueue/ -type f -mtime +1050 -exec rm -f {} +

find /var/spool/clientmqueue/ -type f -mtime +350 -exec rm -f {} +

find /var/spool/clientmqueue/ -type f -mtime +150 -exec rm -f {} +

find /var/spool/clientmqueue/ -type f -mtime +50 -exec rm -f {} +
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.