前言:最近在阅读Innodb IO相关部分的源代码。在阅读之前一直有个疑问,show global status 中有两个指标innodb_data_reads 和 innodb_data_read。两个计数器仅差一个字母,他们之间的含义到底有何差别呢?本文将通过解析这两个参数的含义,分析Innodb对于磁盘IO相关的一些知识

首先我们来看下MySQL官方文档里对于这两个参数的解释:

文档对于这两个参数的解释非常暧昧。这里的读是指什么?是从哪里读?磁盘还是内存?甚至连计数器的单位也不知道。

详细解析:

接下来我们从源代码来解析这两个参数。在src/Srv0srv.c中存在对这两个参数和代码变量的映射关系的定义代码,如下:

     export_vars.innodb_data_read = srv_data_read;
     export_vars.innodb_data_reads = os_n_file_reads; 

接着让我们来看下这两个代码变量在哪里进行了累加操作。

srv_data_read 尽有一处代码进行累加操作,buf0file.c 的 _fil_io 函数中,操作如下:
  srv_data_read+= len;
从这行可以看出,innodb_data_read中实际存的是从磁盘上进行物理IO的字节数。
 
os_n_file_reads 也几乎只有一处代码进行累加(其他是windows的sync读这里忽略),在buf0file.c 的 中,操作如下:os_file_pread

  os_n_file_reads++;

随后,代码即调用os_aio_array_reserve_slot将IO请求推入 simulated array,再根据wake_later标志位决定是否调用

os_aio_simulated_wake_handler_thread来立即唤醒IO工作队列。从这里也可以看到,innodb_data_reads记录的是innodb对于磁盘发起的读IO请求次数。
看到这里我们就很容易产生一个疑问:既然两个变量都是对磁盘发起的IO的计数器,为什么不直接放在一个函数的相邻行里呢?

回答这个问题,我们就需要对于innodb的simulated-aio和read-ahead算法有一定理解了。

进入到simulated的aio slot array的请求会有两种,一种是通过buf_read_page 过来的普通页的读请求,一种是通过buf_read_ahead_random/linear 过来的预读请求。从innodb的实现来说普通数据页的请求是需要立即返回响应的,所以是同步(sync)IO。而对于预读这样数据并非SQL所需要,仅是用于提升性能的页读取,这样的IO完全是可以异步的。这两个差异也是导致simulated aio出现的原因。把IO请求推入slot array后,数据页同步请求立即通知worker thread去os做同步IO。而预读IO请求会不断的推入slot array直到一次预读所需要的page全部推入slot中,然后再会通知worker thread。此外在worker thread中,也会判断一个segment的io请求是否相邻连续,如果连续则把这些请求合并后,作为一次OS IO发到下层存储中。

明白了这些也就不难理解为什么计数器要分开在不同的函数中计数了。如果累加都放在 _fil_io中进行,那么 innodb_data_read = 16K * innodb_data_reads (这里假设page没有做压缩)。然而在有了异步IO合并这个操作后,实际的innodb_data_reads会少于_fil_io中获得的计数次数。所以,通过 innodb_data_read / innodb_data_reads得到的比值也可以推断出一个MySQL实例中顺序IO或者可顺序预读的IO比例。

我们在production环境的服务器上做一个验证:

服务器A:在线用户访问的数据库,猜测随机IO较多

SHOW GLOBAL STATUS LIKE '%innodb_data_read%';

Innodb_data_read 46384854470656
Innodb_data_reads 2812101578

每次IO平均读取字节数=16494

服务器B:历史数据统计的数据库,数据内容和服务器A完全一样,猜测顺序IO较多

SHOW GLOBAL STATUS LIKE '%innodb_data_read%';

Innodb_data_read 54835669766144
Innodb_data_reads 2604758776

每次IO平均读取字节数=21052

可见顺序IO较多的MySQL的单次IO读取字节数确实要多于一个page的大小,说明IO合并效果明显。

而随机IO较多的MySQL的单词IO读取字节数几乎和一个page大小一致,即16K

最后我们再总结下一些结论:

  • Innodb_data_read   表示Innodb启动后,从物理磁盘上读取的字节数总和。
  • Innodb_data_reads 表示Innodb启动后,队伍物理磁盘发起的IO请求次数总和。
  • Innodb_data_read / Innodb_data_reads 得到的比值,越接近16K说明IO压力越倾向于随机IO,越远离16K说明IO从顺序预读中获得性能提升越多

参考资料:

1. InnoDB异步IO(AIO)实现详解 http://hedengcheng.com/?p=98

Innodb Read IO 相关参数源代码解析的更多相关文章

  1. innodb之线程及IO相关参数介绍

    引用链接:http://www.cnblogs.com/henglxm/p/4284504.html   1.IO THREAD: 负责IO的相关线程IO THREAD 1. 参数innodb_wri ...

  2. MySQL相关参数总结

    保留个原文链接,避免被爬虫爬了过去,以便后续更正补充:https://www.cnblogs.com/wy123/p/11273023.html MySQL参数繁多,是一个需要根据具体业务.软硬件环境 ...

  3. Mysql Innodb 引擎优化-内存、日志、IO、其他相关参数

    介绍: InnoDB给MySQL提供了具有提交,回滚和崩溃恢复能力的事务安全(ACID兼容)存储引擎.InnoDB锁定在行级并且也在SELECT语句提供一个Oracle风格一致的非锁定读.这些特色增加 ...

  4. IO 相关配置参数

    INNODB I/O相关配置 记录日志为顺序I/O,刷新日志到数据文件为随机操作.顺序操作性能快于随机IO. innodb_log_file_size innodb_log_files_in_grou ...

  5. Innodb buffer 相关参数

    buffer相关参数: show GLOBAL VARIABLES LIKE 'innodb_buffer_pool_instances'; show GLOBAL VARIABLES LIKE 'i ...

  6. mysql之 binlog维护详细解析(开启、binlog相关参数作用、mysqlbinlog解读、binlog删除)

    binary log 作用:主要实现三个重要的功能:用于复制,用于恢复,用于审计.binary log 相关参数:log_bin设置此参数表示启用binlog功能,并指定路径名称log_bin_ind ...

  7. 电机噪声之谐波分析(内附simulink中FFT分析的相关参数配置与解析)

    电机噪声之谐波分析(内附simulink中FFT分析的相关参数配置与解析) 目录 电机噪声之谐波分析(内附simulink中FFT分析的相关参数配置与解析) 写在前面 正文 电机噪声 谐波的产生 什么 ...

  8. linux device tree源代码解析--转

    //Based on Linux v3.14 source code Linux设备树机制(Device Tree) 一.描述 ARM Device Tree起源于OpenFirmware (OF), ...

  9. MySQL复制相关参数详解

    MySQL复制相关参数详解 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.复制相关系统变量 1>.server_id 是必须设置在master和每个slave上的唯一标 ...

随机推荐

  1. iOS10之后openURL:方法过期之后的替代方法及使用

    目前苹果为iOS10开放了一个key:UIApplicationOpenURLOptionUniversalLinksOnly但亲测无效 目前使用的是这个key:UIApplicationOpenUR ...

  2. PHP学习计划

  3. 数据采集:完美下载淘宝Ip数据库 简单的程序节省60元人民币而不必购买数据库

    曾经做网站类型的程序时,经常需要收集客户端的访问数据,然后加以分析.这需要一个Ip数据库,数据表中显示Ip所在的省份市区等信息.网络上有流传的Ip纯真数据库,一些公开的Web服务也可以查询Ip地址信息 ...

  4. UIButton的titleEdgeInsets和imageEdgeInsets属性

    转:http://www.cnblogs.com/huichun/p/3419596.html uiButton控件上自带了一个uiLabel类型的子控件和一个uiImageView类型的子控件,如果 ...

  5. 都昌 DCWriter电子病历编辑器演示文档截屏

  6. 导出特定内容成insert语句

           )                                EXEC('SELECT ' + @insert_sql + ' FROM ' + @table  )

  7. jquery.jqzoom.js图片放大镜

    jqzoom插件实现图片放大镜效果 1. jquery.jqzoom.js //************************************************************ ...

  8. 温故而知新:Delegate,Action,Func,匿名方法,匿名委托,事件

    Tks: http://www.cnblogs.com/yjmyzz/archive/2009/11/23/1608818.html 20150801 add: http://www.cnblogs. ...

  9. C# winForm 窗体闪烁问题

    在构造函数里加上以下代码: this.DoubleBuffered = true;//设置本窗体            SetStyle(ControlStyles.UserPaint, true); ...

  10. Android-NDK编译:cocos2d-x(三) eclipse 导入工程

    NDK 编译后,用eclipse导入cocos2d-x工程 菜单[File]-->[New]-->[Project] ,弹出New Project 对话框 窗口下方 选 [Android] ...