O_DIRECT 的真正含义是什么?

2023-11-25

如果我打开一个文件O_DIRECT标志,这是否意味着每当对该文件的写入(阻塞模式)返回时,数据都在磁盘上?


(这个答案适用于 Linux - 其他操作系统可能有不同的警告/语义)

我们先从子问题开始:

如果我打开带有 O_DIRECT 标志的文件,是否意味着每当对该文件的写入(阻塞模式)返回时,数据都在磁盘上?

No (as @michael-foukarakis 评论) - 如果您需要保证您的数据已到达非易失性您必须使用/添加其他东西的存储。

O_DIRECT 的真正含义是什么?

It's a hint您希望您的 I/O 绕过Linux内核的缓存。实际发生的情况取决于以下因素:

  • 磁盘配置
  • 无论您是打开块设备还是文件系统中的文件
  • If using a file within a filesystem
    • 使用的确切文件系统以及文件系统和文件上使用的选项
    • 您是否已正确对齐 I/O
    • 文件系统是否必须进行新的块分配以满足您的 I/O
  • 如果底层磁盘是本地的,那么在到达磁盘块设备之前,内核存储堆栈中有哪些层
  • Linux内核版本
  • ...

上面的列表并不详尽。

在“最佳”情况下,设置O_DIRECT将避免在传输数据时制作额外的数据副本,并且调用将在传输完成后返回。当直接打开“真实”本地磁盘的块设备时,您更有可能遇到这种情况。如前所述,即使是这个属性不保证成功的数据write()通话不会突然断电。如果数据从 RAM DMA 到非易失性存储(例如电池支持的 RAID 控制器)或者 RAM 本身是持久存储,那么您may保证数据能够在断电情况下稳定存储。要知道是否属于这种情况,您必须验证您的硬件堆栈,这样您就不能一般地假设这种情况。

在“最坏”的情况下,O_DIRECT即使设置没有被拒绝并且后续调用“成功”,也可能没有任何意义。有时 Linux 存储堆栈中的东西(例如certain文件系统设置)可以选择忽略它,因为它们必须执行的操作或者因为您不满足要求(这是合法的),而只是默默地执行缓冲 I/O(即写入缓冲区/满足从已缓冲的读取)数据)。目前尚不清楚是否会做出额外的努力来确保已确认写入的数据至少“与设备一起”(但在O_DIRECT克里斯托夫·赫尔维格 (Christoph Hellwig) 的帖子指出the O_DIRECT回退将确保数据至少已发送到设备)。进一步复杂化的是使用O_DIRECT暗示与文件元数据无关,所以即使 writedata通过呼叫完成“与设备一起”,关键文件元数据(例如文件的大小,因为您正在执行附加操作)可能不是。因此,您实际上可能无法获取您认为在崩溃后已传输的数据(它可能会显示被截断,或全部为零等)。

虽然简短的测试可以使它看起来像使用的数据O_DIRECT单独总是意味着写入返回后数据将位于磁盘上,更改内容(例如使用 Ext4 文件系统而不是 XFS)可能会以非常激烈的方式削弱实际实现的效果。

当您提到“保证数据”(而不是元数据)时,您可能正在寻找O_DSYNC/fdatasync()?如果您想保证元数据也被写入,您将不得不查看O_SYNC/fsync().

参考

  • Ext4 Wiki:澄清 Direct IO 的语义。还包含有关什么的注释O_DIRECT在一些非 Linux 操作系统上也是如此。
  • “[PATCH 1/1 linux-next] ext4:向补丁添加兼容性标志检查”LKML 线程有来自 Ext4 领导开发人员 Ted Ts'o 的回复,谈论如何进行文件系统可以回退到缓冲 I/OO_DIRECT而不是失败open() call.
  • 在“ubifs:允许 O_DIRECT”LKML 线程 Btrfs 首席开发人员 Chris Mason 中表示Btrfs 在以下情况下求助于缓冲 I/O:O_DIRECT对压缩文件有要求.
  • Linux 上的 ZFS 提交消息讨论的语义O_DIRECT在不同场景下。另请参阅(2020 年中期撰写本文时)提出新的O_DIRECTLinux 上 ZFS 的语义(交互作用很复杂,无法简单解释)。
  • Linux open(2) 手册页(搜索O_DIRECT in the 描述部分注释部分)
  • 确保数据到达磁盘绿网文章
  • 臭名昭著Linus Torvalds O_DIRECT LKML 线程摘要(有关更多上下文,您可以看到完整的 LKML 线程)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

O_DIRECT 的真正含义是什么? 的相关文章

随机推荐

  • 在 SQL Server 中定义一对一关系

    我需要定义一对一的关系 但似乎无法在 SQL Server 中找到正确的方法 您问为什么是一对一的关系 我使用 WCF 作为 DAL Linq 并且有一个包含 BLOB 列的表 BLOB 几乎不会改变 每次查询时传输它都会浪费带宽 我看了一
  • @ElementCollection 与 Map 其中 Entity 是 Embeddable 的字段

    在搜索了 JPA 文档和各种帖子后 我对 JPA2 0 是否可以实现以下操作感到困惑 我刚刚开始使用 JPA 所以如果我做了一些愚蠢的事情 请原谅 我的域模型有一个 投资组合 其中包含零个或多个 未平仓头寸 仓位由 工具 JPA 实体 和价
  • SQL Server 中索引的排序规则

    我感兴趣的是 在创建与该列的排序规则不同的索引时是否可以为该列指定排序规则 当建立索引时 字符串数据是根据列的排序规则还是数据库的排序规则排序 您可以使用所需的排序规则创建计算字段 并在此字段上创建索引
  • 在对象数组中添加匹配键的值

    我有一个数组 其中包含许多具有匹配键的对象 a 2 b 5 c 6 a 3 b 4 d 1 a 1 d 2 我想循环遍历数组 如果键匹配 我想将每个键的结果相加 并返回一个包含每个键之和的对象 i e a 6 b 9 c 6 d 3 我目前
  • 有没有办法在 EmberJS 中将数组传递给 currentWhen ?

    我试图使链接在多个路由上保持 活动 状态 例如 users 和 user 有任何想法吗 您可以重新打开 Ember 的 LinkView 并执行类似的操作 允许 currentWhen 包含空格分隔值 Ember LinkView reop
  • 如何使用 jQuery 更改 css 类规则?

    任何人都可以帮助我吗 我的问题有两个部分 我想做的是使用 jQuery 动态更改 css 类规则 classname color red font size 14px 在上面的示例中 我有一个名为 classname现在使用 jQuery
  • 如何在 mongoDB 中对 $lookup 结果应用条件?

    参考我之前的问题 我有一个关于 lookup 的问题 并添加一些条件 您可以从下面的链接描述中获得有关问题的足够参考 Photo id 1 photo name 1 jpg photo description description 1 a
  • 如何借助 Table 组件显示 JRBeanCollectionDataSource 数据?

    我需要在表组件 JasperReports 中显示 JRBeanCollectionDataSource 数据 这是我的模板 ShowPerson jrxml 文件
  • Bootstrap 3.3.5 中无法点击 form-control-feedback 中的链接

    我正在使用链接form control feedback span从 3 1 1 开始执行 javascript 函数 我正在尝试升级到 3 3 5 但是form control feedback改变了 请参阅工作 JsFiddle 3 1
  • 如何让 pandas.read_csv 不执行任何转换?

    例如 tmp test csv 中的值 即01 02 03 旨在代表strings恰好匹配的 d 与整数相反 In 10 print open tmp test csv read A B C 01 02 03 默认情况下 pandas re
  • 有没有办法使文件输入上的本机“浏览”按钮变大跨浏览器?

    如您所知 您可以使用 hacky 方法制作自己的文件输入控件 将文件输入定位在自定义按钮上并使用opacity 0在文件输入本身上 下图显示了预期的设计 其中文件输入绝对位于浏览按钮上方 正如您所看到的 人造浏览按钮比浏览器 Firefox
  • 如何使用 JQuery 格式化货币[重复]

    这个问题在这里已经有答案了 我正在尝试使用下面的代码来格式化货币 currency keyup function e var val this val val val replace 0 9 g if val length gt 2 val
  • 如何在 Firebase 中保存位置信息

    我正在尝试将位置 纬度和经度 保存为 Firebase 中的键 字段之一 在他们的例子中SF车辆 它们确实展示了如何在存储信息后进行查询 但我的问题是如何首先保存 在他们的博客文章中 GeoFire 走向移动 他们展示了数据的样子 但我如何
  • 本地计算机上的MySQL57服务启动然后停止

    当我尝试启动 SQL Server 时 会弹出一条消息 指出它已启动 但随后停止了 这发生在我的服务器重新启动后 有谁知道我该如何解决这个问题 确保数据目录为用户 网络服务 和管理员设置了完全权限 并且如果目录中有空格 则在目录名称周围加上
  • Twitter 关注者数量

    获取纯文本形式的关注者计数的唯一方法是使用 cURL 吗 或者 Twitter API 是否提供任何此类选项 https api twitter com 1 users lookup json screen name tvdw 我的个人资料
  • 无法监听JavaFX中的KeyEvent

    我希望我的 JavaFX 程序能够响应键盘事件 我尝试将侦听器添加到 rootPane 到最上面Pane 但它不响应事件 这是我的代码 AnchorPane root new AnchorPane root setOnKeyPressed
  • C# 6 中(自动)属性初始化语法之间的差异

    C 6 中用于初始化属性的以下表达式有什么区别 1 从构造函数初始化自动属性 public class Context1 public Context1 this Items new List
  • 通过套接字传输文件,最终大小较少字节

    我正在尝试通过 C 中的套接字接收一些文件 但是服务器向我发送了 1000000 字节文件的 64 字节数据包 并且我在目标文件上获得了大约 999902 字节 while n read sd buffer in BUFSIZE BUFSI
  • 如何在非唯一列中按日期对 pandas DataFrame 条目进行分组

    一只熊猫DataFrame包含名为 date 包含非唯一的datetime价值观 我可以使用以下方法对该框架中的线条进行分组 data groupby data date 然而 这将数据分割为datetime价值观 我想按 日期 列中存储的
  • O_DIRECT 的真正含义是什么?

    如果我打开一个文件O DIRECT标志 这是否意味着每当对该文件的写入 阻塞模式 返回时 数据都在磁盘上 这个答案适用于 Linux 其他操作系统可能有不同的警告 语义 我们先从子问题开始 如果我打开带有 O DIRECT 标志的文件 是否