如何减少磁盘 IO ?
MYSQL Innodb底层采用了B+树数据结构。
而B+树有一个优点,可以减少树的层高,从而减少磁盘IO。
除此之外,MYSQL还采用了BufferPool去减少磁盘IO。
BufferPool ( 缓冲池 )
1、作用
用来缓存表数据与索引数据,减少磁盘 IO ,提升效率。
graph RL
subgraph Mysql Innodb
page[缓存数据页-16kb<br>一行数据<br>一行数据<br>...]
db[(磁盘文件)]
db -->|读取| page
page -->|加载到BufferPool| page03
subgraph BufferPool:默认128M
block01(控制块-约800b)
block02(控制块)
block03(控制块...)
page01(缓存数据页-16kb)
page02(缓存数据页)
page03(缓存数据页...)
end
block01 -.- page01
block02 -.- page02
block03 -.- page03
end
2、Buffer Pool 组成 :
- Buffer Pool: 默认大小128M (物理内存)
- 控制块 : 大小约为数据页的 5%,大概是 800 字节
- 对应缓存页所属的表空间、数据页的编号
- 对应缓存页在 BufferPool 中的地址
- 等等
- 缓存数据页(Page): 默认大小16kb
- 控制块 : 大小约为数据页的 5%,大概是 800 字节
每一个控制块对应一个缓存数据页。
内存分配推荐70~80%物理内存。
3、Page状态:
- free page : 空闲 page,未被使用。
- clean page: 被使用的page,数据没有被修改过。
- dirty page: 被使用的page, 数据被修改过;脏页,Page数据和磁盘数据不一致。
4、Buffer Pool 数据页管理 :
Buffer Pool是通过是三个链表的使用来维护数据页的更新与淘汰。
- Free链表: 记录Buffer Pool空闲数据页。
- Flush链表: 记录Buffer Pool脏页数据 ( 脏页:更新BufferPool数据页,但还未到持久化磁盘 )
- LRU链表: 记录Buffer Pool已保存数据页,并利用该链表实现淘汰机制。
注:
Free链和Flush链表首个节点为基节点,存放链表的头节点、尾节点地址,以及当前链表存在多少节点。
其余都是保存控制块,再通过控制块访问缓存数据页。
5、LRU链表
Least Recently Used :最近最少使用。Mysql对LRU算法进行了优化,尽量减少全表扫描和预读的影响。
LRU链表前 的区域称为。
LRU链表后 的区域称为。
和中间节点叫midpoint。
新增节点从midpoint插入。
新增节点第二次访问时将节点移动到头部 ( 距第一次访问超过innodb_old_blocks_time生效,默认一秒 ) 。
被挤出的节点则会被淘汰。
6、如何判断一个页是否在 BufferPool 中缓存 ?
MySQl 中有一个哈希表数据结构,它使用表空间号+数据页号,作为一个 key,然后缓冲页对应的控制块作为 value。