如何减少磁盘 IO ?
MYSQL Innodb底层采用了B+树数据结构。
而B+树有一个优点,可以减少树的层高,从而减少磁盘IO。
除此之外,MYSQL还采用了BufferPool去减少磁盘IO,提升效率。
一、BufferPool ( 缓冲池 )
1、作用
用来缓存表数据页与索引数据页,减少磁盘 IO ,提升效率。
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链表前
5
8
\dfrac{5}{8}
85 的区域称为
热数据区域
\color{red}{热数据区域}
热数据区域。
LRU链表后
3
8
\dfrac{3}{8}
83 的区域称为
冷数据区域
\color{blue}{冷数据区域}
冷数据区域。
热数据区
\color{red}{热数据区}
热数据区和
冷数据区
\color{blue}{冷数据区}
冷数据区中间节点叫midpoint。
新增节点从midpoint插入。
新增节点第二次访问时将节点移动到
热数据区
\color{red}{热数据区}
热数据区头部 ( 距第一次访问超过innodb_old_blocks_time生效,默认一秒 ) 。
被挤出
冷数据区
\color{blue}{冷数据区}
冷数据区的节点则会被**淘汰**。
6、Flush链表
记录脏页,一次内存操作 –> 写入redo log,一次磁盘顺序写
7、如何判断一个页是否在 BufferPool 中缓存 ?
MySQl 中有一个哈希表数据结构,它使用表空间号+数据页号,作为一个 key,然后缓冲页对应的控制块作为 value。
二、Change Buffer (写缓存)
作用:
在进行DML操作时,
如果二级索引没有在缓冲池中时,不会立刻将磁盘页加载到BufferPool,而是在Change Buffer记录缓冲变更;
等未来数据被读取时,再将数据合并恢复到BufferPool中。
场景
数据库大部分都是非唯一索引 && 写多读少 或 写入后不是立刻读取。