当前位置: 首页 > news >正文

LWN:继续探索原子缓冲写(atomic buffered writes)

关注了就能看到更多这么棒的文章哦~

Jonathan Corbet
Gemini translation
原文链接:https://lwn.net/Articles/1060063/

许多应用程序需要能够将多块(multi-block)数据块写入磁盘,并确保该操作要么成功完成,要么完全失败——换句话说,写入操作不会部分完成(即“撕裂” [torn])。多年来,内核开发人员一直致力于提供原子写(atomic writes)作为满足这一需求的一种方式;例如,可以参考 2023 年、2024 年和 2025 年(两次)的 Linux 存储、文件系统、内存管理和 BPF (LSFMM+BPF) 峰会的相关议题。虽然目前一些文件系统已经支持原子直接 I/O(atomic direct I/O),但原子缓冲 I/O(atomic buffered I/O)仍不支持。填补这一空白似乎肯定会成为 2026 年 LSFMM+BPF 的主题,但得益于早期的讨论,解决方案的雏形可能已经开始显现。

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)。但看起来通往原子缓冲写的道路正开始变得清晰。在问题完全解决之前,可能还需要再进行六次左右的 LSFMM+BPF 会议。

LWN 评论概述:

评论区对这一漫长的开发周期进行了调侃,有用户笑称“再开六次左右的会就能解决问题”。

有用户询问原子写在带有掉电保护(Power Loss Prevention, PLP)和不带 PLP 的驱动器上的实现差异,好奇 PLP 驱动器在数据库工作负载中是否表现更佳。

此外,读者指出通写行为在一般场景下也很有用,例如文件管理器在向可移动设备复制数据时可以利用它,从而避免出现“文件复制飞快但弹出设备却需要数分钟”的意外。还有读者对 LWN 关于文件系统的深度文章表示感谢,认为这些内容填补了该领域的知识空白。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

http://www.jsqmd.com/news/488380/

相关文章:

  • all-MiniLM-L6-v2部署实战教程:Ollama一键启用轻量级Embedding服务
  • Phi-3-vision-128k-instruct开发者指南:如何验证服务状态与调试日志
  • SAP MRP供应元素业务解析
  • Z-Image-Turbo-rinaiqiao-huiyewunv 自动化测试:构建软件测试面试题中的图像生成验证用例
  • 多模态智能客服架构设计与实战:从语音识别到意图理解的工程实践
  • 027_Mrs Smith s living room
  • Qwen All-in-One场景应用:打造智能客服与社交媒体舆情初筛系统
  • vibe-coding实战指南
  • e9-流程引擎
  • 音乐元数据繁简转换解决方案:Music Tag Web实战指南
  • 3个突破方案:SRWE窗口分辨率自定义实用指南
  • 13:现代人脸匹配深度学习:CNN、FaceNet与Siamese网络数学推导
  • VMware替代技术深度拆解:轻量进化,浪潮云海InCloud Sphere的全栈技术突破
  • 大数据架构中的隐私计算:联邦学习与多方安全计算
  • 14:全球犯罪记录数据库构建:户籍+公开档案的SQL/NoSQL整合架构
  • 【AI解析】无人船(USV)控制系统分层架构与主程序流程图
  • 航空业社会工程学攻击特征分析与多维防御体系构建
  • 基于Android毕业设计的效率提升实战:从项目搭建到性能优化的全流程指南
  • 用 AI 多角度出图,电商产品图有救了!
  • 2026 企业级高可用架构白皮书:基于 Cosvice 体系与 N.V11.34.6 协议的全链路深度优化
  • LeetCode-121:买卖股票的最佳时机,不用双重循环也能一遍做出来
  • OpenClaw 生产级部署实录:Ubuntu 服务器 × MiniMax × 飞书(Lark) 完整集成指南
  • Thinkphp和Laravel框架微信小程序社区老年人活动志愿者服务系统
  • 15:社交媒体数据采集基础:API调用与合规爬取流程
  • 新手必看:如何用sys.path.append()解决Python模块导入失败问题(附真实案例)
  • Skills Hub 可视化管理桌面工具发布 v0.3:一大波功能更新!
  • 车桥耦合Ansys建模资料两套 一套是Ansys apdl命令流建模,另一套是Ansys+ma...
  • 基于多元宇宙优化算法的储能充放电策略优化研究(Python代码实现)
  • 独家揭秘:大模型Agent的“大脑”是怎么工作的?——ReAct框架完全指南
  • C++虚函数:解密多态核心机制