在前面的《SSD科普三十二》中,我们介绍了一次 Read Path 是如何完成的。

当 Host 想读取数据时,它只需要告诉 SSD 一个 LBA。

SSD 通过 FTL 查询映射关系,找到这个 LBA 当前对应的数据位置,然后经过 NAND Read、ECC 校验,最终把正确的数据返回给 Host。

但是这里留下了一个新的问题:

如果用户不想要这份数据了呢?

比如:

删除一张照片。

删除一个视频。

清理电脑中的垃圾文件。

很多人会认为:

文件删除以后,SSD应该马上知道,然后把对应的数据删除。

但实际情况并不是这样。

因为:

SSD根本不知道你删除了什么文件。

那么问题来了:

用户明明点击了“删除”,为什么 SSD 却不知道?

这正是今天要讲的内容。


一、用户看到的是文件,SSD看到的是LBA

我们平时使用电脑时,面对的是文件。

例如:

旅行照片.jpg

项目文档.doc

电影.mp4

我们可以:

  • • 打开文件;
  • • 修改文件;
  • • 删除文件。

但是,这些概念属于操作系统中的文件系统。

文件系统负责管理:

哪个文件存在哪里,占用了哪些空间。

而 SSD 并不认识这些东西。

SSD 不知道:

  • • 哪个 LBA 属于照片;
  • • 哪个 LBA 属于视频;
  • • 哪个 LBA 属于系统文件。

SSD 看到的世界非常简单:

Host 给我一个逻辑地址,我负责存储和返回对应的数据。

例如:

LBA 1000~1999

对于 SSD 来说,它只知道:

这些逻辑地址对应某些 NAND 中的物理位置。

至于这些数据原来是什么文件,SSD并不知道。


二、文件系统和SSD之间隔着一个逻辑地址

为了理解为什么删除文件 SSD 不知道,我们需要先看一下数据存储的过程。

用户保存一个文件:

照片.jpg

首先由文件系统管理。

文件系统可能分配:

LBA 1000~1999

用于保存这份文件。

然后,这些 LBA 会交给 SSD。

SSD 内部的 FTL 再建立:

LBA → NAND物理地址

的映射。

因此,一份文件真正经过了两个转换:

文件
↓
文件系统分配逻辑地址
↓
LBA
↓
FTL映射
↓
NAND物理位置

这里有一个关键点:

文件名只存在于文件系统中。

SSD内部只关心:

哪些 LBA 需要保存,哪些数据需要返回。


三、删除文件时,首先发生变化的是文件系统

假设:

现在有一个文件:

photo.jpg

文件系统记录:

photo.jpg
↓
LBA 1000~1999

当用户点击删除以后,文件系统首先做的事情是什么?

不是通知 SSD 擦除 NAND。

而是:

删除文件记录,并释放这些逻辑空间。

也就是说:

原来:

LBA 1000~1999 属于 photo.jpg

删除以后:

这些逻辑空间以后可以重新分配给新的文件。

从文件系统角度来看:

这个文件已经不存在了。

但是:

SSD里面的数据呢?

其实可能还存在。


四、为什么文件系统释放空间后,还需要告诉SSD?

看到这里,很多人可能会问:

既然文件已经删除了,为什么还需要额外通知 SSD?

原因是:

文件系统知道的事情,SSD并不知道。

假设:

SSD里面:

LBA 1000
↓
NAND Page A

用户删除文件。

文件系统:

这部分空间不用了。

但是 SSD:

我不知道。

如果没有额外通知,SSD 仍然可能认为:

LBA 1000 对应的数据还是有效数据。

这会带来一个问题:

SSD内部有一个重要机制:

Garbage Collection(垃圾回收)。

我们之前讲过,NAND不能覆盖写。

当数据更新时:

旧数据不会直接被覆盖,而是会变成无效数据。

SSD需要在合适的时候回收这些空间。

但是 GC 需要知道:

哪些数据还有效。

哪些数据已经没有意义。

如果 SSD 不知道用户已经删除的数据,那么它只能保守处理:

认为这些数据仍然有效。

结果就是:

  • • 回收时需要搬迁更多数据;
  • • 增加 NAND 写入次数;
  • • 增加写放大;
  • • 影响 SSD 性能。

五、SSD需要一种机制知道“哪些数据不用了”

所以,SSD需要一个额外的信息。

这个信息不是:

删除哪个文件。

因为 SSD 根本不知道文件。

而是:

哪些逻辑地址的数据以后不需要保存。

也就是说:

Host需要告诉 SSD:

这些 LBA 已经没有有效用户数据。

这就是后来的 TRIM 机制。

在 SATA SSD 中,这个机制通常称为 TRIM。

而在 NVMe SSD 中,对应的是 Dataset Management Command 中的 Deallocate 操作。

NVMe规范定义 Dataset Management Command 用于 Host 向 SSD 提供逻辑块范围的信息,其中包括 Deallocate 属性。


六、TRIM并不是“删除数据”

这里需要特别强调一个容易误解的地方。

很多人第一次听到 TRIM,会认为:

TRIM就是告诉SSD立即删除数据。

其实不是。

TRIM真正表达的是:

这些逻辑地址中的数据已经不再需要保存。

它解决的是:

让 SSD 知道哪些数据已经失效。

而不是:

立即擦除 NAND。

因为 NAND Flash 有自己的限制:

数据写入以 Page 为单位。

但是擦除只能以 Block 为单位。

所以 SSD 不可能收到删除通知以后,马上找到对应 Page,然后直接擦除。

真正的空间回收,需要后续通过 Garbage Collection 完成。


七、从删除文件到SSD知道,中间发生了什么?

整个过程可以简单理解为:

用户删除文件

↓

文件系统删除文件记录,释放对应逻辑空间

↓

操作系统通知 SSD:这些 LBA 已经不再需要

↓

SSD 更新内部状态

↓

后续 Garbage Collection 回收空间

其中最关键的一步就是:

把“文件系统认为空间释放了”这个信息传递给 SSD。

因为:

文件系统知道文件。

SSD知道LBA。

两者之间需要一个桥梁。


八、为什么要专门讲TRIM?

从用户角度看:

删除文件似乎只是一个简单操作。

但是从 SSD 角度看:

它涉及三个不同世界:

文件系统世界

负责:

文件、目录、空间管理。

↓

块设备世界

负责:

逻辑地址。

↓

SSD世界

负责:

LBA到NAND物理位置的映射。

用户删除一个文件以后:

真正的问题不是:

SSD怎么删除这个文件?

而是:

SSD怎么知道这个文件对应的数据已经没有价值?

TRIM正是为了解决这个问题而出现。


下一篇,我们继续讲:

SSD科普三十四:SSD知道数据不要了,为什么还不直接删除?

我们会进一步介绍:

  • • TRIM和NVMe Deallocate有什么区别;
  • • SSD收到Deallocate以后,FTL如何处理;
  • • 为什么TRIM不会立即擦除NAND;
  • • TRIM如何影响GC和写放大。

从这一篇开始,SSD的数据生命周期又进入了新的阶段:

数据写进去以后,如何被读取;
数据不要以后,如何被释放。

谢谢你读我的文章