在创建/删除一系列相同大小的文件后,NTFS磁盘上的空间不足

时间:2010-08-25 12:27:45

标签: c windows ntfs virtual-drive disk-io

我在处理大型项目时遇到了一个非常奇怪的问题。我在一个分区上写了一堆相同大小的文件(尝试了通过diskmgmt.msc创建的RAM磁盘和虚拟磁盘)。如果没有足够的可用空间来容纳另一个文件(由GetDiskFreeSpaceExW报告),我会删除先前创建的(仅一个)并写入新的。然后,我删除另一个旧文件并写一个新文件,无限广告(因此,您可能会认为该分区是同等大小文件的环形缓冲区)。在一系列写入删除(从几百到几千)之后,我在编写新文件时遇到no free space错误(在此之前,GetDiskFreeSpaceExW报告了足够的空间)。我让我的几个同事尝试在他们的硬件上重现问题,但问题没有重新出现。

为了澄清一点,这是确切的算法:

  1. 选择文件大小(例如,S字节)
  2. 使用GetDiskFreeSpaceExW检查可用空间
  3. 如果free_space> S:写一个大小为S且转到2的新文件
  4. 其他:删除一个文件并转到2
  5. 请务必注意,我将数据写入大小为4096字节的块中的文件(问题可能会或可能不会重新出现,具体取决于块大小)。文件大小为5MB。 NTFS分区大小为21 MiB。簇大小为512 B(同样,更改这些参数会影响结果)。使用这些参数,在创建第684个文件期间发生故障。它不依赖于我是使用RAM磁盘还是虚拟磁盘(因此,它不是特定实现的问题)。

    我在失败后分析了生成的磁盘映像转储,发现文件严重碎片化。 Chkdsk在实验之前和之后都没有报告任何问题。系统日志中未发现任何错误。

    我的上网本(Dell Inspiron 1110)的可能相关参数:

    • 奔腾SU4100,相对较慢的双核x64 CULV CPU(1.3 GHz)
    • Windows 7旗舰版x64版
    • 2 GB RAM

    有没有人知道发生了什么以及如何调试它?我在哪里可以查找其他信息?我已经没有想法了,我需要尽快解决这个问题......

    UPD:我在创建文件时写入文件数据(即write()失败),时出现问题。所以,它看起来不像我缺少MFT条目。

    UPD2:回答了一些问题

    • 分区是新格式化的分区,因此,文件没有特定属性,没有目录结构,没有
    • 权限是默认的
    • 没有.lnk's,没有硬链接 - 我只是编写
    • 的文件
    • 所有文件都写入根目录,不再创建目录
    • 文件名只是文件的序数(即1,2,3,...)
    • 没有替代数据流,使用`fopen()`创建文件,用`fwrite()`写入并用`fclose()`
    • 关闭
    • $ Txf创建,确实
    • 没有错误的群集,这是一个虚拟(或RAM)磁盘

4 个答案:

答案 0 :(得分:1)

FS有自己的开销,你没有考虑到。该开销不是常量,因此通过删除/写入文件可能会导致碎片化。换句话说,“5 MB的可用空间”并不意味着你可以向磁盘写入5MB。

答案 1 :(得分:1)

假设您的实施正确并且您的同事无法重现问题,则可能是您的MFT空间不足。

  

默认情况下,Windows XP保留每个NTFS卷(称为MFT区域的区域)的12.5%   独家使用MFT。所以,如果你   计划存储大量的小文件   (在8K以下,比方说)你的音量,你的   MFT可能会在您的空间用完之前耗尽空间   音量的自由空间确实如此   结果将是MFT碎片。

来自Technet

  

首先,即使删除文件和目录,MFT也不会缩小   从卷;相反,MFT   标志着FRS反映了   删除。其次,NTFS非常存储   MFT FRS中的小文件   参考文件。虽然这个   安装提供了性能优势   对于这些文件,它可能会导致MFT   音量过大时过度增长   包含许多这样的文件。

答案 2 :(得分:1)

很好的NTFS问题,而不是这里的所有信息。什么是导演结构?这有LINK文件吗?你在驱动器上使用压缩吗?卷影副本?

你没有用完MFT空间,因为有一个常量的文件/目录。这意味着MFT是静态的。 MFT预留空间也将用于低磁盘空间场景。我已经用完了NTFS卷上的每个集群。

对于发生的事情有几种解释:

1)$ Log文件可能已经增长。这是一个回滚日志。

2)如果驱动器上存在非统一权限,则文件安全信息的@SII文件可能会增加

3)如果该卷上的某些文件具有指向它们的.lnk /快捷方式文件,系统会将每个目标的GUID放入索引中。 (如果你在资源管理器中点击了2个文件,你会获得.lnk文件 - 在最近的文档中!)

4)目录结构不是静态的(或文件名的长度不一致)目录的$ index缓冲区的大小可能会增大。

5)如果该驱动器上有系统卷directroy,则可能有卷影副本和其他操作系统特定数据。

6)备用数据流未显示在文件大小中。有吗?

7)TxF - 在vista及更高版本下,可能会有一个占用可变空间的事务层。

8)坏簇?集群可能会变坏(但chkdsk可能会注意到这一点......)

9)文件变得碎片化,并且其他元数据的片段列表太大而不适合MFT记录(不太可能因为你的文件很小而你没有大量长文件)

10)使用硬链接也会在驱动器上放置更多数据。

我列出了所有这些作为其他人的参考!

最后的注意事项 - 有时你可以创建和写一个小文件,即使有0个字节可用,因为NTFS驻留文件只占用一个MFT记录(它们会重新删除一个免费的记录)

答案 3 :(得分:0)

虽然禁用TXF会修复此问题(TXF只是使用卷上空间的文件系统的一个组件)并不是特别令人惊讶,但有两件事需要考虑。实际上,第一个,更重要的是,您可能需要小心禁用它。 (其他组件可能依赖于它; Windows Update是一个这样的组件,但它应该只关心系统卷。)

要考虑的另一件事是,这通常是一种脆弱的模式。文件系统对它可以消耗的内容有一些假设。例如,索引将增长(以预定义的增量,可能会发生变化),并且它们可能不会以您发现可预测的方式缩小。此外,安全描述符索引可能会继续增长。

上面关于影子副本的另一个注意事项应始终牢记在心。

FWIW $ Log文件不会自动增长。