【问题标题】:Is it possible to get the compressed and uncompressed sizes of a file on a btrfs file system?是否可以在 btrfs 文件系统上获取文件的压缩和未压缩大小?
【发布时间】:2013-10-28 15:44:51
【问题描述】:

在启用transparent compressionbtrfs 文件系统上,是否可以确定压缩后的大小(我假设这是ls -l 列出的内容)和未压缩的文件大小?

【问题讨论】:

  • ls -l 会显示未压缩的大小,而不是压缩后的大小。
  • @nemequ 谢谢,很高兴知道。那我怎样才能得到压缩后的大小呢?
  • 不知道。我的猜测是查看范围(可能通过 filefrag),但这并不是我真正的领域。这个问题可能比堆栈溢出更适合超级用户,但是TBH 我会尝试一个特定于 btrfs 的论坛(比如他们的 IRC 房间或邮件列表)。

标签: shell file filesystems compression filesize


【解决方案1】:

有一个第三方工具可以做到这一点。

https://github.com/kilobyte/compsize

用法:

ayush@devbox:/code/compsize$ sudo compsize /opt
Processed 54036 files, 42027 regular extents (42028 refs), 27150 inline.
Type       Perc     Disk Usage   Uncompressed Referenced  
Data        82%      5.3G         6.4G         6.4G       
none       100%      4.3G         4.3G         4.3G       
zlib        37%      427M         1.1G         1.1G       
lzo         56%      588M         1.0G         1.0G  

【讨论】:

  • 这是正确的答案,即使运行它需要更多的参与。在 SuSE Linux Leap 42.3 上,我必须安装 libbtrfs-devel 包才能编译它,但效果很好!
【解决方案2】:

我无法逐个文件地回答,@catlover2 给出了文件系统的答案。但是您应该区分磁盘上的块大小和(虚拟)文件系统中的大小,lsdu 不能超出文件系统,因此它们没有提供有关使用多少磁盘块的信息,并且@jiliagre --apparent-size 在这里没用。

为了更好的说明这个问题,我用一个23G的文件btrfs文件系统做了一个测试;首先未压缩,然后 lzo 压缩。示例文件是一个虚拟机映像,压缩级别仅为 0.5。显示只有dfbtrfs filesystem df可以显示压缩。

$   lvcreate vg0 test_btrfs -L 30G
Logical volume "test_btrfs" created
$ mkfs.btrfs /dev/vg0/test_btrfs
...
fs created label (null) on /dev/vg0/test_btrfs
    nodesize 16384 leafsize 16384 sectorsize 4096 size 30.00GiB
$ mount /dev/vg0/test_btrfs /tmp/test_btrfs
$ btrfs filesystem df /tmp/test_btrfs
Data, single: total=8.00MiB, used=256.00KiB
System, DUP: total=8.00MiB, used=16.00KiB
System, single: total=4.00MiB, used=0.00
Metadata, DUP: total=1.00GiB, used=112.00KiB
Metadata, single: total=8.00MiB, used=0.00
$ cp bigfile /tmp/test_btrfs
$ btrfs filesystem df /tmp/test_btrfs
Data, single: total=24.01GiB, used=22.70GiB
System, DUP: total=8.00MiB, used=16.00KiB
System, single: total=4.00MiB, used=0.00
Metadata, DUP: total=1.00GiB, used=23.64MiB
Metadata, single: total=8.00MiB, used=0.00
$ btrfs filesystem df /tmp/test_btrfs
... unchanged!
$ cd /tmp/test_btrfs/
$ ls -l bigfile
-rw------- 1 root root 24367940096 May  4 15:03 bigfile
$ du -B1 --apparent-size bigfile
24367940096 bigfile
$ du -B1 bigfile
24367943680 bigfile
$ btrfs filesystem defragment -c bigfile
$ ls -l bigfile
-rw------- 1 root root 24367940096 May  4 15:03 bigfile
$ du -B1 --apparent-size bigfile
24367940096 bigfile
$ du -B1 bigfile
24367943680 bigfile
$ btrfs filesystem df /tmp/test_btrfs
Data, single: total=24.01GiB, used=12.90GiB
System, DUP: total=8.00MiB, used=16.00KiB
System, single: total=4.00MiB, used=0.00
Metadata, DUP: total=1.00GiB, used=39.19MiB
Metadata, single: total=8.00MiB, used=0.00
$ df -BG /tmp/test_btrfs
Filesystem                 1G-blocks  Used Available Use% Mounted on
/dev/mapper/vg0-test_btrfs       30G   13G       16G  47% /tmp/test_btrfs

@gandalf3 的问题仍未得到解答,可能我们需要等待 btrfs 的开发(或帮助开发它!)以获得合适的底层磁盘块du一个特殊的文件。这将非常有用,当我挂载带压缩的 btrfs fs(没有 force)不知道我的文件是否被压缩以及压缩到哪个级别时,我感到非常沮丧。

【讨论】:

    【解决方案3】:

    在 Ubuntu-18 中

    apt install btrfs-compsize
    compsize /mnt/btrfs-partition
    

    【讨论】:

      【解决方案4】:

      无论文件系统类型如何,文件在磁盘上的大小由du 命令给出1,例如:

      $ du -h *
      732K    file
      512 file1
      4.0M    file2
      $ du -B1 *
      749568  file
      512 file1
      4091904 file2
      

      磁盘大小等于文件大小加上元数据大小,四舍五入为文件系统块大小。非压缩文件的磁盘大小通常比它们的实际(字节数)大小略大。

      如前所述,未压缩的大小由ls -l 显示。也可以通过du--apparent-size option举报;

      $ du --apparent-size -h *
      826K    file
      64M file1
      17M file2
      $ du --apparent-size -B 1  *
      845708  file
      67108864    file1
      16784836    file2
      

      请注意,-B1--apparent-size 是 GNU 特定的 du 扩展。

      1 看来btrfs 不遵循这个规则。如果这是真的/仍然是真的,我的理解是这应该被认为是一个错误,或者至少是一个POSIX non conformance

      【讨论】:

      • btrfs 对 du 的磁盘大小撒谎 :(
      • 这不是错误,请参阅 Btrfs 常见问题解答中标题为“Why does not du report the compressed size?”的条目 示例:有一些实用程序通过比较标称大小和块分配大小来确定文件的稀疏度,这如果 st_blocks 包含压缩后的数量,行为可能会导致错误。
      • @RayHulha 好的,这不是错误,因为它不是一个损坏的实现,而是一个设计决策。它仍然不符合 POSIX,恕我直言,这是一个带有错误解释的设计缺陷:这样做不是为了破坏伪造的第三方程序,而是忽略了这样做会破坏非伪造程序的事实,这些程序期望在 st_blocks 中有可靠的值。 “磁盘块数”是什么意思很清楚,btrfs 不符合这个定义。
      • 该功能称为透明压缩。如果尺寸会显示压缩后的尺寸,那它现在就不会很透明了吗?
      【解决方案5】:

      我也试图回答这个问题,这就是我发现的:du -sdf 产生不同的数字。所以我做了一些测试:

      1. 我在 /home 中放置了一个大小约为 3TB 的测试目录。它是整个 /home 目录的部分副本,其中包含典型的文档、文本文件、图像和程序

      2. 我使用 .tar.gz 压缩了这个目录,导致文件大小为

      # du -s ./test.tar.gz 1672083116 ./test.tar.gz

      1. 在文件系统中存在此文件的情况下,我这样做了:

      # du -s /home 11017624664 /home

      # du --apparent-size -s /home 11010709168 /home

      # df /home Filesystem 1K-blocks Used Available Use% Mounted on /dev/md2 31230406656 9128594488 22095200200 30% /home

      这意味着我们有((11017624664/(1024**2))/(9128594488/(1024**2))-1)*100 = 20%的压缩比

      1. 然后我删除了这个文件,我得到了这个:

      # du -s /home 9348284812 /home

      # du --apparent-size -s /home 9340957158 /home

      # df /home Filesystem 1K-blocks Used Available Use% Mounted on /dev/md2 31230406656 7455549036 23764949364 24% /home

      产生 25% 的压缩比。同样从这些信息中,我得出结论,实际大小为 1592 G 的 test.tar.gz 文件在磁​​盘 1595 G 上占用。我还注意到,使用 --apparent-size 标志产生的差异微不足道,可能是由于块大小四舍五入。

      旁注,我用于挂载此分区的 fstab 行是:

      UUID=be6...07fe /home btrfs defaults,compress=zlib 0 2

      总结:

      要检查整个分区的压缩率,请使用以下两个命令:

      du -s /home df /home

      然后划分输出。我想我的 25% 压缩率是 zlib 压缩器的典型结果。

      【讨论】:

        【解决方案6】:

        您可以在文件中创建 Btrfs 文件系统,挂载它,将文件复制到那里并运行 df:

        $ dd if=/dev/zero of=btrfs.data size=1M count=1K
        $ mkdir btrfs
        $ mount btrfs.data btrfs -o compress
        ... copy the files to ./btrfs
        $ sync
        $ cd btrfs
        $ btrfs filesystem df .
        

        从 17MiB 压缩到 5MiB 的单个文件示例:

        $ cd btrfs
        $ ls -l
        -rwx------ 1 atom atom 17812968 Oct 27  2015 commands.bin
        $ btrfs filesystem df .
        Data, single: total=1.01GiB, used=5.08MiB
        System, DUP: total=8.00MiB, used=16.00KiB
        Metadata, DUP: total=1.00GiB, used=112.00KiB
        GlobalReserve, single: total=16.00MiB, used=0.00B
        

        【讨论】:

          【解决方案7】:

          运行btrfs filesystem df /mountpoint

          示例输出:

          Data: total=2.01GB, used=1.03GB
          System, DUP: total=8.00MB, used=4.00KB
          System: total=4.00MB, used=0.00
          Metadata, DUP: total=1.00GB, used=2.52MB
          Metadata: total=8.00MB, used=0.00
          

          关键行以Data:开头; used= 是压缩后的大小,total= 是总大小,就像在未压缩的文件系统上一样。我创建了一个测试文件系统,使用compress_force=zlib 选项挂载它,并将1GB 的零复制到文件系统上的一个文件中;那时Data: 行是Data: total=1.01GB, used=32.53MB(零是相当可压缩的!)。然后我重新挂载了禁用压缩的文件系统,将另一个 GB 的零复制到其中,此时Data: 行读取Data: total=2.01GB, used=1.03GB

          正如上面提到的 nemequ,ls -l 相反,显示的是 未压缩 大小。

          【讨论】:

          • 这不是这个意思。这应该意味着使用了两个块(1GB),但只使用了 1.03GB。这仅允许您在开始时看到未压缩的大小,因为现有大小为 0
          • -1 这个答案是完全错误的,并且基于错误的假设。 total= 不量化数据使用量。 Btrfs 提前保留大块空白空间:这提高了数据局部性并减少了碎片。 total量化了当前chunk的总和,即used+chunks中空空间的总和。当您写入并且块中有足够的可用空间时,used 会发生变化,但 total 不会。当used 接近total 时,Btrfs 会在total 之外的一些空间上放置一个新的占位符,将其添加到total,并且不会触及used
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-08-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多