前言:最近在阅读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. Swift 中范围和区间如何使用?

    虽然现在swift语言已经发展到了2.0版了,但是相信很多学习iOS开发的童鞋仍对swift语言存在各种各样的疑问,今天小编将为大家详细介绍swift中的范围和区间,下面我们一起来看看吧. Range ...

  2. Arduino单片机使用和开发问题记录

    1.将程序上传到板子时Arduino IDE提示“avrdude: stk500_getsync(): not in sync: resp=0x00” 网上查遇到这个问题的人比较多,有说驱动问题的,有 ...

  3. [推荐]Hadoop+HBase+Zookeeper集群的配置

    [推荐]Hadoop+HBase+Zookeeper集群的配置 Hadoop+HBase+Zookeeper集群的配置  http://wenku.baidu.com/view/991258e881c ...

  4. 还有人在用SQL Server 2000或2005吗? 2014来了!

    你的项目,还在用SQL Server 2000或2005吗? 很多人甚至还没有来得及用过SQL Server 2008,SQL Server 2012,现在SQL Server 2014已经出来了! ...

  5. .NET中的流

    当应用程序需要和磁盘上的文件打交道的时候,就有了流的概念.流就像架设在应用程序所在内存和磁盘之间的一个管道. 大致思路 → 建立管道 //FileMode.Open打开现有文件,另外还有FileMod ...

  6. [算法导论]哈希表 @ Python

    直接寻址方式: class HashTable: def __init__(self, length): self.T = [None for i in range(length)] class Da ...

  7. iOS 同一设备内的应用之间资源共享的实现

    我们都知道,iOS为安全考虑,各应用只能使用其自已的应用沙盒内的存储空间,各应用之间是不能互相访问彼此的沙盒空间的. 另外,iOS设备都没有外置存储卡,这样,象 Android 设备间共同访问外置存储 ...

  8. Scala 深入浅出实战经典 第77讲:模式匹配下的提取器动手构造实战

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  9. 使用sqlserver的游标功能来导数据的常见写法

    一定要自己试过才知道么? 你也没试过吃屎,你怎么知道屎不能吃,难道你试过啊...(没有愤怒的意思) ),),) declare cursor_data CURSOR FOR SELECT [UserN ...

  10. JS区别不同浏览器(微信、手机等)

    最近一直在忙于自己公司的旅游产品,设计方面太广并且要兼容各种设备和场景,包括PC.Mobile.Pad.还有各种支付.由于微信支付和支付宝存在竞争,所以需要区别不同的浏览器,并且WEB项目还要出现在A ...