内存索引节点和磁盘索引节点你俩到底是什么关系

1. 为什么会有“内存中的索引节点”?

首先,我们要明白索引节点(在UNIX/Linux中称为i-node,在一些教材中也泛称为文件控制块FCB)是存储在磁盘上的。它记录了文件的所有属性,如大小、权限、时间戳、以及指向数据块的指针等。

2. 哪些操作会改变“内存i-node”?

只要文件的元数据发生变化,内存i-node就会被修改。例如:

在这些操作发生后,内存中的i-node就已经和磁盘上的原始i-node不一致了。此时,内核会将这个内存i-node标记为**“脏”(Dirty)**,表示它“已被修改,需要写回磁盘”。

3. 什么时候“内存i-node”会被写回到“磁盘i-node”?

这正是你问题的关键。操作系统不会在每次修改后都立即写回,而是会在以下几种关键时机,将“脏”的内存i-node同步到磁盘:

  1. 文件正常关闭时 (close()):

    • 这是最常见和最重要的时机。我们之前讨论过,close()操作的一个核心职责就是确保数据和元数据的一致性。在关闭文件时,内核会检查其内存i-node是否为“脏”。如果是,就会将其内容写回到磁盘上对应的i-node中。
  2. 内核定期同步:

    • 现代操作系统(如Linux)中有名为syncbdflushkupdated的后台守护进程。它们会周期性地(例如每隔5秒或30秒)被唤醒,然后将在内存中所有“脏”的缓冲区数据和“脏”的i-node批量地写回到磁盘。这保证了即使系统长时间不关机,数据的安全性也能得到阶段性的保障。
  3. 用户或管理员强制同步:

    • 在Linux/UNIX系统中,执行sync命令会强制内核立即将所有脏数据和脏i-node写回磁盘。这在重要操作后或关机前非常有用。
  4. 应用程序主动请求同步 (fsync()):

    • 对于需要极高可靠性的程序(如数据库),它可以调用fsync()系统调用。这个调用会强制将指定文件的脏数据和脏i-node立即、同步地写回磁盘,并等待磁盘操作完成后才返回。这为应用程序提供了更精细的控制。
  5. 内存不足时:

    • 当系统内存紧张,需要回收内存页面时,如果一个“脏”的内存i-node所在的内存页被选中换出,系统也会先将其内容写回磁盘。

一个生动的比喻