1.何为innodb_buffer_pool
innodb_buffer_pool
我们俗称缓冲池,
缓冲池简单来说就是一块内存区域,通过内存的速度来弥补磁盘速度较慢对数据库性能的影响。
写入时,先将数据写入缓冲池种,再定期刷新到磁盘;读取时,将读到的页放到缓冲池种,下次再读取相同的页时,会首先判断该页是否在缓冲池中,若在缓冲池中则直接从缓冲池中返回。
2.innodb_buffer_pool的组成及工作原理
2.1 innodb_buffer_pool的组成
2.2 innodb_buffer_pool的工作原理
先了解一些名词:
页(page)
页
的大小一般为16K,是缓冲池和磁盘交互的基本单位。
Free list
数据库刚启动的时候,lru列表为空,此时需要用到的时候直接将free列表中的页删除,在lru列表中增加相应的页,维持页数守
LRU list
ibp真正存放数据的地方
FLush list
脏页链表,脏页,被修改后的页
LRU淘汰算法
最近最少使用算法
Midpoint LRU
淘汰算法
MySQL采用
innodb_buffer_pool工作过程:
开始时,三个list链表都为空:
- 是否命中缓冲池---->命中直接访问(为了避免查询数据页时扫描LRU,还为每个buffer pool instance维护了一个page hash,通过space id和page no可以直接找到对应的page。一般情况下,当我们需要读入一个Page时,首先根据space id和page no找到对应的buffer pool instance。然后查询page hash,如果page hash中没有,则表示需要从磁盘读取。)
- .没有命中---->从磁盘加载页到缓冲池中–→需要一个空闲页面---->有的话直接加入
- free list为空–→需要访问LRU进行淘汰
- LRU没有可以淘汰的---->单页刷脏–→然后释放内存块加入到free list–→去free list去取
3.Checkpoint技术
- 缩短数据库的恢复时间
- 缓冲池不够用时,将脏页刷新到磁盘
- 重做日志不可用时,刷新脏页 当mysql crash的时候,Innodb扫描redo log,从last checkpoint开始apply redo log到buffer pool,直到last checkpoint对应的LSN等于Logflushed up to对应的LSN,则恢复完成
4.innodb_buffer_pool的相关参数
参数名称 | 参数含义 |
---|---|
innodb_buffer_pool_size | 冲池的大小,取内存大小的70%-80% |
innodb_buffer_pool_instances | 缓冲池的个数 |
innodb_old_blocks_pct | 设置midpoint的位置,默认37%,内存大时设置为20%,保留20%冷数据 |
innodb_old_blocks_time | old页存在多久mid多久会被加入到new,即没被刷走加入new |
innodb_read_ahead_threshold | 预取页面到缓冲池中的线性预读的灵敏度 |
innodb_random_read_ahead | 随机预读,已经废弃 |
innodb_flush_neighbors | 刷脏页的时候刷新邻接页,官方建议SSD关闭 |
innodb_lru_scan_depth | 扫描LRU的深度,有助于释放更多的空闲页 |
innodb_adaptive_flushing | 是否打开自适应刷脏,默认开启 |
innodb_flushing_avg_loops | 重新生成刷脏建议的间隔, 默认30s |
innodb_max_dirty_pages_pct_lwm | 脏页低水位,超过该值开始刷脏 |
innodb_max_dirty_pages_pct | 高水位超过后激烈刷脏 |
innodb_io_capacity | 系统IO吞吐能力 |
innodb_buffer_pool_dump_at_shutdown | 缓冲池预热功能 |
innodb_buffer_pool_load_at_startup | 加载上次的缓冲池dump,和上面参数结合使用 |
5.innodb_buffer_pool监控
innodb_buffer_pool的使用细节情况,我们可以通过下面的命令来进行观察监控:
>show engine innodb status\G;
....
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 4397727744
Dictionary memory allocated 532423
Buffer pool size 262112
Buffer pool size, bytes 4294443008
Free buffers 16384
Database pages 245717
Old database pages 90623
Modified db pages 0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 1986, not young 26282860
0.00 youngs/s, 0.00 non-youngs/s
Pages read 2705, created 3123983, written 3204827
0.00 reads/s, 0.00 creates/s, 0.00 writes/s
No buffer pool page gets since the last printout
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len: 245717, unzip_LRU len: 0
I/O sum[48]:cur[0], unzip sum[0]:cur[0]
....
#Buffer pool size 总共多少页
#Free buffers free链表中页的数量
#Database pages LRU 页数量
#Old database pages LRU old页数量
#Modified db pages 脏页的数量
#Buffer pool hit rate 缓冲池命中率