如何以编程方式模拟文件损坏以测试 ReFS 健康检查和恢复功能?

How to programmatically simulate file corruption to test ReFS Health Check and Recovery features?

我想以编程方式测试 Windows ReFS Health Check and Recovery 功能。

注意:ReFS 仅检测位腐烂(无自我修复)。要让 ReFS 同时 检测和自动修复,还必须使用存储 Spaces。因此,我已经准备了一个存储镜像 Space 池 S:\,具有 2 路镜像设置。

ReFS 完整性流已启用,

PS C:\> Set-FileIntegrity -FileName 'S:\' -Enable $True

根据找到的说明 here

如何以编程方式模拟文件损坏以测试 ReFS 运行状况检查和恢复功能?

我找不到一个简单的方法来介绍 bit-rot。我尝试过的所有系统都只执行 ReFS 可接受的合法更改。

如果可能,PowerShell 方法最好。 Perl,Python 或任何其他好东西。

提前谢谢你。

听起来您想绕过文件系统直接写入底层存储。这意味着直接写入 disk/partition/volume。 在 Windows 中,这可以通过处理较低级别的构造来完成,例如 \.\PhysicalDrive0 - 您可以打开此类设备的 "file" 句柄并直接写入扇区。您可能会发现一些低级工具可以做到这一点。

在 Linux 中这更容易一些,因为您可以使用 dd 写入任何块设备。

如果您的 Windows 机器是虚拟机,那么从主机编辑 VHDX 文件("hard disk")可能是最简单的方法,或许可以使用 HEX 编辑器。

将特定文件映射到包含其数据运行的磁盘扇区可能有点困难。有多种方法可以检测数据的真实位置,但您可以采用一种简单的蛮力方法,即写入一段看似独特的特定数据,然后扫描整个磁盘来找到它。

要创建损坏,请使用 Hard Disk Sentinel Pro 中的破坏性写入测试。将其设置为随机而不是顺序工作。我将其设置为写入随机位模式。只需 运行 一到三分钟,您就会在显示的地图上看到整个驱动器上的一大堆点都被摧毁了。

这是我做一些测试的方法(我打字很快,所以我希望我没有遗漏任何东西)

  1. 几乎用文件填满 ReFS 镜像存储 space。

  2. 为所有文件启用文件完整性:

    Get-ChildItem -Path 'i:*' -Recurse |设置文件完整性-启用 $True -强制 $False

我们稍后使用 Enforce $True 进行另一项测试,但先进行 false 测试。稍后你会明白为什么。阅读启用和强制执行。

  1. 移除其中一个驱动器并将其连接到第二台计算机上的 SATA 端口。
  2. 在第二台计算机上,使用 Hard Disk Sentinel 引入文件损坏
  3. 删除损坏的驱动器并将其放回第一台具有存储 space 的计算机中。您现在将拥有一个镜像存储 space,其中一个驱动器正常,一个驱动器有一堆损坏的文件。

尝试将存储 space 中的所有文件批量复制到其他驱动器。

我的测试表明几乎没有任何东西得到修复,事件日志中几乎没有任何显示。也许一两个错误,仅此而已。您可能认为一开始并没有太多损坏。那么现在设置 Enforce $True 并再次执行复制操作。启用 Enforce 后,副本将在数十个具有校验和错误的文件处停止——证明 ReFS 在这种情况下正在查看校验和。

问题是日志中几乎什么也没有显示。此外,在启用 Enforce 的情况下,我在关闭 Enforce 的第一次测试期间应该修复的一个文件上出现了校验和错误!

检查这些线程:

Why Use ReFS?

ReFS test with corrupt data. Does it work

Has anyone run the Data Integrity Scan on an ReFS volume?

ReFS/Storage Spaces 确实会不时地记录一个问题,人们会看到它,所以他们就认为它工作得很好。此外,人们找不到创建测试损坏的好方法,因此他们不会费心进行测试。我在 Windows 10 Pro for Workstations SKU 上进行了测试,结果很糟糕。

请运行自己做一些测试来证实我的发现。

只是一个警告:你需要非常,非常非常,如果你决定启用[=129],请小心=]完整性流。

精简版

Integrity Streams 禁用所有弹性,并会导致 ReFS 删除有读取错误的文件。

长版

启用 Integrity Streams 后出现读取错误,ReFS 将删除错误文件。

  • 如果您有一个 300 GB 的文件(例如 WindowsSever2012R2_prod.vhdx)
  • 并且 ReFS 甚至检测到 单个 不可纠正的位
  • 它将删除整个文件

没有确认。没有警告。没有上诉。

一个不可恢复的读取错误,所有数据都消失了。如果您不喜欢它:您不应该启用 integrity 流。

这种行为非常安静 documented,使用非常无害的术语:

Resilient File System (ReFS) overview

Key Benefits

Resiliency

  • Salvaging data - If a volume becomes corrupted and an alternate copy of the corrupted data doesn't exist, ReFS removes the corrupt data from the namespace. ReFS keeps the volume online while it handles most non-correctable corruptions, but there are rare cases that require ReFS to take the volume offline.

(强调我的).

Storage Spaces 将在 Windows 事件日志中记录您的数据现已消失:

  • Source: Microsoft-Windows-ReFS
  • Event ID: 513

(Warning): The file system detected a corruption on a file. The file has been removed from the file system namespace. The name of the file is "M:\VirtualDisks\WindowsServer2012R2_Prod.vhdx".

所以,"warning",我们删除了一个虚拟服务器,以及上面的所有东西,因为我们发现了一个坏点。

通过启用 Integrity 流,您特别选择加入此*非*弹性功能。

可能数据并未真正删除

文档说明:

ReFS removes the corrupt data from the namespace

这是真的;您在任何地方都找不到该文件 - 它已经消失了。如果您有一个 1.2 TB 的数据库文件,并且有一个不可恢复的位,那么您的 1.2 TB 数据就消失了——就像删除一个文件一样。

但是文件继续用完存储 space 中的 space。换句话说,它似乎文件实际上仍然保留着,但它是"inaccessible".

但是鉴于没有记录或已知的方法来再次制作文件"accessible"(即"undelete"),结果是一样的——你的数据被删除了。

所以请注意

完整性流的基本设计目标是:

  • 我们宁愿删除您的数据
  • 比暴露读取错误

如果您启用完整性流:那么您同意您宁愿删除数据也不愿冒险返回部分数据。

我想不出在任何情况下,在任何地方,在任何行业,在世界的任何地方,有人会想要他们的 "resilient" 文件系统故意删除 EVERYTHING 在一个读取错误的情况下。

但这就是您的要求。

我猜有点有道理:

  • "i valid integrity"
  • "over resiliency"

如何模拟

运行 HxD 以管理员身份,打开 \.\PhysicalDiskx 写入:

翻转一位,然后保存。

我不会真的为这个演示做这件事,因为在我的三向镜像上我启用了完整性流;而且我不想丢失所有数据。

更新:也许您可以选择不丢失所有数据

我是 运行 命令以确保我已经完全禁用 Integrity Streams 的任何意外使用,并且 Get-FileIntegrity 的输出有一些东西奇数:

PS M:\> Get-Item . | Get-FileIntegrity

FileName  Enabled  Enforced
--------  -------  --------
M:\       False    True

"Enforced" 到底是什么意思? Integrity Streams 怎么会是 "enforced on",却没有启用?像往常一样,documentation of Get-FileIntegrity 不包含文档。

所以我尝试检查 documentation of Set-FileIntegrity;它有一些东西!

-Enforce

Indicates whether to enable blocking access to a file if integrity streams indicate data corruption.

If you specify a value of $True for this parameter, the cmdlet also enables integrity for the file.

就是这样!

  • 这是默认损坏的功能,
  • 这将导致您完全丢失数据
  • 如果出现最微小的不可纠正的读取错误

妈妈叉衬衫球。谁提出了那个 fork bench。

默认情况下它是打开的!默认情况下绝对 不会 启用该功能!该功能甚至不应该存在!

所以现在我是 运行 递归设置选项的命令:

  • 完整性流:禁用
  • 静默删除您的所有数据:禁用

命令

首先是查找任何已启用完整性的文件的命令:

PS M:\> Get-ChildItem -Recurse | Get-FileIntegrity | Where {$_.Enabled -EQ $true}

FileName                                    Enabled Enforced
--------                                    ------- --------
M:\Folder1\Folder 2\The Video File 102.mkv  True    True
M:\Folder1\Folder 2\The Video File 101.mkv  True    True
M:\Folder1\Folder 2\The Video File 103.mkv  True    True
M:\Folder1\Folder 2\The Video File 104.mkv  True    True
M:\Folder1\Folder 2\The Video File 108.mkv  True    True
M:\Folder1\Folder 2\The Video File 109.mkv  True    True
M:\Folder1\Folder 2\The Video File 105.mkv  True    True
M:\Folder1\Folder 2\The Video File 111.mkv  True    True
M:\Folder1\Folder 2\The Video File 106.mkv  True    True
M:\Folder1\Folder 2\The Video File 107.mkv  True    True
M:\Folder1\Folder 2\The Video File 112.mkv  True    True
M:\Folder1\Folder 2\The Video File 110.mkv  True    True

所以,是的,我有一些数据存在风险。现在我们要关闭它:

PS M:\> Get-ChildItem -Recurse | Get-FileIntegrity | Where {$_.Enabled -EQ $true} | Set-FileIntegrity -Enable $False

红利阅读

我只想指出,我在最新的 Windows 11 上测试了此行为,以下是我的观察结果:

1 - 如果您有镜像存储空间,并且单个磁盘上的文件中有数据损坏,REFS 会在启用完整性流的情况下自动为您修复它 Ref Image -> 1

2 - 如果两个磁盘都损坏,REFS 将阻止对该文件的访问,但不会删除它。您可以通过手动将强制标志更改为 false(例如 Get-Item 'E:\claclaboth.txt' | Set-FileIntegrity -Enable $True -Enforce $False)Ref Image -> 2[=12 来重新获得对该文件的访问权限=]

3 - 从任务调度程序(在 Windows -> 数据完整性检查和扫描下)定期清理似乎在 Windows 11 上仍然无所事事,但数据完整性扫描任务似乎确实正确刷盘,你只需要添加一个触发器来调度它,否则它永远不会运行。

根据以上发现,我认为您可以将强制标志保留为默认值,因为 REFS 不会删除您的文件,只会阻止它。

撇开性能问题不谈,如果想要类似 ZFS 的弹性但需要继续使用 Windows,REFS 现在似乎成熟多了。