缓冲池 buffer pool
缓冲池的出现,是因为磁盘速度拖了cpu速度的后腿,而将部分数据放到内存加入缓存,可以一定程度上解决此问题
缓冲池的组成
缓存的数据页类型有
- 数据页data page
- 插入缓冲 insert buffer
- 锁信息 lock info
- 索引页 index page
- 自适应哈希索引
- 数据字典信息
占大头的当然是索引页和数据页
缓冲池如何更新
缓冲池数据更新算法基于LRU
LRU(Last Recent Used)算法
算(法)如其名,即将使用最频繁的页在LRU列表前端,最少使用的在后端。
- 新查询的页已经在LRU列表,直接提到头部
- 新查询的页不在LRU列表,插入头部,如果LRU列表满了,先淘汰尾部的页
算法很简单直观,但用在sql查询中有一个问题。经常会有操作扫描表,此时缓存的页很容易被经常刷出,导致缓存没有起作用。所以innodb对此算法做了优化
Innodb的缓冲池淘汰策略 midpoint insertion strategy
- midpoint
新访问的页会首先放到设定的midpoint而不是直接放到LRU头部
|---------------------------midpoint------------|
|---------------a---------------|------b---------|
如果有全表扫描的操作,最多将b部分全部淘汰,而不会影响到a
mysql> show variables like 'innodb_old_blocks_pct';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_old_blocks_pct | 37 |
+-----------------------+-------+
1 row in set (0.02 sec)
- blocks time
此参数决定数据加入midpoint之后多久才能被提到LRU头部
set Global innodb_old_blocks_time=1000;
重做日志 redo log
既然数据有了缓存,那保持数据一致性(把缓冲池的页刷到磁盘)是必不可少的。但如果每次数据更新都要把新页刷到磁盘,其开销便使缓存失去了意义。另外新页刷到磁盘时发生宕机那数据便不能恢复。
所以有了
Write Ahead Log
顾名思义,写磁盘前先记日志。就是redo log了。
但日志总不能一直记,不执行吧
Checkpoint
就是把缓冲池的数据刷到哦磁盘的策略(宕机时就是从redo log)
1.Sharp CheckPoint
发生在数据库关闭时,会将所有的脏页刷回磁盘
2.Fuzzy CheckPoint
只刷新一部分脏页