MySQL innodb引擎架构分析-Buffer Pool

系列文章目录

1. MySQL innodb引擎架构分析-Buffer Pool
2. MySQL innodb引擎架构分析-Redo log
3. MySQL innodb引擎架构分析- Double Write Buffer
4.MySQL innodb引擎架构分析-Change Buffer


前言

InnoDB是MySQL的数据库引擎之一,现为MySQL的默认存储引擎,为MySQL AB发布binary的标准之一,它是事务型数据库的首选引擎,支持ACID事务,支持行级锁定。InnoDB是为处理巨大数据量时的最大性能设计。InnoDB存储引擎完全与MySQL服务器整合,InnoDB存储引擎为在主内存中缓存数据和索引而维持它自己的缓冲池,这个缓冲池就是Buffer Pool。


一、Buffer Pool是什么?

在这里插入图片描述

Buffer Pool是以页为单位的MySQL数据缓冲池,其工作原理类似Java的新生代、老年代(&元空间),它能降低磁盘访问的次数以提高数据库的性能。Buffer Pool的默认大小是128M。在实际的生产环境中可以通过参数innodb_buffer_pool_size对 Buffer pool进行调整。

二、Buffer Pool是如何工作的?

当我们在数据库select数据时,如果每次都去磁盘读取,那效率无疑是大打折扣,同理,如果每次update也都是去磁盘更新,那效率也是很低的,为了降低数据库操作时频繁的操作磁盘,Buffer Pool应运而生,在第一次磁盘读出数据是如何知道Buffer Pool空间哪里是空闲的呢?在更新时更新了Buffer Pool中的数据,是怎么知道哪些页的是“脏数据”(没有持久化到磁盘的数据),在Buffer Pool空间已满,下次来的数据怎么放呢?为了解决这种问题,Buffer Pool有3种数据链表设计:free链,flush链,Lru升级链。

1. free链

free链能帮助MySQL找到空闲的缓存页,它是一个双向链表,链表上除了描述信息块,还有一个基础节点,存储了free链有多少个描述信息块,也就是有多少个空闲的缓存页,链表节点是空闲的缓存页对应的描述信息块,当数据库加载数据的时候,会从free链中找到空闲的缓存页,加载数据到缓存页后,会把缓存页对应的描述信息块从free链表中移除

2. flush链

flush链帮MySQL找到脏缓存页,也就是需要持久化的缓存页,如果更新了缓存页,会把该缓存页加入到flush链表中,它也有一个基础结点,并存储了有多少个描述信息块,可以通过阈值和自适应刷脏来处理脏数据页的磁盘持久化;

根据脏页的情况(阈值)和相关配置刷新

清理脏数据后台线程的个数:

SHOW VARIABLES LIKE 'innodb_page_cleaners';

脏页的最低水位,默认为0,非0时表示开启脏页预刷,当脏页达到innodb_max_dirty_pages_pct_lwm时刷脏页就开始了

SHOW VARIABLES LIKE 'innodb_max_dirty_pages_pct_lwm';

innodb_max_dirty_pages_pct控制脏页在BufferPool中的百分比,默认是75%,innodb就会强制刷脏页

SHOW VARIABLES LIKE 'innodb_max_dirty_pages_pct';(Innodb_buffer_pool_pages_dirty/Innodb_buffer_pool_pages_total)

查看脏页数量

select * from performance_schema.global_status where VARIABLE_NAME = 'Innodb_buffer_pool_pages_dirty';

查看页总数

select * from performance_schema.global_status where VARIABLE_NAME = 'Innodb_buffer_pool_pages_total';

刷一个脏page时,是否刷这个page的整个extent(简单理解就是若干个物理连续的page组成一个extent,为了更好的IO)。0表示关闭该功能,1表示刷extent中连续的page,2表示刷整个extent中的page。当数据在普通盘上,开启该功能可以减少IO次数,当数据在ssd上,IO情况较好,可以考虑关闭该功能,刷整个extent会比刷一个page更慢,所以mysql8.0中innodb_flush_neighbors的默认值为0

SHOW VARIABLES LIKE 'innodb_flush_neighbors';

自适应刷脏

在一般的业务压力下,采用阈值没有问题. 但是对于用户业务不确定的场景, 简单的采用阈值的方式容易造成在用户业务压力大的情况下数据库的剧烈抖动。所以采用自适应的刷脏策略,尽可能在所有的用户场景达到系统平滑运行。
首先需要开启,是否打开自适应刷脏:

SHOW VARIABLES LIKE 'innodb_adaptive_flushing';

根据redo log产生的速度,参考当前刷脏的平均数量和设置的系统IO参数(innodb_io_capacity, innodb_io_capacity_max) 三者的平均值生成一个合理的建议刷脏的Page数量;

3. Lru升级链

如果MySQL数据库使用普通的Lru策略来进行缓存页的淘汰,那在我们查询大量数据时可能导致把缓冲池的所有页都替换出去,导致大量热数据被换出,MySQL性能急剧下降,为了应对这种问题,MySQL采用了冷热2段机制,比例为5:3,空间的5分是热数据,3分是冷数据,在MySQL设置的时间内(1秒)重复读取的页不会作为热数据移到热数据区的头部,这样解决了当读取大量数据时新的数据会覆盖热数据的问题。只有符合设定的条件读取的数据才会放到热数据区的头部,如果要覆盖缓冲,直接覆盖冷数据区的最后一个即可。


总结

BufferPool是InnoDB独有的,用于提升性能,不管读写操作都可以,同时我们可以灵活配置相关参数(innodb_buffer_pool_size、innodb_buffer_pool_instances、innodb_change_buffer_max_size)优化mysql;

参数:innodb_buffer_pool_size

配置缓冲池的大小,在内存允许的情况下,DBA往往会建议调大这个参数,越多数据和索引放到内存里,数据库的性能会越好。

参数:innodb_buffer_pool_instances

innodb_buffer_pool_instances 参数,将 buffer pool 分成几个区,每个区用独立的锁保护,这样就减少了访问 buffer pool 时需要上锁的粒度,以提高性能。参数设置是个平衡问题,innodb_buffer_pool_instances 设置太小,锁冲突集中;设置太大,维护成本升高。

参数:innodb_change_buffer_max_size

允许将更改缓冲区的最大大小配置为缓冲池总大小的百分比。默认情况下设置为25。最大可设置为50。

猜你喜欢

转载自blog.csdn.net/ren365880/article/details/128244650