
媒介
InnoDB做为一款成熟的跨平台数据库引擎,其实现了一套高效易用的IO接口,包含同步异步IO,IO归并等。本文简单介绍一下其内部实现,重要的代码集中在os0file.cc这个文件中。本文的分析默认基于MySQL 5.6,CentOS 6,gcc 4.8,其他版本的信息会另行指出。
基本常识
WAL技巧 : 日记先行技巧,根本所有的数据库,都应用了这个技巧。简单的说,就是须要写数据块的时刻,数据库前台线程把对应的日记先写(批量次序写)稻磁逄上,然后就告诉客户端操作成功,至于真正写数据块的操作(离散随机写)则放到后台IO线程中。应用了这个技巧,固然多了一个磁盘写入操作,然则因为日记是批量次序写,效力很高,所以客户端很快就能获得响应。此外,如不雅在真正的数据块落盘之前,数据库奔溃,重启时刻,数据库可以应用日记来做崩溃恢复,不会导致数据损掉。
数据预读 : 与数据块A“相邻”的数据块B和C在A被攫取的时刻,B和C也会有很大年夜的概率被攫取,所以可以在攫取B的时刻,提前把他们读到内存中,这就是数据预读技巧。这里说的相邻有两种含义,一种是物理上的相邻,一种是逻辑上的相邻。底层数据文件中相邻,叫做物理上相邻。如不雅数据文件中不相邻,然则逻辑上相邻(id=1的数据和id=2的数据,逻辑上相邻,然则物理上不必定相邻,可能存在同一个文件中不合的地位),则叫逻辑相邻。
文件打开模式 : Open体系调用常见的模式重要三种:O_DIRECT,O_SYNC以及default模式。O_DIRECT模式表示后续对文件的操作不应用文件体系的缓存,用户态直接操作设备文件,绕过了内核的缓存和优化,大年夜别的一个角度来说,应用O_DIRECT模式进行写文件,如不雅返回成功,数据就真的落盘了(不推敲磁盘自带的缓存),应用O_DIRECT模式进行读文件,每次读操作是真的大年夜磁盘中攫取,不会大年夜文件体系的缓存中攫取。O_SYNC表示应用操作体系缓存,对文件的读写都经由内核,然则这个模式还包管每次写数据后,数据必定落盘。default模式与O_SYNC模式类似,只是写数据后不包管数据必定落盘,数据有可能还在文件体系中,当主机宕机,数据有可能损掉。
此外,写操作不仅须要修改或者增长的数据落盘,并且还须要文件元信息落盘,只有两部分都落盘了,才能包管数据不丢。O_DIRECT模式不包管文件元信息落盘(但大年夜部分文件体系都包管,Bug #45892),是以如不雅不做其他操作,用O_DIRECT写文件后,也存在损掉的风险。O_SYNC则包管数据和元信息都落盘。default模手站种数据都不包管。
调用函数fsync后,能包管数据和日记都落盘,是以应用O_DIRECT和default模式打开的文件,写完数据,须要调用fsync函数。
同步IO : 我们常用的read/write函数(Linux上)就是这类IO,特点是,在函数履行的时刻,调用者会等待函数履行完成,并且没有消息通知机制,因为函数返回了,就表示操作完成了,后续直接检查返回值就可知道操作是否成功。这类IO操作,编程比较简单,在同一个线程中就能完成所有操作,然则须要调用者等待,在数据库体系中,比较合适急需某些数据的时刻调用,例如WAL每日记必须在返回客户端前落盘,则进行一次同步IO操作。
异步IO : 在数据库中,后台刷数据块的IO线程,根本都应用了异步IO。数据库前台线程只须要把刷块请求提交到异步IO的队列中即可返回做其他工作,而后台线程IO线程,则按期检查这些提交的请求是否已经完成,如不雅完成再做一些后续处理工作。同时异步IO因为经常是一批一批的请求提交,如不雅不合请求拜访同一个文件且偏移量持续,则可以归并成一个IO请求。例如,第一个请求攫取文件1,偏移量100开端的200字节数据,第二个请求攫取文件1,偏移量300开端的100字节数据,则这两个请求可以归并为攫取文件1,偏移量100开端的300字节数据。数据预读中的逻辑预读也经常应用异步IO技巧。
今朝Linux上的异步IO库,须要文件应用O_DIRECT模式打开,且数据块存放的内存地址、文件读写的偏移量和读写的数据量必须是文件体系逻辑块大年夜小的┞符数倍,文件体系逻辑块大年夜小可以应用类似sudo blockdev --getss /dev/sda5的语句萌芽。如不雅上述三者不是文件体系逻辑块大年夜小的┞符数倍,则在调用读写函数时刻会报错EINVAL,然则如不雅文件不应用O_DIRECT打开,则法度榜样依然可以运行,只是退化成同步IO,壅塞在io_submit函数调用上。
开辟者大年夜赛路演 | 12月16日,技巧立异,北京不见不散
InnoDB惯例IO操作以及同步IO
在InnoDB中,如不雅体系有pread/pwrite函数(os_file_read_func和os_file_write_func),则应用它们进行读写,不然应用lseek+read/write筹划。这个就是InnoDB同步IO。查看pread/pwrite文档可知,这两个函数不会改变文件句柄的偏移量且线程安然,所以多线程情况下推荐应用,而lseek+read/write筹划则须要本身应用互斥锁保护,在高并发情况下,频繁的陷入内核态,对机能有必定影响。
在InnoDB中,应用open体系调用打开文件(os_file_create_func),模式方面除了O_RDONLY(只读),O_RDWR(读写),O_CREAT(创建文件)外,还应用了O_EXCL(包管是这个线程创建此文件)和O_TRUNC(清空文件)。默认情况下(数据库不设置为只读模式),所有文件都以O_RDWR模式打开。innodb_flush_method这个参数比较重要,重点介绍一下:
- 如不雅innodb_flush_method设置了O_DSYNC,日记文件(ib_logfileXXX)应用O_SYNC打开,是以写完数据不须要调用函数fsync刷盘,数据文件(ibd)应用default模式打开,是以写完数据须要调用fsync刷盘。
- 如不雅innodb_flush_method设置了O_DIRECT,日记文件(ib_logfileXXX)应用default模式打开,写完数据须要调用fsync函数刷盘,数据文件(ibd)应用O_DIRECT模式打开,写完数据须要调用fsync函数刷盘。
- 如不雅innodb_flush_method设置了fsync或者不设置,数据文件和日记文件都应用default模式打开,写完数据都须要应用fsync来刷盘。
推荐阅读
Node.js中遇到含空格URL的神奇“Bug”——小范围深入HTTP协议
开辟者大年夜赛路演 | 12月16日,技巧立异,北京不见不散 HTTP 的 Request 数据包其实是文本格局的,在 Raw 的状况下,大年夜概是以如许的情势存在:起首声明,我在“Bug”字眼上>>>详细阅读
地址:http://www.17bianji.com/lsqh/39782.html
1/2 1

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