了解NTFS压缩

摘要:
本文的目标是让读者更全面地了解压缩NTFS文件时到底发生了什么。CompressionUnitsNTFS使用一个名为“压缩单元”的参数来定义数据流中压缩字节范围的粒度和对齐方式。下面的图表显示了与每个有效的NTFS簇大小相对应的CU大小。NTFSCompression既然我们已经讨论了稀疏文件,我们将继续讨论传统的NTFS压缩。这可以防止NTFS在用户希望读取文件中的小字节范围时不得不解压缩整个文件。NTFS不能压缩CU2和CU3,但部分CU4可压缩69%。

在您选中“压缩内容以节省磁盘空间”复选框之前,最好先了解一下这对磁盘上运行的快乐的小字节、字节和半字节有何影响。
备份应用程序在备份压缩文件时通常会收到ERROR U DISK U FULL errors,当驱动器上还有几GB的可用空间时,这会导致相当大的混乱。复制压缩文件时也可能出现其他问题。本文的目标是让读者更全面地了解压缩NTFS文件时到底发生了什么。

Compression Units

NTFS使用一个名为“压缩单元”的参数来定义数据流中压缩字节范围的粒度和对齐方式。压缩单元的大小完全基于NTFS簇大小(有关详细信息,请参阅下表)。在下面的描述中,缩写“CU”用于描述压缩单元和/或其尺寸。
CU的默认大小是16个簇,尽管CU的实际大小实际上取决于磁盘的簇大小。下面的图表显示了与每个有效的NTFS簇大小相对应的CU大小。

Cluster SizeCompression UnitCompression Unit (hex bytes)
512 Bytes8 KB0x2000
1 KB16 KB0x4000
2 KB32 KB0x8000
4 KB64 KB0x10000
8 KB64 KB0x10000
16 KB64 KB0x10000
32 KB64 KB0x10000
64 KB64 KB0x10000

本机NTFS压缩在群集大小大于4KB的卷上不起作用,但仍可以使用稀疏文件压缩。

NTFS稀疏文件

NTFS的稀疏文件特性允许应用程序创建非常大的文件,这些文件主要由零范围组成,而无需为零范围实际分配LCN(逻辑群集)。对于代码头,可以通过使用FSCTL_SET_SPARSE IO控制代码调用DeviceIoControl来完成,如下所示。

BOOL SetSparse(HANDLE hFile)
     {
           DWORD Bytes;
           return DeviceIoControl(hFile, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &Bytes, NULL);
     }

若要指定零范围,则应用程序必须使用FSCTL_SET_ZERO_DATA IO控制代码调用DeviceIoControl。

BOOL ZeroRange(HANDLE hFile, LARGE_INTEGER RangeStart, LONGLONG RangeLength)
     {
            FILE_ZERO_DATA_INFORMATION FileZeroData;
            DWORD Bytes;
            FileZeroData.FileOffset.QuadPart =RangeStart.QuadPart;
            FileZeroData.BeyondFinalZero.QuadPart = RangeStart.QuadPart + RangeLength + 1;
            returnDeviceIoControl( hFile,
                                     FSCTL_SET_ZERO_DATA,
                                     &FileZeroData,
                                     sizeof(FILE_ZERO_DATA_INFORMATION),
                                     NULL,
                                     0,
                                     &Bytes,
                                     NULL);
     }

因为稀疏文件实际上不会为零范围分配空间,所以稀疏文件可以比父卷大。为此,NTFS创建一个占位符VCN(虚拟集群号)范围,不映射逻辑集群。任何访问“稀疏”范围的尝试都会导致NTFS返回一个满是零的缓冲区。访问分配的范围将导致对分配范围的正常读取。当数据写入稀疏文件时,会创建一个与包含写入字节的压缩单元边界完全对齐的分配范围。请参阅下面的示例。如果虚拟集群号vcn0x3a发生单字节写入,那么所有压缩单元3(vcn0x30-0x3f)将成为分配的LCN(逻辑集群号)范围。分配的LCN范围将填充零,并且单个字节将写入目标LCN中适当的字节偏移量。

[...] -ALLOCATED
(,,,) -Compressed
{ } - Sparse (or free) range
   / 00000000000000000000000000000000000000000000000000000000000000000000000000000000VCN 000000000000000011111111111111112222222222222222333333333333333344444444444444440123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
            CU0 CU1 CU2 CU3 CU4
     |++++++++++++++||++++++++++++++||++++++++++++++||++++++++++++++||++++++++++++++|{ }[..............]{ }
Extents {
    VCN = 0x0 LEN = 0x30 CU0 -CU2
    VCN = 0x30 LEN = 0x10: LCN = 0x2a21fCU3
    VCN = 0x10 LEN = 0x10CU4
}

下面是使用稀疏文件API创建的2GB文件的屏幕截图。

了解NTFS压缩第1张

请注意,这个卷只有76.9MB,但在根文件夹中有一个2GB的文件。

了解NTFS压缩第2张

如果我们试图用COPY命令复制这个稀疏文件,它将失败。这是因为COPY不知道如何复制文件上的稀疏属性,所以它试图在D:的根目录中创建一个真正的2GB文件。当尝试将大型数据库文件从一个卷移动到另一个卷时,可能会发生这种情况。如果您的数据库应用程序使用稀疏属性,那么在将数据库移动到其他卷时,最好使用数据库软件的备份/还原功能。

了解NTFS压缩第3张

现在让我们用COMPACT实用程序查看文件的属性。请注意,该文件显示为压缩文件,并且具有巨大的压缩比。

了解NTFS压缩第4张

如果您返回并从资源管理器查看文件属性,您将注意到没有压缩复选框(或任何其他指示文件已压缩)。这是因为shell不检查文件中的稀疏位。

了解NTFS压缩第5张

简而言之,在将稀疏文件从一个位置移动到另一个位置时要小心。应用程序告诉文件系统零范围的偏移量,因此您应该始终将稀疏文件的管理留给创建它们的应用程序。手动移动或复制稀疏文件可能会导致意外结果。

NTFS Compression

既然我们已经讨论了稀疏文件,我们将继续讨论传统的NTFS压缩。NTFS通过将数据流分成CU来压缩文件(这与稀疏文件的工作方式类似)。当创建或更改流内容时,数据流中的每个CU都被单独压缩。如果压缩导致减少一个或多个群集,则压缩单元将以其压缩格式写入磁盘。然后将稀疏VCN范围固定到压缩VCN范围的末尾以进行对齐(如下例所示)。如果数据压缩不足以将一个集群的大小缩小,那么整个CU将以未压缩的形式写入磁盘。
这种设计使得随机访问非常快,因为只有一个CU需要解压缩才能访问文件中的任何单个VCN。不幸的是,大型顺序访问相对较慢,因为许多CU的解压需要执行顺序操作(如备份)。
在下面的示例中,压缩文件由六组映射对(编码的文件范围)组成。三个分配的范围与三个稀疏范围共存。稀疏范围的目的是保持压缩单元边界上的VCN对齐。这可以防止NTFS在用户希望读取文件中的小字节范围时不得不解压缩整个文件。第一个压缩单元(CU0)压缩了12.5%(这使得分配的范围缩小了2个VCNs)。在文件扩展数据块中添加了一个额外的空闲VCN范围,作为CU尾部释放的lcn的占位符。第二个分配的压缩单元(CU1)与第一个相似,只是CU压缩了大约50%。
NTFS不能压缩CU2和CU3,但部分CU4可压缩69%。因此,CU2和CU3未压缩,而CU4从VCN 0x40压缩到0x44。因此,CU2、CU3和CU4是一个单独的运行,但该运行包含压缩和未压缩VCN的混合。
注意:每组括号代表已分配或可用空间的连续运行。一组NTFS映射对描述了每组括号。

[...] -ALLOCATED
(,,,) -Compressed
{ } - Sparse (or free) range
   / 00000000000000000000000000000000000000000000000000000000000000000000000000000000VCN 000000000000000011111111111111112222222222222222333333333333333344444444444444440123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
           CU0 CU1 CU2 CU3 CU4
     |++++++++++++++||++++++++++++++||++++++++++++++||++++++++++++++||++++++++++++++|(,,,,,,,,,,,,){}(,,,,,,){ }[...............................,,,,){ }
Extents {
    VCN = 0x0 LEN = 0xe : LCN = 0x29e32dCU0
    VCN = 0xe LEN = 0x2CU0
    VCN = 0x10 LEN = 0x8 : LCN = 0x2a291fCU1
    VCN = 0x18 LEN = 0x8CU1
    VCN = 0x20 LEN = 0x25 : LCN = 0x39dd49 CU2 -CU4
    VCN = 0x45 LEN = 0xbCU4
}

现在我们来讨论这个设计的局限性。下面是一些在读/写压缩文件时出错的例子。

Disk full error during a backup read operation or file copy

  1. NTFS确定正在访问哪个压缩单元。
  2. 读取压缩单元的整个分配范围。
  3. 如果单元没有被压缩,那么我们跳到第5步。否则,NTFS将尝试保留(但不分配)将解压缩的CU写回磁盘所需的空间。如果磁盘上的可用空间不足,则应用程序在读取期间可能会出现错误“磁盘已满”。
  4. CU将在内存中解压缩。
  5. 解压后的字节范围将映射到缓存中并返回到请求应用程序。
  6. 如果CU的一部分在缓存中被改变…
    步骤3中的保留磁盘空间将变为已分配空间。
    铜的含量将被压缩并冲洗回新分配的区域(LCN位置通常不会改变)。
    CU中的任何可恢复磁盘空间都将被释放。

Failure to copy a large file to a compressed folder

这是压缩中最常见的问题,目前的解决方案是教育用户了解限制。NTFS压缩大约为每16个数据簇创建一个文件片段。因为标准压缩允许的最大集群大小是4K,所以允许的最大压缩单元是64KB。为了将一个100GB的文件压缩成64KB的部分,最终可能会有1638400个片段。编码1638400个片段对于文件系统来说是有问题的,并且可能导致创建压缩文件失败。在Vista及更高版本上,文件复制将失败,并受到状态“文件”和“系统”的限制。在早期版本中,状态代码为statusu unficientu RESOURCES。如果可能,请避免对较大或对系统性能至关重要的文件使用压缩。
我收到了来自NTFS主要开发负责人关于这个博客的反馈。幸运的是,大多数反馈都很好,但他要求我增加一个最大尺寸的建议。根据我们开发团队的研究,对于集群大小为4KB的卷上的压缩文件,50-60GB是一个“合理的大小”。对于集群大小较小的卷,这个“合理大小”会急剧下降。

压缩.VHD(虚拟硬盘)文件会导致虚拟机性能降低

免责声明:文章转载自《了解NTFS压缩》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇SQL serve 数据库--视图、事物、分离附加、备份还原Fiddler及浏览器开发者工具进行弱网测试下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

NTFS多流文件、结构化存储和摘要属性集合

Question:首先是一个简单的应用问题。我曾经看过无数的文献。其实看文献无非就是为了归类和总结,如果看了不做总结,便相当于白看。可是做总结是个令人烦恼的过程。写纸上吧,不太好整理;以注释形式写在pdf里一并保存吧,那要查的时候还得一个个pdf打开了去找,多麻烦;用ReferenceManager或者是excel吧,那在复制文件的时候,我还得记得顺带co...

什么是系统封装

什么是系统封装   系统封装,说简单就是把系统制作成镜像的方法刻录到光盘,用在系统安装上面。系统封装,不同于系统的正常安装。最本质的区别在于 系统封装 是将一个完整的系统以拷贝的形式打包,然后用粘贴的形式安装在另外一个系统盘上,而正常安装则是通过 Setup程序进行安装。 举一个不太贴切的例子,你要铺草坪,你可以在那片土地上撒草籽等待草的长成,也可以直...

开机自动mount

root权限编辑:/etc/fstab vim /etc/fstab #当前系统里的唯一标志  挂载到什么地方   文件系统类型    选项               是否dump   # <file system>                <mount point>      <type>           ...

让你的Mac支持NTFS

前段时间换成Mac电脑之后,发现有一点不爽,不能在Mac下写入NTFS格式的磁盘,所以就去研究了一下。 解决方法有如下三种。 第一种,直接使用第三方软件,如Paragon NTFS for MAC,Tuxera NTFS等,不过大部分都是收费的。有一款免费的是Mounty,我之前用了一下,我自己的机器上没有效果,大家可以尝试一下。 第二种,执行我写好的脚本...

Win &amp;amp; Mac 系统之间U盘传递的U盘文件格式选取问题

Win & Mac 系统之间U盘传递的U盘文件格式选取问题 1. Win系统与Mac系统之间可以通过 exFat U盘文件系统传递 exFAT(Extended File Allocation Table File System,扩展FAT,也称作FAT64,即扩展文件分配表)是Microsoft在Windows Embeded 5.0以上(包括W...

archlinux 下挂载ntfs分区,显示"permission denied"

安装完archlinux的xfce4桌面后,在普通用户下想挂载windows的分区,可是遇到了大麻烦: 1.尝试打开系统自动挂载的分区时,提示“not authorized to perform operation" 2.自己手动挂载分区后,要打开的话,提示”permission denied“ 但这两个问题在root用户下不会发生,于是开始了漫长的漫长的...