MySQL根据5.1.34之前版本的一个BUG分析O_DIRECT

Mysql错误日志:

Version:  '5.1.34-percona-highperf-log'  socket:  '/home/mysql/mysql.sock'  port:  3306  Source distribution
140324  5:00:02  InnoDB: Failed to set O_DIRECT on file  /tmp/#sql593e_191_0.ibd: CREATE: Invalid argument, continuing anyway
140324  5:00:02  InnoDB: O_DIRECT is known to result in  'Invalid argument' on Linux on tmpfs, see MySQL Bug#26662
140324  5:00:02  InnoDB: Failed to set O_DIRECT on file  /tmp/#sql593e_191_0.ibd: OPEN: Invalid argument, continuing anyway
140324  5:00:02  InnoDB: O_DIRECT is known to result in  'Invalid argument' on Linux on tmpfs, see MySQL Bug#26662
140324  5:00:02  InnoDB: Failed to set O_DIRECT on file  /tmp/#sql593e_192_0.ibd: CREATE: Invalid argument, continuing anyway
140324  5:00:02  InnoDB: O_DIRECT is known to result in  'Invalid argument' on Linux on tmpfs, see MySQL Bug#26662
140324  5:00:02  InnoDB: Failed to set O_DIRECT on file  /tmp/#sql593e_192_0.ibd: OPEN: Invalid argument, continuing anyway
140324  5:00:02  InnoDB: O_DIRECT is known to result in  'Invalid argument' on Linux on tmpfs, see MySQL Bug#26662

innodb_flush_method 这个参数控制着innodb数据文件及redo log的打开、刷写模式。对于这个参数,文档上是这样描述的:

从MySQL 5.6的版本开始,也就是InnoDB 1.2版本中(PS:MariaDB 10.x版本将集成InnoDB 1.2版本),对于参数innodb_flush_method提供了一个新的设置值O_DIRECT_NO_FSYNC。

有四个值:fdatasync,O_DSYNC,O_DIRECT,O_DIRECT_NO_FSYNC

  • 默认是fdatasync,调用fsync()去刷数据文件与redo log的buffer
  • 为O_DSYNC时,innodb会使用O_SYNC方式打开和刷写redo log,使用fsync()刷写数据文件
  • 为O_DIRECT时,innodb使用O_DIRECT打开数据文件,使用fsync()刷写数据文件跟redo log
  • 为O_DIRECT_NO_FSYNC时,InnoDB存储引擎将依然使用O_DIRECT选项打开数据表空间文件,但是在刷新时,不再需要需要额外的fsync操作

首先文件的写操作包括三步:open,write,flush

  • 上面最常提到的fsync(int fd)函数,该函数作用是flush时将与fd文件描述符所指文件有关的buffer刷写到磁盘,并且flush完元数据信息(比如修改日期、创建日期等)才算flush成功。
  • 使用O_SYNC方式打开redo文件表示当write日志时,数据都write到磁盘,并且元数据也需要更新,才返回成功
  • O_DIRECT则表示我们的write操作是从mysql innodb buffer里直接向磁盘上写

至此总结一下三者写数据方式:

  • fdatasync模式:写数据时,write这一步并不需要真正写到磁盘才算完成(可能写入到操作系统buffer中就会返回完成),真正完成是flush操作,buffer交给操作系统去flush,并且文件的元数据信息也都需要更新到磁盘。
  • O_DSYNC模式:写日志操作是在write这步完成,而数据文件的写入是在flush这步通过fsync完成
  • O_DIRECT模式:数据文件的写入操作是直接从mysql innodb buffer到磁盘的,并不用通过操作系统的缓冲,而真正的完成也是在flush这步,日志还是要经过OS缓冲

优点:

  1. 目前都是硬盘如SSD、F/M卡 IO已经很快了,无需再利用系统缓存。
  2. 最为安全和稳妥的做法还是将参数innodb_flush_method设置为O_DIRECT。
  3. 若重做日志使用O_DIRECT,写入重做日志文件的过程会变慢(因为不是仅写入到操作系统缓存),Group Commit的效率就会变差。

原文发布于微信公众号 - MYSQL轻松学(learnmysql)

原文发表时间:2016-10-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Laoqi's Linux运维专列

Python访问数据库Mysql

3836

使用CentOS 7上的Postfix,Dovecot和MariaDB发送电子邮件

Postfix邮件传输代理(MTA)是一种高性能的开源电子邮件服务器系统。本指南将帮助您在CentOS 7 Linode上运行Postfix,使用Dovecot...

593
来自专栏云计算

使用Postfix,Dovecot和MySQL发送电子邮件

在本指南中,您将学习如何在Debian或Ubuntu上使用Postfix,Dovecot和MySQL设置安全的虚拟用户邮件服务器。我们将解释如何创建新的用户邮箱...

622
来自专栏Laoqi's Linux运维专列

Mysql创建用户并授权

一、Mysql创建用户并授权 mysql 默认的账户也是root,同linux一样也是超级管理员,权利特别大,所以我们不可以随便就把mysql密码告诉其他人。 ...

45512
来自专栏Laoqi's Linux运维专列

Zabbix 监控交换机

如果我们需要监控打印机、路由器、UPS等设备,肯定不能使用zabbix agentd,因为他们不能安装软件的,还好他们一般都支持SNMP协议,这样我可以使用SN...

3218
来自专栏技术专栏

Flume学习笔记

Agent 选型:exec source +memory channel+logger sink

711
来自专栏散尽浮华

Centos下DNS+NamedManager高可用部署方案完整记录

之前说到了NamedManager单机版的配置,下面说下DNS+NamedManager双机高可用的配置方案:

1246
来自专栏乐沙弥的世界

基于用户管理的同机数据库克隆

      Oracle 同机数据库复制或克隆经常用于提供测试或开发环境。对于生成的克隆数据库有多种方式,如使用冷备方式进行数据库克隆(需要使用nid修改db_...

551
来自专栏维C果糖

史上最简单的 MySQL 教程(三十五)「数据备份与还原(上)」

数据备份与还原的方式有很多种,具体可以分为:数据表备份、单表数据备份、SQL备份和增量备份。

3947
来自专栏乐沙弥的世界

Oracle 热备份

Oracle 热备份是指数据库处于open状态下,对数据库的数据文件、控制文件、参数文件、密码文件等进行一系列备份操作。

441

扫描关注云+社区