2

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

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

  1. 选择文件大小(比如 S 字节)
  2. 使用 GetDiskFreeSpaceExW 检查可用空间
  3. 如果 free_space > S:写入大小为 S 的新文件并转到 2
  4. 否则:删除一个文件并转到 2

需要注意的是,我以 4096 字节大小的块将数据写入文件(问题可能会或可能不会重新出现,具体取决于块大小)。文件大小为 5MB。NTFS 分区大小为 21 MiB。集群大小为 512 B(同样,更改这些参数会影响结果)。使用这些参数,在创建第 684 个文件期间会发生故障。它不取决于我是使用 RAM 磁盘还是虚拟磁盘(因此,这不是特定实现的问题)。

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

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

  • Pentium SU4100,相对较慢的双核 x64 CULV CPU (1.3 GHz)
  • Windows 7 Ultimate x64 版
  • 2 GB 内存

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

UPD:问题发生在我写入文件数据(即write()失败)时,而不是在我创建文件时。所以,看起来我并不缺少 MFT 条目。

UPD2:回答一些被问到的问题

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

4 回答 4

1

FS 有自己的开销,您不考虑这些开销。该开销不是恒定的,因此通过删除/写入文件可能会导致碎片。换句话说,“5 MB 可用空间”并不意味着您可以将 5 MB 写入磁盘。

于 2010-08-25T12:34:52.850 回答
1

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

默认情况下,Windows XP 保留每个 NTFS 卷(称为 MFT 区域的区域)的 12.5% 供 MFT 专用。因此,如果您计划在您的卷上存储大量小文件(例如 8K 以下),您的 MFT 可能会在您的卷的可用空间之前耗尽空间,结果将是 MFT 碎片。

来自Technet

首先,即使您从卷中删除文件和目录,MFT 也不会缩小;相反,MFT 标记 FRS 以反映删除。其次,NTFS 将非常小的文件存储在引用文件的 MFT FRS 中。尽管此设置为这些文件提供了性能优势,但当卷包含许多此类文件时,它可能会导致 MFT 过度增长。

于 2010-08-25T12:35:08.310 回答
1

很好的 NTFS 问题,而不是这里的所有信息。什么是目录结构?这上面有链接文件吗?您是否在驱动器上使用压缩?卷影副本?

您不会用完 MFT 空间,因为文件/目录的数量是恒定的。这意味着 MFT 是静态的。此外,MFT 预留空间将用于磁盘空间不足的情况。我已经用完了 NTFS 卷上的每个集群。

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

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

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

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

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

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

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

7) TxF - 在 vi​​sta 和更高版本下,可能有一个占用可变空间的事务层。

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

9)文件变得碎片化,并且带有其他元数据的片段列表太大而无法放入 MFT 记录中(不太可能因为您的文件很小并且您没有大量长文件)

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

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

最后一点 - 有时即使有 0 个字节可用,您也可以创建和写入一个小文件,因为 NTFS 驻留文件只占用一条 MFT 记录(它们会恢复已删除的免费记录)

于 2010-08-25T17:53:13.337 回答
0

虽然禁用 TXF 会解决此问题并不令人惊讶(TXF 只是使用卷上空间的文件系统的一个组件),但有两件事需要考虑。第一个,也是更多的旁白,真的,你可能要小心禁用它。(其他组件可能依赖于它;Windows Update 就是这样一个组件,尽管它应该只关心系统体积。)

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

上面关于卷影副本的另一个注意事项是要始终牢记的。

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

于 2010-08-27T13:51:14.333 回答