LWN:继续探索原子缓冲写(atomic buffered writes)
关注了就能看到更多这么棒的文章哦Jonathan CorbetGemini translation原文链接https://lwn.net/Articles/1060063/许多应用程序需要能够将多块multi-block数据块写入磁盘并确保该操作要么成功完成要么完全失败——换句话说写入操作不会部分完成即“撕裂” [torn]。多年来内核开发人员一直致力于提供原子写atomic writes作为满足这一需求的一种方式例如可以参考 2023 年、2024 年和 2025 年两次的 Linux 存储、文件系统、内存管理和 BPF (LSFMMBPF) 峰会的相关议题。虽然目前一些文件系统已经支持原子直接 I/Oatomic direct I/O但原子缓冲 I/Oatomic buffered I/O仍不支持。填补这一空白似乎肯定会成为 2026 年 LSFMMBPF 的主题但得益于早期的讨论解决方案的雏形可能已经开始显现。Pankaj Raghav 于 2 月 13 日发起了这项讨论指出 ext4 和 XFS 现在在使用直接 I/O 时都支持原子写但支持原子缓冲 I/O “仍然是一个有争议的话题”。目前有两个尚未落实的提案旨在添加此功能一个是 John Garry 在 2024 年提交的系列补丁另一个是 Ojaswin Mujoo 最近提交的补丁集。这些提案停滞不前部分原因是担心 I/O 路径增加的复杂性以及原子缓冲写是否真的有必要。PostgreSQL 数据库经常被提及为该功能的潜在用户与许多其他数据库管理系统不同它使用缓冲 I/O。PostgreSQL 的代码通常必须费尽周折来确保部分的 I/O 操作不会损坏数据库有时甚至会牺牲性能。PostgreSQL 是一个重要的用户但并非所有开发人员都确信原子缓冲写是解决其问题的办法例如Christoph Hellwig 评论道“我认为更好的议题应该是我们如何帮助 postgres 摆脱缓冲 I/O而不是为它们增加更多的特殊情况。”PostgreSQL 开发人员 Andres Freund 回应称该项目确实正在致力于添加直接 I/O 支持但其性能尚未达到缓冲 I/O 方法的水平。但他表示直接 I/O 仅对某些大型安装场景有用。对于较小的系统或者数据库作为具有自身内存需求的较大型应用程序的一部分运行的系统内核可以管理内存分配的缓冲 I/O 设置仍然表现更好。他指出即使直接 I/O 成为 PostgreSQL 的一个具有竞争力的选项“超过 50% 的用户”仍然无法从中受益。对话中的大多数开发人员似乎都接受原子缓冲 I/O 有其合理的用例尽管 Hellwig 仍然持保留意见。不过达成“有一个解决方案会很好”的共识本身并不能产生解决方案。原子直接 I/O 是一个复杂的问题需要内核在整个过程中将 I/O 请求保持在一起直到最终写入存储设备。缓冲 I/O 增加了复杂性因为这些操作必须经过页缓存page cache而且实际的写入操作通常是在内核抽出时间时的另一个时间点执行的。在内核中以这种方式跟踪原子性要求并防止多个操作相互干扰并非易事。在讨论初期Mujoo 建议一种可能的解决方案是对原子缓冲写使用通写writethrough语义。换句话说当用户空间发起请求原子行为的缓冲写时这将通过使用带有RWF_ATOMIC标志的pwritev2()来完成内核将立即启动将数据写入磁盘的过程。这将允许创建一个短期的固定pin以将页面保留在内存中如果装满数据的页面在操作过程中被推送到交换分区 [swap]则很难执行原子写并允许内核在操作进行期间防止对这些页面的任何其他更改。这样就不需要寻找一种方法来跟踪页缓存中脏数据dirty data的原子写了。Jan Kara 同意通写行为可能会很有趣。他说这将允许重用许多现有的直接 I/O 基础设施从而使解决方案变得简单得多。他说真正的问题在于通写行为是否对 PostgreSQL 有用。Freund 回答说通写确实会有用即使在没有原子行为的情况下也是如此。他建议通过要求原子缓冲写在包含RWF_ATOMIC的同时包含一个新的RWF_WRITETHROUGH标志来实现这样如果内核以后实现了不带通写的原子缓冲写用户空间就不会看到行为变化。Raghav 询问了提议的RWF_WRITETHROUGH标志与现有的RWF_DSYNC之间的区别指出前者可能像大多数缓冲写一样是异步的而后者是同步的。然而Dave Chinner 不同意这种解释他认为通写行为本质上是同步的以便可以立即报告错误。他说获得异步行为的方法是使用异步 I/O 接口asynchronous-I/O interface或io_uring。但他表示RWF_WRITETHROUGH本身在行为上应与直接 I/O 写入完全相同允许使用现有的 I/O 路径来实现它。RWF_DSYNC仍然会有所不同因为它强制存储设备将数据提交到持久介质而RWF_WRITETHROUGH不会执行那个额外的步骤意味着数据可能会保留在设备的写缓存中。为了尝试总结讨论Raghav 发布了一组提议的结论第一步将是实现提议的通写行为并立即启动请求的操作。然而仅靠通写并不能保证原子行为因此还有更多工作要做。下一步将是确保正在写入的数据在操作进行期间不被修改。幸运的是内核长期以来一直有一种机制——稳定页stable pages可以派上用场。通过防止对正在写入的缓冲区进行修改内核可以防止数据损坏。后续步骤将包括在开始操作之前小心地将完整数据范围复制到页缓存中并确保缓冲区是在单个原子操作中写入的。不可避免地还会有其他细节需要处理例如指定和强制执行用于原子写的缓冲区的对齐要求alignment requirements。但看起来通往原子缓冲写的道路正开始变得清晰。在问题完全解决之前可能还需要再进行六次左右的 LSFMMBPF 会议。LWN 评论概述评论区对这一漫长的开发周期进行了调侃有用户笑称“再开六次左右的会就能解决问题”。有用户询问原子写在带有掉电保护Power Loss Prevention, PLP和不带 PLP 的驱动器上的实现差异好奇 PLP 驱动器在数据库工作负载中是否表现更佳。此外读者指出通写行为在一般场景下也很有用例如文件管理器在向可移动设备复制数据时可以利用它从而避免出现“文件复制飞快但弹出设备却需要数分钟”的意外。还有读者对 LWN 关于文件系统的深度文章表示感谢认为这些内容填补了该领域的知识空白。全文完LWN 文章遵循 CC BY-SA 4.0 许可协议。欢迎分享、转载及基于现有协议再创作长按下面二维码关注关注 LWN 深度文章以及开源社区的各种新近言论
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2417993.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!