第 22 章 写屏障
写屏障 是一种内核机制,用于确保正确写入文件系统元数据,并在持久存储上排序,即使具有易失性写缓存的存储设备断电。启用写屏障的文件系统可确保通过 fsync () 传输的数据在电源丢失过程中持久保留。
启用写屏障会给某些应用程序带来大量性能损失。具体来说,大量使用 fsync () 或创建和删除许多小文件的应用程序可能会运行得非常慢。
22.1. 写屏障的重要性
文件系统安全地更新元数据,确保一致性。Journalled 文件系统将元数据更新捆绑到事务中,并以以下方式将它们发送到持久性存储:
- 文件系统将事务正文发送到存储设备。
- 文件系统发送提交块。
- 如果事务及其相应的提交块写入了磁盘,则文件系统假定事务将在任何电源失败后都能生存。
但是,对于带有额外缓存的存储设备而言,电源失败期间文件系统的完整性会变得更加复杂。存储目标设备(如本地 S-ATA 或 SAS 驱动器)可能具有大小为 32MB 到 64MB 的写缓存(与现代驱动器)。硬件 RAID 控制器通常包含内部写缓存。此外,像 NetApp、IBM、Hitachi 和 EMC(其他人)的高端阵列也具有大型缓存。
当数据处于缓存中时,带有写缓存的存储设备会报告 I/O 为"完成";如果缓存断电,也会丢失数据。更糟糕的情况是,当缓存降级到持久存储时,它可能会更改原始元数据排序。发生这种情况时,提交块可能会出现在磁盘上,而没有完整的、相关的事务。因此,日志可能会在断电后的恢复期间将这些未初始化的事务块重新运行到文件系统中,这会导致数据不一致和损坏。
写障碍是如何工作的
在 Linux 内核中,写障碍是通过 I/O 前后的存储写缓存刷新实现的,这是 顺序关键的。写事务后,将刷新存储缓存,提交块被写入,然后再次刷新缓存。这样可确保:
- 磁盘包含所有数据。
- 未发生重新排序。
启用障碍后,fsync () 调用也会发出存储缓存清除。这样可保证文件数据在磁盘上持久保留,即使 fsync () 返回后不久发生断电。