碎片化的 NTFS HDD - 删除文件速度慢,每个文件耗时 600 毫秒

碎片化的 NTFS HDD - 删除文件速度慢,每个文件耗时 600 毫秒

我有一个目录

42048 个文件 32,442,230,574 字节

运行碎片整理程序告诉我一切正常

defrag E: /A /V
Microsoft Drive Optimizer
Copyright (c) Microsoft Corp.

Invoking analysis on New Volume (E:)...


The operation completed successfully.

Post Defragmentation Report:

        Volume Information:
                Volume size                 = 931.50 GB
                Cluster size                = 4 KB
                Used space                  = 814.77 GB
                Free space                  = 116.73 GB

        Fragmentation:
                Total fragmented space      = 1%
                Average fragments per file  = 1.00

                Movable files and folders   = 516620
                Unmovable files and folders = 4

        Files:
                Fragmented files            = 160
                Total file fragments        = 2273

        Folders:
                Total folders               = 25503
                Fragmented folders          = 2
                Total folder fragments      = 8

        Free space:
                Free space count            = 78165
                Average free space size     = 1.52 MB
                Largest free space size     = 2.97 GB

        Master File Table (MFT):
                MFT size                    = 2.50 GB
                MFT record count            = 2631423
                MFT usage                   = 100%
                Total MFT fragments         = 14

        Note: File fragments larger than 64MB are not included in the fragmentation statistics.

        You do not need to defragment this volume.

所以不应该有任何碎片问题。但是当我尝试删除该目录中的某些文件时,我在 WPA 中看到删除一个文件需要 600 毫秒,而碎片整理运行一整夜后,删除单个文件需要 2400 毫秒! 在此处输入图片描述

Defrag 说一切正常,那么这里为什么会有这么多碎片?我尝试使用 contig.exe 检查 $MFT,它有 7 个碎片,但看起来还不错:

E:\> contig -a $MFT

Contig v1.8 - Contig
Copyright (C) 2001-2016 Mark Russinovich
Sysinternals

E:\$Mft is in 13 fragments
E:\$Mft::$BITMAP is defragmented

Summary:
     Number of files processed:      2
     Number unsuccessfully procesed: 0
     Average fragmentation       : 7 frags/file

慢速方法似乎是 NtfsInsertCachedLcnAtIndex,它由 NtfsScanEntireBitmap 调用。我怀疑 NTFS 位图已降级为一个非常长的列表。问题是我无法使用 contig.exe 访问 $BITMAP。它说访问被拒绝。有人遇到过类似的问题吗?除了格式化硬盘外,如何解决这些问题? 在此处输入图片描述 将 NTFS 簇大小从 4 KB 更改为 32 KB 是否会使情况变得更好,或者这对于一直创建和删除许多 1-2 MB 文件的卷来说没有区别?

更新1 添加了智能数据

在此处输入图片描述

更新 2 添加了 n 次文件删除的图表 - 没有明显的趋势可见

在此处输入图片描述

更新 3 使用 contig.exe 在空文件夹中创建 100 个 500K 文件,然后逐个删除文件,结果显示以下模式

    for( $i=0;$i -le 100;$i++){​​​​​​​​ contig -n "$i.json" 500000  }​​​​​​​​
    Get-ChildItem *.json | foreach {​​​​​​​​ (Measure-Command {​​​​​​​​ Remove-Item $_ }​​​​​​​​ ).TotalMilliSeconds }​​​​​​​​

5.2938
2.7115
1.2143
1.297
1.1552
1.3336
1.8351
1.1386
2230.3417
0.862
0.7522
0.7832
0.7061
0.711
0.7167
0.713
0.7137
2627.1645

Contig 会创建未碎片化的文件,因此它不可能是文件碎片。但对于某些文件,删除效率非常低。这更像是 NTFS 文件系统问题。我会向 MS 查询。

更新 4 这是 NTFS 内部的实际限制。我编写了一些测试,例如在文件夹中创建几百 K 个文件,以检查 NTFS 文件创建查询性能。这种方法效果很好,尽管有传言称它可以处理几百 K 个文件,即使文件名几乎相同,也不会出现很大的性能下降,我确实怀疑这可能会导致一些树平衡问题。在另一台装有三星 SSD 的机器上进行持续写入性能测试后,我再次遇到了文件删除问题。这次通过 del 删除单个文件需要 2-6 秒从包含 20K 个文件的目录中的 cmd.exe 开始。

在此处输入图片描述

一些 NTFS 表被降级为巨大的链接列表,这些列表应该具有 O(1) 查找时间,但在这种情况下不再如此。我想知道有多少人受到这个问题的影响并相信一些专家的回答,即您不需要对 SSD 上的驱动器进行碎片整理......您不需要移动集群,但您仍然需要对 NTFS 表进行碎片整理,这肯定需要一些清理,正如我的三星 SSD 860 EVO 1TB 所示。在碎片整理运行了几天后,原始 HDD 问题确实一天天好转。我需要对 NTFS 中的某些内容进行“碎片整理”,但我不知道是什么。它不应该是卷位图,因为这只会影响 SSD 的快速寻道时间。

答案1

更大的扇区大小可能会稍微提高性能,但我认为不会提高太多。

我想说你的问题是在一个文件夹中有 42048 个文件。

Windows 文件夹功能本质上是顺序的,因此文件夹中的条目越多,每次操作需要读写的磁盘条目就越大,所需的搜索时间就越长。

我的建议是将文件夹分成几个较小的子文件夹,每个子文件夹包含的文件不超过几千个。

答案2

我遇到的问题是,在 1 或 2TB 的 NTFS 硬盘上打开一个包含大约 70 000 个文件、长度为 3-5MBytes 的文件夹需要 60-90 秒的时间,而使用 WinXP SP3 32 位系统则需要 60-90 秒。当我整理双重录音时,文件数量下降到大约 4000 个,此时资源管理器的行为正常。

我在检查您的 SMART 数据时遇到了困难。我认为 smartmontools 日志文件(参数“-a”)更容易读取。

你说:

慢速方法似乎是 NtfsScanEntireBitmap 调用的 NtfsInsertCachedLcnAtIndex。我怀疑 NTFS 位图已降级为一个非常长的列表。

不,不是列表。访问列表非常耗时。NTFS 位图实际上是存储在文件中的位图。给定一个簇号 x,您将粗略地检查文件位置处的字节向下舍入(x/8),并检查与 x MOD 8 等效的位以检查簇是否空闲。长度是在格式化驱动器时确定的。为了验证,我刚刚检查了我的 D 驱动器:长度为 107 734 683 648 字节,位图文件长度为 3 287 808。簇大小为 8x512 字节。14 GB 未使用。107 734 683 648/4096/8 大约为 3 287 808。通过将 MFT 条目设置为已删除并删除此文件使用的簇,删除文件的成本很低。但我想您可能必须重新平衡以树形式存储的目录列表,以防删除,也许还需要一些其他结构来跟踪空闲的连续集群区域。

每次删除都会影响此处描述的列表:

https://link.springer.com/article/10.1007/s11036-019-01441-1

https://www.researchgate.net/publication/338057560_Disk_Cluster_Allocation_Behavior_in_Windows_and_NTFS

如果您使用每个文件删除它们,则必须重新处理此列表以避免碎片整理。

我猜测所需时间的来源如下:

  1. 重新平衡目录树
  2. 重新平衡空闲集群列表。

附言:想了解您使用了哪些好用的小型调试工具来收集您提供的信息,并查看列出所有函数调用的时间日志。

相关内容