假设我们正在谈论一个普通的 USB 闪存驱动器(可能具有或不具有磨损均衡功能)和一个没有针对闪存进行特别优化的“哑”文件系统(例如 FAT32 等)。该驱动器可能不支持 TRIM。
由于闪存驱动器块的重写次数有限,因此尝试尽可能减少重写次数是有意义的。现在,如果我要创建一些文件 A、B 和 C,然后反复就地修改文件,这会对驱动器造成更大的磨损,而不仅仅是添加 B'、C' 等,并最终在空间不足时删除原始文件?
我是否过早进行了优化,或者其中是否有一些道理?
(注:本文不是关于驱动器或操作系统内部是如何运作的。这是关于用户应该使用它)
答案1
所有 USB 驱动器都有一个微控制器,它接收传入的 USB 请求并将其转换为与 USB 设备上的实际存储一致的操作。
对于具有 NAND 闪存的 USB 驱动器,这些设备上的固件/微控制器很可能(希望)实现具有磨损均衡功能的 FTL。
不幸的是,如果您不知道任何固件的源代码,也不完全了解 USB 闪存驱动器上的小型硬件平台,您就无法知道该微控制器到底在做什么。
对于 USB 闪存驱动器,没有所谓的标准硬件、固件或软件平台,因此,如果您不熟悉相关的微控制器、NAND 闪存硬件和固件,就无法依赖任何标准来帮助您准确预测固件对传入的 USB 请求可能执行的操作。
这与驱动器或操作系统的内部功能无关。
我知道,但如果没有这些内部知识,你就无法有意义地修改写入行为。尤其是因为有各种微控制器、固件和 NAND 闪存芯片,对一个闪存驱动器可能有效的东西可能对另一个闪存驱动器无效。
未针对闪存进行特别优化的“哑”文件系统
“针对闪存优化”的文件系统需要直接访问闪存硬件,以便它们可以自己向闪存发出擦除命令。通过 USB、SATA、SCSI 总线使用大容量存储命令与设备通信不是直接访问。
最容易遇到这种情况的可能就是基于 Linux 的消费级路由器 - 底层 Linux 操作系统已打开,可以访问 4MB、8MB、16MB 或类似的闪存芯片,并可以直接与其通信和管理它。Android 手机也类似。
您不能在除 TRIM 之外的 USB 或 SATA 大容量存储设备上发出擦除命令(这只是对设备固件的请求,而不是对闪存芯片的直接命令),这些标准适用于硬盘驱动器而不是闪存硬件。
现在,如果我要创建一些文件 A、B 和 C,然后反复就地修改文件,这会对驱动器造成的磨损是否比仅仅添加 B'、C' 等更大?
闪存芯片以页面为单位进行读写。它们以 Linux 项目称为“擦除块”的页面集为单位进行擦除。(这与机械硬盘非常不同)。
基于闪存的存储设备实现了 FTL - 闪存转换层。它的含义是:它们维护一个内部表,将操作系统可见的“块”映射到固件可见的闪存页面(PBA 到 LBA),并且它们还将跟踪哪些“擦除块”已准备好写入新数据。传入的写入不会仅根据传入的块号进入闪存页面,而是进入固件认为合适的位置 - 并且固件将更新其内部 PBA 到 LBA 表,以便在下次需要时找到它。
好的固件会尝试将写入重定向到具有已擦除页面的擦除块,以提高性能,并且它们会在后台交换块,以尝试在写入之前无需擦除。当驱动器已满时,不太可能做到这一点,并且性能会受到影响。
然后,您可以假设,即使从操作系统的角度来看是同一个文件和“块”,写入也不会到达闪存上的同一个位置。因此,担心修改文件对您没有任何好处。
这个故事的寓意是:不要担心。像对待普通硬盘一样对待它,并保留备份。劣质闪存驱动器会比优质闪存驱动器更早报废。