最近和文件系统内核开发人员做技术交流,对O_DIRECT选项有了新的认识。
 

在 InnoDB存储引擎的配置中参数innodb_flush_method通常设置为O_DIRECT,这也是官方文档所推荐的设置值。DBA或开发人员 知道该参数是文件打开的一个标识,启用后文件的写入将绕过操作系统缓存,直接写文件。其在InnoDB存储引擎中的表现为对于写入到数据表空间将绕过操作 系统缓存。这样设置通常不会有更好的性能,但是数据库已经有自己的缓存系统,这样的设置可以确定数据库系统对于内存的使用。下面是man手册中对于 O_DIRECT选项的说明:

Try to minimize cache effects of the I/O to andfromthis file.In general this will degrade performance, but it is useful in special situations, such aswhen applications do their own caching.

然而在源码内,细心的读者可能会产生一些困惑,因为不管参数innodb_flush_method的设置为何值,在刷新脏页时都会调用fsync操作,具体见函数buf_flush_buffered_writes。那么,当用户已经打开文件操作的O_DIRECT标识,为什么还需要进行一次fsync操作确保文件的写入呢?
 
最早发现这个问题的是Facebook的MySQL团队负责人Mark Calleghan。其在2009年时在MySQL数据库的官方论坛中提交Bug #45892,当年看到此Bug的回复时还是有些疑惑,因为其答复的诸如xfs这类文件系统,有些元数据还需要通过fsync进行刷新。公司同事花花也有问过我同样的问题,不知道是否在做云硬盘时遇到了类似问题。
 
最近和文件系统内核开发人员做交流,其对ext4的文件系统做了简单的介绍,自己对文件系统有了重新认识,对之前Bug的回复也有了更为清楚的理解。在有些文件系统中,例如ext4、xfs,文件(包括目录,在Linux中所有对象都是文件)都有一个inode与之对应,其保存有两部分的内容,元数据和文件的存储数据。根据wiki的介绍,元数据包含的内容有:
  • 文件的字节数
  • 文件的权限
  • 文件的时间戳
  • 链接的数量,即有多少文件指向该inode
  • 指向数据块的链接
  • etc
可 以发现元数据及其重要的,不仅仅是文件最后修改时间、权限等信息,它还包含有指向存储块的信息。若在数据增长时,元数据没有及时更新,那么同样可能会导致 数据丢失的情况。虽然此时,数据可能在磁盘上,但文件不知道那些块也是其组成部门。可以看到,这也是MySQL官网对上述Bug中的回复:

For example,if a file grows while O_DIRECT is enabled it will still write to the new part of the file, however since the metadata doesn't reflect the new size of the file the tail portion can be lost in the event of a crash.

 
inode中的元数据是保存在inode cache中,inode的保存文件的数据是保存在操作系统缓存中(若未开启O_DIRECT标识)。读者可以观察下图Linux文件系统的实现方式:
fsync操作会同步上图中的Inode cache,Buffer cache(也就是操作系统缓存),Directory cache。 因此这就是为什么InnoDB存储引擎即使在文件打开时加上O_DIRECT标识,刷新脏页依然需要fsync操作。这是因为O_DIRECT标识只是忽 略了图中Buffe cache。刷新文件的另一个函数fdatasync,其仅刷新buffer cache的内容到磁盘,因此比fsync有更好的性能,但是存在数据丢失的风险。
 
若用户想通过O_DIRECT写入文件,但避免可能存在的潜在风险时,可以再加上O_SYNC标识,此时写入实际变为了一个同步写(synchronous I/O)操作,因此不再需要额外的fsync操作。见man手册中的说明:

The O_DIRECT flag on its own makes an effort to transfer data synchronously, but does not give the guarantees of the O_SYNC flag that data and necessary metadata are transferred.To guarantee synchronous I/O, O_SYNC must be used in addition to O_DIRECT.

 
未完待续......
 
MySQL5.6中增加了一个选项:O_DIRECT_NO_FSYNC

InnoDB O_DIRECT选项漫谈(一)【转】的更多相关文章

  1. CDH 6.0.1 集群搭建 「Process」

    这次搭建我使用的机器 os 是 Centos7.4 RH 系的下面以流的方式纪录搭建过程以及注意事项 Step1: 配置域名相关,因为只有三台机器组集群,所以直接使用了 hosts 的方法: 修改主机 ...

  2. [MySQL Reference Manual]14 InnoDB存储引擎

    14 InnoDB存储引擎 14 InnoDB存储引擎 14.1 InnoDB说明 14.1.1 InnoDB作为默认存储引擎 14.1.1.1 存储引擎的趋势 14.1.1.2 InnoDB变成默认 ...

  3. MySQL 5.7 安装完成后,立即要调整的性能选项

    原文:MySQL 5.7 Performance Tuning Immediately After Installation 本文是对上一篇<安装 MySQL 后,需要调整的 10 个性能配置项 ...

  4. MySQL InnoDB存储引擎事务的ACID特性

    1.前言 相信工作了一段时间的同学肯定都用过事务,也都听说过事务的4大特性ACID.ACID表示原子性.一致性.隔离性和持久性.一个很好的事务处理系统,必须具备这些标准特性: 原子性(Atomicit ...

  5. Mysql数据库的使用总结之Innodb简介

     最近在对开发的软件的服务器部分制作安装包,但服务器部分需要有mysql数据库的支持.因此,采用免安装版的mysql策略:将mysql数据库需要的文件在安装程序中进行设置和打包即可.但也遇到了很多问题 ...

  6. Mysql数据库的使用总结之Innodb简介(一)

       最近在对开发的软件的服务器部分制作安装包,但服务器部分需要有mysql数据库的支持.因此,采用免安装版的mysql策略:将mysql数据库需要的文件在安装程序中进行设置和打包即可.但也遇到了很多 ...

  7. MySQL数据库引擎MyISAM和InnoDB的区别介绍

    MySQL数据库有多种存储引擎:比如:MyISAM.InnoDB.MERGE.MEMORY(HEAP).BDB(BerkeleyDB).EXAMPLE.FEDERATED.ARCHIVE.CSV.BL ...

  8. 一步到位之INNODB

    原文链接:http://imysql.com/2012/09/21/mysql-faq-setup-innodb-quickly.html 快速认识InnoDB InnoDB是MySQL下使用最广泛的 ...

  9. 常用Mysql存储引擎--InnoDB和MyISAM简单总结

    常用Mysql存储引擎--InnoDB和MyISAM简单总结 2013-04-19 10:21:52|  分类: CCST|举报|字号 订阅     MySQL服务器采用了模块化风格,各部分之间保持相 ...

随机推荐

  1. 新浪微博客户端(63)-使用block进行链式编程

    Person.h #import <Foundation/Foundation.h> @interface Person : NSObject - (Person *(^)())study ...

  2. 关于web服务器访问速度慢的一些简单解决方法

    首先要考虑下 访问的用户: [root@app opt2]# netstat -ant | grep $ip: tcp ::: :::* LISTEN tcp ::ffff: ::ffff: TIME ...

  3. Memcached存储命令 - set

    Memcached set 命令用于将 value(数据值) 存储在指定的 key(键) 中. 如果set的key已经存在,该命令可以更新该key所对应的原来的数据,也就是实现更新的作用. set 命 ...

  4. AjaxAnywhere+struts用法

    AjaxAnywhere的用法 1,简介 AjaxAnywhere被设计成能够把任何一套现存的JSP组件转换成AJAX感知组件而不需要复杂的JavaScript编码.它利用标签把Web页面简单地划分成 ...

  5. getStyle(),修改样式属性

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. 【AngularJS】—— 11 指令的交互

    前面基本了解了指令的相关内容: 1 如何自定义指令 2 指令的复用 本篇看一下指令之间如何交互.学习内容来自<慕课网 指令3> 背景介绍 这例子是视频中的例子,有一个动感超人,有三种能力, ...

  7. ionic导航之后返回功能的说明

    当我导航view之后,再使用$location.path("/path/origin")方法重新定位到初始页面,在深入进入其他的view之后使用这个方法就遇到了问题. 假设这个设置 ...

  8. HDOJ 3652 B-number

    B-number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  9. 如何修改windows远程端口

    Windows系统默认远程桌面端口是3389,修改方法: 远程登陆服务器,运行中使用"regedit"命令打开注册表编辑器,依次展开"HKEY_LOCAL_MACHINE ...

  10. php正则预查

    php正则预查 // 把ing结尾的单词词根部分(即不含ing部分)找出来$str = 'hello ,when i am working , don not coming';零宽度:站在原地往前看, ...