服务热线
Service Hotline
4005-616-228
新闻中心
公司新闻
行业动态
IT知识
技术实力
服务质量
法律保障

MySQL 引擎特征:InnoDB IO 子体系

发布时间:2019-06-19????阅读:156 |
分享到:

原文出处: 水中的泪   

媒介

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函数挪用上。

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来刷盘。

假如innodb_flush_method配置为O_DIRECT_NO_FSYNC,文件打开方法与O_DIRECT模式相同,区别是,数据文件写完后,不挪用fsync函数来刷盘,首要针对O_DIRECT能担保文件的元数据也落盘的文件体系。
InnoDB今朝还不支持行使O_DIRECT模式打开日记文件,也不支持行使O_SYNC模式打开数据文件。
留意,假如行使linux native aio(详见下一节),innodb_flush_method必然要设置成O_DIRECT,不然会退化成同步IO(错误日记中不会有使命提醒)。

收缩
  • 400-616-2280
  • 0531-88532317