尽管在btrfs上有足够的空间,但“设备上没有剩余空间”错误


17

几乎到处我都在抱怨日志失败 No space left on device

Gitlab日志:

==> /var/log/gitlab/nginx/current <==
2016-11-29_20:26:51.61394 2016/11/29 20:26:51 [emerg] 4871#0: open() "/var/opt/gitlab/nginx/nginx.pid" failed (28: No space left on device)

Dovecot电子邮件日志:

Nov 29 20:28:32 aws-management dovecot: imap(email@www.sitename.com): Error: open(/home/vmail/emailuser/Maildir/dovecot-uidlist.lock) failed: No space left on device

输出 df -Th

Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/xvda1     ext4      7.8G  3.9G  3.8G  51% /
devtmpfs       devtmpfs  1.9G   28K  1.9G   1% /dev
tmpfs          tmpfs     1.9G   12K  1.9G   1% /dev/shm
/dev/xvdh      btrfs      20G   13G  7.9G  61% /mnt/durable
/dev/xvdh      btrfs      20G   13G  7.9G  61% /home
/dev/xvdh      btrfs      20G   13G  7.9G  61% /opt/gitlab
/dev/xvdh      btrfs      20G   13G  7.9G  61% /var/opt/gitlab
/dev/xvdh      btrfs      20G   13G  7.9G  61% /var/cache/salt

看起来还有足够的inode空间。输出df -i

Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/xvda1     524288 105031 419257   21% /
devtmpfs       475308    439 474869    1% /dev
tmpfs          480258      4 480254    1% /dev/shm
/dev/xvdh           0      0      0     - /mnt/durable
/dev/xvdh           0      0      0     - /home
/dev/xvdh           0      0      0     - /opt/gitlab
/dev/xvdh           0      0      0     - /var/opt/gitlab
/dev/xvdh           0      0      0     - /var/cache/salt

输出 btrfs fi show

Label: none  uuid: 6546c241-e57e-4a3f-bf43-fa933a3b29f9
        Total devices 4 FS bytes used 11.86GiB
        devid    1 size 10.00GiB used 10.00GiB path /dev/xvdh
        devid    2 size 10.00GiB used 9.98GiB path /dev/xvdi
        devid    3 size 10.00GiB used 9.98GiB path /dev/xvdj
        devid    4 size 10.00GiB used 9.98GiB path /dev/xvdk

输出 btrfs fi df /mnt/durable

Data, RAID10: total=17.95GiB, used=10.12GiB
Data, single: total=8.00MiB, used=0.00
System, RAID10: total=16.00MiB, used=16.00KiB
System, single: total=4.00MiB, used=0.00
Metadata, RAID10: total=2.00GiB, used=1.74GiB
Metadata, single: total=8.00MiB, used=0.00
unknown, single: total=272.00MiB, used=8.39MiB

这可能是什么原因?我正在使用基本Linux AMI ec2内核版本4.4.5-15.26.amzn1.x86_64

更新资料

运行以下建议的命令,btrfs fi balance start -dusage=5 /mnt/durable使我返回以下错误:

ERROR: error during balancing '/mnt/durable' - No space left on device There may be more info in syslog - try dmesg | tail

手动删除一堆总计约1GB的较大文件后,我重新启动了计算机并再次尝试,确保我使用的是sudo,并执行了命令。然后,我再次以良好的方式重新启动了计算机,似乎已经解决了问题


您有任何配额设置吗?
Zoredache

通用工具无法正确理解BTRFS,您需要特定于BTRFS的工具。请添加“ btrfs fi show”和“ btrfs fi df / mnt / durable”的输出
Peter Green

@PeterGreen添加了btrfs的输出...看起来像您找到了罪魁祸首。
奥斯汀

您还可以添加我建议的第二条命令的输出吗?
彼得·格林

2
内核版本在这里非常重要,因为btrfs过去在自由空间方面存在很多问题,如果这是另一种情况,将来的读者可以从该信息中受益。
PlasmaHH

Answers:


19

欢迎来到BTRFS的世界。它具有一些诱人的功能,但也有一些令人毛骨悚然的问题。

首先,关于设置的一些信息,看起来您在BTRFS“ raid 10”卷中有四个驱动器(因此所有数据两次存储在不同的磁盘上)。然后,将此BTRFS卷划分为不同安装点上的子卷。子卷共享一个磁盘空间池,但是具有单独的inode编号,可以安装在不同的位置。

BTRFS以“块”形式分配空间,将块分配给特定类别的数据或元数据。可能发生的事情(在您的情况下似乎已经发生)是所有可用空间都分配给了数据块,没有元数据的空间

似乎(出于我尚未完全理解的原因),BTRF在元数据空间使用比例指标达到100%之前“耗尽”了元数据空间。

这似乎是您的情况,已经有很多可用数据空间,但是没有未分配给块的可用空间,而现有元数据块中的可用空间不足。

解决方法是运行“重新平衡”。这将移动数据,以便可以将某些块返回到“全局”空闲池,在其中可以将它们重新分配为元数据块

btrfs fi balance start -dusage=5 /mnt/durable

后面的数字-dusage设置了重新平衡的积极程度,即必须重新写入多个块。如果余额表示重写了0个块,请使用更高的值重试-dusage

如果平衡失败,那么我将尝试通过删除文件来重新启动和/或释放一些空间。


9
重新平衡是新的碎片整理。
内森·奥斯曼

1
ERROR: error during balancing '/mnt/durable' - No space left on device从驱动器中删除近1 GB后获得平衡
奥斯汀

您是否尝试过重新引导(当我遇到类似问题时,清理后重新引导对我有用)。
彼得·格林

@PeterGreen dmesg | tail重新启动后出现新错误后,在我的帖子中添加了内容。
奥斯汀

4

由于您正在使用RAID设置运行btrfs,因此请尝试运行平衡操作。

btrfs balance start /var/opt/gitlab

如果这给出了有关空间不足的错误的信息,请尝试使用以下语法:

btrfs balance start -musage=0 -dusage=0 -susage=0 /var/opt/gitlab 

对看到空间错误的每个btrfs文件系统重复此操作。如果您的空间问题是由于元数据未在镜像磁盘之间分布而造成的,则这可能会为您腾出一些空间。


我确实收到有关空间的错误。尝试其他语法时,它会向我显示警告:Refusing to explicitly operate on system chunks. Pass --force if you really want to do that.可以吗?
奥斯汀

尝试不带-susage=0选项。
virtex's

2

在我的系统上,我在cron.monthly中添加了以下作业。

clear_cache重新装入是由于BTRFS是用免费的地图有一些腐败问题。(我认为他们终于找到了问题,但问题很烦人,我愿意每月支付一次重建地图的费用。)

我增加了一些usage选项以逐渐释放空间以获得更大的余额。

#!/bin/sh

for mountpoint in `mount -t btrfs | awk '{print $3}' | sort -u`
do
    echo --------------------------
    echo Balancing $mountpoint :
    echo --------------------------
    echo remount with clear_cache...
    mount -oremount,clear_cache $mountpoint
    echo Before:
    /usr/sbin/btrfs fi show $mountpoint
    /usr/sbin/btrfs fi df $mountpoint
    for size in 0 1 5 10 20 30 40 50 60 70 80 90
    do
        time /usr/sbin/btrfs balance start -v -musage=$size $mountpoint 2>&1
        time /usr/sbin/btrfs balance start -v -dusage=$size $mountpoint 2>&1
    done
    echo After:
    /usr/sbin/btrfs fi show $mountpoint
    /usr/sbin/btrfs fi df $mountpoint
done

如果由于空间不足而无法平衡,建议您在平衡期间将其他某种块设备(或另一磁盘上的回送设备)临时添加到卷中,然后去掉它。


非常感谢@rrauenza!您的脚本确实挽救了我的生活。在我的情况下平衡命令成功搬迁块刚刚起来,从60
米哈尔FAPSO

1

btrfs的问题不大,这是该系统已完成的事情。这看起来像是从“单一”分配策略到“ raid 10”分配策略的不完全重新平衡的结果,这由大量的单个分配块证明。它可能以单个开始,然后转换被中断。分配不一致的池必然会出现分配问题。

考虑您已消耗了61%的池。您的分配策略是RAID10,因此在所有内容都被复制2之前,应达到最大50%的池消耗,因为这就是复制2的原因。这就是为什么您从单一到RAID 10的转换失败(并继续)的原因。我只能猜测,但是它可能是在重新平衡过程中分配的。您的设备上没有剩余空间,无法使用您拥有的磁盘重新平衡到RAID 10。达到61%的唯一原因是因为磁盘分配的不一致,有些是单次分配的,大多数是RAID 10。

如果您想在不做任何更改的情况下获得空间,则可以重新平衡为单个分配策略。您也可以添加更多磁盘或增加磁盘大小。或者,您可以像在这种情况下所做的那样,只删除一堆文件,以便您的池实际上可以平衡到RAID 10(因为总体消耗少于50%)。请确保删除文件后重新平衡,否则您仍将拥有此垃圾分配策略。

具体来说,删除这些文件后在重新平衡时强制实施RAID 10,以确保摆脱那些分配的块,如下所示:

btrfs fi balance start -dconvert=raid10 -mconvert=raid10 /home

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.