作家
登录

MySQL引擎特性:InnoDB IO子系统

作者: 来源: 2017-12-15 09:08:26 阅读 我要评论

  • 如不雅innodb_flush_method设置为O_DIRECT_NO_FSYNC,文件打开方法与O_DIRECT模式类似,差别是,数据文件写完后,不调用fsync函数来刷盘,重要针对O_DIRECT能包管文件的元数据也落盘的文件体系。
  • InnoDB也须要临时文件,临时文件的创建逻辑比较简单(os_file_create_tmpfile),就是在tmp目次下成功创建一个文件后直接应用unlink函数释放掉落句柄,如许当过程停止后(不管是正常停止照样异常停止),这个文件都邑主动释放。InnoDB创建临时文件,起首复竽暌姑了server层函数mysql_tmpfile的逻辑,后续因为须要调用server层的函数来释放资本,其又调用dup函数拷贝了一份句柄。

    InnoDB今朝还不支撑应用O_DIRECT模式打开日记文件,也不支撑应用O_SYNC模式打开数据文件。

    在分发IO线程时,尽量把相邻的IO放在一个线程内,这个与Simulate aio类似,然则后续的IO归并操作,Simulate aio是本身实现,Native aio则交给内核完成了,是以代码比较简单。

    留意,如不雅应用linux native aio(详见下一节),innodb_flush_method必定要设备成O_DIRECT,不然会退化成同步IO(缺点日记中不会有义务提示)。

    InnoDB应用了文件体系的文件锁来包管只有一个过程对某个文件进行读写操作(os_file_lock),应用了建议锁(Advisory locking),而不是强迫锁(Mandatory locking),因为强迫锁在不少体系上有bug,包含linux。在非只读模式下,所有文件打开后,都用文件锁锁住。

    InnoDB中目次的创建应用递归的方法(os_file_create_subdirs_if_needed和os_file_create_directory)。例如,须要创建/a/b/c/这个目次,先创建c,然后b,然后a,创建目次调用mkdir函数。此外,创建目次上层须要调用os_file_create_simple_func函数,而不是os_file_create_func,须要留意一下。

    综上所述,可以看出IO请求是一个一个的push的对立面,每push进一个后台线程就拿去处理,如不雅后台线程优先级比较高的话,IO归并效不雅可能比较差,为懂得决这个问题,Simulate aio供给类似组提交的功能,枷?鏖IO请求提交后,才唤醒后台线程,让其同一进行处理,如许IO归并的效不雅会比较好。但这个依然有点小问题,如不雅后台线程比较劳碌的话,其就不会进入等待状况,也就是说只要请求进入了队列,就会被处理。这个问题鄙人面的Native aio中可以解决。

    如不雅须要获取某个文件的大年夜小,InnoDB并不是去查文件的元数据(stat函数),而是应用lseek(file, 0, SEEK_END)的方法获取文件大年夜小,如许做的原因是防止元信息更新延迟导致获取的文件大年夜小有误。

    InnoDB会预分派一个大年夜小给所有新建的文件(包含数据和日记文件),预分派的文件内容全部置为零(os_file_set_size),当前文件被写满时,再进行扩大。此外,在日记文件创建时,即install_db阶段,会以100MB的距离在缺点日记中输出分派进度。

    总体来说,惯例IO操作和同步IO比拟较较简单,然则在InnoDB中,数据文件的写入根本都用了异步IO。

    InnoDB异步IO

    因为MySQL出生在Linux native aio之前,所以在MySQL异步IO的代铝闼楝有两种实现异步IO的筹划。

    第一种是原始的Simulated aio,InnoDB在Linux native air被import进来之前以及某些不支撑air的体系上,本身模仿了一条aio的机制。异步读写请求提交时,仅仅把它放入一个队列中,然后就返回,法度榜样可以去做其他工作。后台有若干异步io处理线程(innobase_read_io_threads和innobase_write_io_threads这两个参数控制)赓续大年夜这个队列中掏出请求,然后应用同步IO的方法完成读写请求以及读写完成后的工作。

    别的一种就是Native aio。今朝在linux上应用io_submit,io_getevents等函数完成(不应用glibc aio,这个也是模仿的)。提交请求应用io_submit, 等待请求应用io_getevents。别的,window平台上也有本身对应的aio,这里就不介绍了,如不雅应用了window的技巧栈,数据库应当会选用sqlserver。今朝,其他平台(Linux和window之外)都只能应用Simulate aio。

    起首介绍一下一些通用的函数和构造,接下来分别具体介绍一下Simulate alo和Linux上的Native aio。

    在os0file.cc中定义了全局数组,类型为os_aio_array_t,这些数组就是Simulate aio用来缓存读写请求的队列,数组的每一个元素是os_aio_slot_t类型,琅绫擎记录了每个IO请求的类型,文件的fd,偏移量,须要攫取的数据量,IO请求提议的时光,IO请求是否已经完成等。别的,Linux native io中的struct iocb也在os_aio_slot_t中。数组构造os_aio_slot_t中,记录了一些统计信息,例如有若干瘪据元素(os_aio_slot_t)已经被应用了,是否为空,是否为满等。如许的全局数组一共有5个,分别用来保存数据文件读异步请求(os_aio_read_array),数据文件写异步请求(os_aio_write_array),日记文件写异步请求(os_aio_log_array),insert buffer写异步请求(os_aio_ibuf_array),数据文件同步读写请求(os_aio_sync_array)。日记文件的数据块写入是同步IO,然则这里为什么还要给日记写分派一个异步请求队列(os_aio_log_array)呢?原因是,InnoDB日记文件的日记头中,须要记录checkpoint的信息,今朝checkpoint信息的读写照样用异步IO来实现的,因为不是很紧急。在window平台中,如不雅对特定文件应用了异步IO,就这个文件就不克不及应用同步IO了,所以惹人了数据文件同步读写请求队列(os_aio_sync_array)。日记文件不须要读异步请求队列,因为只有在做奔溃恢复的时刻日记才须要被攫取,而做崩溃恢复的时刻,数据库还弗采取,是以完全没须要搞成异步攫取模式。这里有一点须要留意,不管变量innobase_read_io_threads和innobase_write_io_threads两个参数是若干,os_aio_read_array和os_aio_write_array都只有一个,只不过数据中的os_aio_slot_t元素会响应增长,在linux中,变量加1,元素数量增长256。例如,innobase_read_io_threads=4,则os_aio_read_array数组被分成了四部分,每一个部分256个元素,每个部分都有本身自力的锁、旌旗灯号量以及统计变量,用来模仿4个线程,innobase_write_io_threads类似。大年夜这里我们也可以看出,每个异步read/write线程能缓存的读写请求是有上限的,即为256,如不雅跨越这个数,后续的异步请求须要等待。256可以懂得为InnoDB层对异步IO并发数的┞菲握,而在文件体系层和磁盘层面也有长度限制,分别应用cat /sys/block/sda/queue/nr_requests和cat /sys/block/sdb/queue/nr_requests萌芽。


      推荐阅读

      Node.js中遇到含空格URL的神奇“Bug”——小范围深入HTTP协议

    开辟者大年夜赛路演 | 12月16日,技巧立异,北京不见不散 HTTP 的 Request 数据包其实是文本格局的,在 Raw 的状况下,大年夜概是以如许的情势存在:起首声明,我在“Bug”字眼上>>>详细阅读


    本文标题:MySQL引擎特性:InnoDB IO子系统

    地址:http://www.17bianji.com/lsqh/39782.html

    关键词: 探索发现

    乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

    网友点评
    自媒体专栏

    评论

    热度

    精彩导读
    栏目ID=71的表不存在(操作类型=0)