os_aio_init在InnoDB启动的时刻调用,用来初始化各类构造,包含上述的全局数组,还有Simulate aio顶用的锁和互斥量。os_aio_free则释放响应的构造。os_aio_print_XXX系列的函数用来输出aio子体系的状况,重要用在show engine innodb status语句中。
Simulate aio
Simulate aio相对Native aio来说,因为InnoDB本身实现了一套模仿机制,比拟较较复杂。
- 人口函数为os_aio_func,在debug模式下,会校验一下参数,例如数据块存放的内存地址、文件读写的偏移量和读写的数据量是否是OS_FILE_LOG_BLOCK_SIZE的┞符数倍,然则没有考验文件打开模式是否用了O_DIRECT,因为Simulate aio最终都是应用同步IO,没有须要必定要用O_DIRECT打开文件。
- 校验经由过程后,就调用os_aio_array_reserve_slot,感化是把这个IO请求分派到某一个后台io处理线程(innobase_xxxx_io_threads分派的,但其实是在同一个全局数组中)中,并把io请求的相干信息记录下来,便利后台io线程处理。如不雅IO请求类型雷同,请求同一个文件且偏移量比较接近(默认情况下,偏移量差别在1M内),则InnoDB会把这两个请求分派到同一个io线程中,便利在后续步调中IO归并。
- 提交IO请求后,须要唤醒后台io处理线程,因为如不雅后台线程检测到没有IO请求,会进入等待状况(os_event_wait)。
- 至此,函数返回,法度榜样可以去干其他工作了,后续的IO处理交给后台线程了。
- 介绍一下后台IO线程怎么处理的。
- InnoDB启动时,后台IO线程会被启动(io_handler_thread)。其会调用os_aio_simulated_handle大年夜全局数组中掏出IO请求,然后用同步IO处理,停止后,须要做收尾工作,例如,如不雅是写请求的话,则须要在buffer pool中把对应的数据页大年夜脏页列表中移除。
- os_aio_simulated_handle起首须要大年夜数组中遴选出某个IO请求来履行,遴选算法并不是简单的先辈先出,其遴选所有请求中offset最小的请求先处理,如许做是为了后续的IO归并比较便利计算。然则这也轻易导致某些offset特别大年夜的孤立请求长时光没有被履行到,也就是饿逝世,为懂得决这个问题,在遴选IO请求之前,InnoDB会先做一次遍历,如不雅发明有请求是2s前推送过来的(也就是等待了2s),然则还没有被履行,就优先履行最老的请求,防止这些请求被饿逝世,如不雅有两个请求等待时光雷同,则选择offset小的请求。
- os_aio_simulated_handle接下来要做的工作就是进行IO归并,例如,读请求1请求的是file1,offset100开端的200字节,读请求2请求的是file1,offset300开端的100字节,则这两个请求可以归并为一个请求:file1,offset100开端的300字节,IO返回后,再把数据拷贝到原始请求的buffer中就可以了。写请求也类似,在写操作之前先把须要写的数据拷贝到一个临时空间,然后一次写完。留意,只有在offset持续的情况下IO才会归并,有间断或者重叠都不会归并,一模一样的IO请求也不会归并,所以这里可以算是一个可优化的点。
- os_aio_simulated_handle如不雅发明如今没有IO请求,就会进入等待状况,等待被唤醒
总体来说,InnoDB实现的┞封一套模仿机制照样比较安然靠得住的,如不雅平台不支撑Native aio则应用这套机制来读写数据文件。
Linux native aio
如不雅体系安装了libaio库且在设备文件琅绫擎设置了innodb_use_native_aio=on则启动时刻会应用Native aio。
- 人口函数依然为os_aio_func,在debug模式下,依然会检查传入的参数,同样不会检查文件是否以O_DIRECT模式打开,这算是一个有点风险的点,如不雅用户不知道linux native aio须要应用O_DIRECT模式打开文件才能发挥出aio的优势,那么机能就不会达到预期。建议在此处做一下检查,有问题输出到缺点日记。
- 检查经由过程之后,与Simulated aio一样,调用os_aio_array_reserve_slot,把IO请求分派给后台线程,分派算法也推敲了后续的IO归并,与Simulated aio一样。不合之处,主如果须要用IO请求的参数初始化iocb这个构造。IO请求的相干信息除了须要初始化iocb外,也须要在全局数组的slot中记录一份,主如果为了在os_aio_print_XXX系列函数中统计便利。
- 调用io_submit提交请求。
- 至此,函数返回,法度榜样可以去干其他工作了,后续的IO处理交给后台线程了。
接下来是后台IO线程。
- 与Simulate aio类似,后台IO线程也是在InnoDB启动时刻启动。如不雅是Linux native aio,后续会调用os_aio_linux_handle这个函数。这个函数的感化与os_aio_simulated_handle类似,然则底层实现比拟较较简单,其仅仅调用io_getevents函数等待IO请求完成。超不时光为0.5s,也就是说如不雅即使0.5内没有IO请求完成,函数也会返回,持续调用io_getevents等待,当然在等待前会断定一下办事器是否处于封闭状况,如不雅是则退出。
还要一个差别是,当没有IO请求的时刻,Simulate aio会进入等待状况,而Native aio则会每0.5秒醒来一次,做一些检查工作,然后持续等待。是以,当有新的请求来时,Simulated aio须要用户线程唤醒,而Native aio不须要。此外,在办事器封闭时,Simulate aio也须要唤醒,Native aio则不须要。
可以发明,Native aio与Simulate aio类似,请求也是一个一个提交,然后一个一个处理,如许会导致IO归并效不雅比较差。Facebook团队提交了一个Native aio的组提交优化:把IO请求起首缓存,等IO请求都到了之后,再调用io_submit函数,一口气提交先前的所有请求(io_submit可以一次提交多个请求),如许内核就比较便利做IO优化。Simulate aio在IO线程压力大年夜的情况下,组提交优化会掉效,而Native aio则不会。留意,组提交优化,不克不及一口气提交太多,如不雅跨越了aio等待队列长度,会强迫提议一次io_submit。
总结
本文具体介绍了InnoDB中IO子体系的实现以及应用须要留意的点。InnoDB日记应用同步IO,数据应用异步IO,异步IO的写盘次序也不是先辈先出的模式,这些点都须要留意。Simulate aio固然有比较大年夜的进修价值,然则在现代操作体系中,推荐应用Native aio。
推荐阅读
Node.js中遇到含空格URL的神奇“Bug”——小范围深入HTTP协议
开辟者大年夜赛路演 | 12月16日,技巧立异,北京不见不散 HTTP 的 Request 数据包其实是文本格局的,在 Raw 的状况下,大年夜概是以如许的情势存在:起首声明,我在“Bug”字眼上>>>详细阅读
地址:http://www.17bianji.com/lsqh/39782.html
1/2 1

网友点评
精彩导读
科技快报
品牌展示