Linux的存储系统分为VFS层、文件系统层、
Page Cache
缓存层、通用Block层、IO调度层、Block设备驱动层、Block设备层当MySQL发起一次数据页的随机读写,或者是一次
redo log
日志文件的顺序读写的时候,实际上会把磁盘IO请求交给Linux操作系统的VFS层,这一层的作用,就是根据你是对哪个目录中的文件执行的磁盘IO操作,把IO请求交给具体的文件系统举个例子,在linux中,有的目录比如
/xx1/xx2
里的文件其实是由NFS文件系统管理的,有的目录比如/xx3/xx4
里的文件其实是由Ext3文件系统管理的,那么这个时候VFS层需要根据你是对哪个目录下的文件发起的读写IO请求,把请求转交给对应的文件系统接着文件系统会先在
Page Cache
这个基于内存的缓存里找你要的数据在不在里面,如果有就基于内存缓存来执行读写,如果没有就继续往下一层走,此时这个请求会交给通用Block层,在这一层会把你对文件的IO请求转换为Block IO请求IO请求转换为Block IO请求之后,会把这个
Block IO
请求交给IO调度层,在这一层里默认是用CFQ公平调度算法的能假设此时你数据库发起了多个SQL语句同时在执行IO操作。
有一个SQL语句可能非常简单,比如
update xxx set xx1=xx2 where id=1
,他其实可能就只要更新磁盘上的一个block里的数据就可以了。但是有的SQL语句,比如说select * from xx where xx1 like "%xx%"
可能需要IO读取磁盘上的大量数据。
那么此时如果基于公平调度算法,就会导致他先执行第二个SQL语句的读取大量数据的IO操作,耗时很久,然后第一个仅仅更新少量数据的SQL语句的IO操作,就一直在等待他,得不到执行的机会。
所以一般建议MySQL的生产环境,需要调整为deadline IO调度算法
,他的核心思想就是,任何一个IO操作都不能一直不停的等待,在指定时间范围内,都必须让他去执行。
所以基于deadline算法,上面第一个SQL语句的更新少量数据的IO操作可能在等待一会儿之后,就会得到执行的机会,这也是一个生产环境的IO调度优化经验。
IO完成调度之后,就会决定哪个IO请求先执行,哪个IO请求后执行,此时可以执行的IO请求就会交给Block设备驱动层,然后最后经过驱动把IO请求发送给真正的存储硬件,也就是Block设备层
然后硬件设备完成了IO读写操作之后,要不然是写,要不然是读,最后就把响应经过上面的层级反向依次返回,最终MySQL可以得到本次IO读写操作的结果