如何检查 XFS 上包含引用链接文件的文件夹的磁盘使用情况?

如何检查 XFS 上包含引用链接文件的文件夹的磁盘使用情况?

XFS 支持写入时复制 (CoW),因此尚不完全清楚du如果某些字节在文件之间共享会发生什么情况。我想找到一种方法来检查文件夹使用了多少磁盘空间,而不是多次计算共享字节,即磁盘上的实际使用情况。

xfs_estimate似乎都没有du做我需要的事情:

$ mkdir testfolder
$ cd testfolder 
$ dd if=/dev/zero of=testfile  bs=1M count=500 status=progress
500+0 records in
500+0 records out
524288000 bytes (524 MB, 500 MiB) copied, 0,158889 s, 3,3 GB/s
$ cp --reflink=always testfile testfile2                      
$ xfs_estimate .                         
. will take about 1004,4 megabytes
$ du -hs .      
1000M   .

我期望的是某些工具说该文件夹仅使用 500MB。

df显示使用 plain 时可用磁盘空间减少 500MB cp,但使用cp --reflink=always.因此,重新链接似乎有效,但df在实践中没有帮助,因为磁盘很大,我想检查一个相当小的文件夹的实际大小。

我认为这对于 BTRFS 来说也可能是一个有效的问题。但就我而言,我需要一个适用于 XFS 的解决方案。

答案1

感觉应该有一个工具默认可以执行此操作,但我不记得是否有一个。

您可以使用filefrag(通用、FIEMAP ioctl)或使用xfs_bmap(XFS 特定)查询文件范围。这样,您可以选择仅对共享区(重复项)进行一次计数(或根本不计数)。

# filefrag -e -k testfile
Filesystem type is: 58465342
File size of testfile is 5242880 (5120 blocks of 1024 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..    5119:         96..      5215:   5120:             last,shared,eof
testfile: 1 extent found

在此示例中,filefrag知道并显示范围是共享的(文件系统中的任何位置,不一定在该目录内),但xfs_bmap不会:

# xfs_bmap -l testfile
testfile:
    0: [0..10239]: 192..10431 10240 blocks

但基本上这是您可以用来自己编写脚本的关键要素。

显示所有可能的共享范围:

# find . -xdev -type f -exec filefrag -e -k {} + | grep shared
   0:        0..    5119:         96..      5215:   5120:             last,shared,eof
   0:        0..    5119:       5216..     10335:   5120:             last,shared,eof
   0:        0..    5119:         96..      5215:   5120:             last,shared,eof

共享(目录内重复)范围使用xfs_bmap

# find . -xdev -type f -exec xfs_bmap -l {} + | grep 'blocks$' | grep -v ': hole' | sort | uniq -d
0: [0..10239]: 192..10431 10240 blocks

请注意,xfs_bmap每个块使用 512 字节,而filefrag使用 1024 字节(带-k选项)或任何文件系统块大小(例如 4096 字节)。

使用以下方式共享重复范围filefrag

# find . -xdev -type f -exec filefrag -ek {} + | grep shared | sort | uniq -d
   0:        0..    5119:         96..      5215:   5120:             last,shared,eof

因此,在这种情况下,您必须从du -cks .结果中减去 5120。

答案2

我试图找出我的文件实际使用了多少空间以及与其他文件共享了多少空间。我不确定为什么“total”与 相比在某些字节上有所不同du,但最终它似乎返回了我需要的内容:

file="/mnt/cache/domains/Windows 10/vdisk1-backup.img"

du -h "$file"

mapfile -t fragments < <( filefrag -ek "$file" | tail -n +4 | cut -d ":" -f 4 | grep -oP "[0-9]+" )
sum=$(IFS=+; echo "$((${fragments[*]}))")
sum=$((sum * 1024))
sum=$(echo "$sum" | numfmt --to=iec)
echo "$sum total"

mapfile -t fragments < <( filefrag -ek "$file" | tail -n +4 | grep "shared" | cut -d ":" -f 4 | grep -oP "[0-9]+" )
sum=$(IFS=+; echo "$((${fragments[*]}))")
sum=$((sum * 1024))
sum=$(echo "$sum" | numfmt --to=iec)
echo "$sum shared"

mapfile -t fragments < <( filefrag -ek "$file" | tail -n +4 | grep -v "shared" | cut -d ":" -f 4 | grep -oP "[0-9]+" )
sum=$(IFS=+; echo "$((${fragments[*]}))")
sum=$((sum * 1024))
sum=$(echo "$sum" | numfmt --to=iec)
echo "$sum unique"

输出:

15G     /mnt/cache/domains/Windows 10/vdisk1-backup.img
15G total
8.3G shared
6.8G unique

答案3

我在 Veeam 社区页面上为此提出了一个解决方案:

固有:

由于我们根据使用 (Veeam) CloudConnect 的客户的实际磁盘使用情况进行计费,因此现有报告无法用于报告和计费(它们报告预重复数据删除/重新链接数据)。花了一段时间才弄清楚,但有一种方法可以计算不可变存储库上每个目录所使用的实际磁盘空间。

解决方案:

使用:https://community.veeam.com/blogs-and-podcasts-57/check-reflink-and-spared-space-on-xfs-repositories-244

我推断了一个脚本,该脚本将给出不可变存储库上每个文件夹(IE:客户端)的磁盘使用情况。这不是“使用的数据”;这就是 Veeam 的报告。这是“已使用的磁盘”。引用链接后磁盘上的实际大小(重复数据仅计算一次)。

关于此脚本的注释;看来原来的博客条目对于块的大小是错误的。他们将其归因于 4096...这在磁盘上是正确的...但所使用的实用程序明确给出了块大小为 512 的信息: https://linux.die.net/man/8/xfs_bmap “512字节块的单位”

要使用此脚本,我们使用 cron 任务并将输出通过管道传输到存储库本身上的邮件客户端(即:script.bash 2>&1 | mail -s“$HOSTNAME 的不可变存储报告”[电子邮件受保护]

#!/bin/bash

for clientDir in `find /backups/disk-01/backups/ -mindepth 1 -maxdepth 1 -type d`
do
    echo $clientDir
    clientSpaceUsed=$(find $clientDir/*/* -xdev -type f -exec xfs_bmap -l {} + | awk '{ print $3 " " $4 }' | sort -k 1 | uniq | awk '{ print $2 }' | grep -Eo '[0-9]{1,7}' | paste -sd+ | bc | awk '{print $1*512/1024/1024/1024}')
    #block sizes of 512 bytes.  Divided by 1024 for KB.  Divided by 1024 for MB. Divided by 1024 for GB.
    echo "$clientSpaceUsed GB"
done

分解其工作原理:

对于“/backups/disk-01/backups/”中的每个客户端目录

输出正在报告的目录

运行 xfs_bmap -l (这告诉我们有关相关块的所有信息) 获取第 3 列和第 4 列(现在变成第 1 列和第 2 列,其余的被丢弃) 按第 1 列排序 删除重复的数据行(用于快速克隆的引用链接;保留用于计数目的的数据的单个副本)仅选择第 2 列(现在变为第 1 列)

删除除数字以外的任何内容

将这些数字加在一起

乘以块大小 (512)

除以 1024(现在为 KB)

除以 1024(现在为 MB)

除以 1024(现在为 GB)

输出文本

答案4

如果您只想知道类似于的实际可用空间,df请使用xfs_spaceman.

例如:

xfs_spaceman -c 'freesp -s -m4096' /path/to/xfs/mount

计算速度可能很慢,但报告的“总可用块”对于引用链接/重复数据删除数据来说是准确的,并且可以乘以块大小以获得以字节为单位的实际可用空间。

相关内容