mysql 缓冲池(buffer pool)详解

发布时间 2023-09-18 22:14:41作者: 李若盛开

https://blog.csdn.net/zuodaoyong/article/details/129900151?ops_request_misc=&request_id=&biz_id=102&utm_term=buffer_pool%E7%9A%84%E4%BD%9C%E7%94%A8&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-129900151.142^v94^control&spm=1018.2226.3001.4187

InnoDB存储引擎是以页为单位来管理空间的,我们进行的增删改查操作其实本质都是在访问页面(读页面,写页面,创建新页面)等,磁盘IO需要消耗的时间很多,而在内存中进行操作,效率会高,为了能让数据表或者索引中的数据随时被使用,DBMS会申请占用内存来作为数据缓冲池,在真正访问页面之前,需要把磁盘上的页缓存到内存中的buffer pool中之后才可以访问。这样做的好处可以让磁盘活动量最小,从而减少与磁盘直接进行IO,这种策略可以提升SQL语句的查询性能。如果索引的数据在缓冲池中,那么访问的成本就会降低很多

一、缓冲池

缓冲池不是查询缓存

在InnoDB存储引擎中有一部分数据会放入内存中,缓冲池占了这部分内存的大部分,它用于存储各种数据的缓存,如下图

 从图中,可以看到Innodb缓冲池包含数据页,索引页,插入缓冲,锁信息,自适应hash和数据字典信息

1、缓冲池的主要性

2、缓存原则

 (位置*频次)这个原则,可以帮助对IO访问效率进行优化

(1)位置

位置决定效率,提供缓冲池就是为了在内存中可以直接访问数据

(2)频次

频次决定优先级顺序,因为缓冲池的大小是有限的,比如磁盘有200G,但是内存只有16G,缓冲池大小只有1G,就无法将所有数据都加载到缓冲池中,这时就涉及到优先级顺序,对优先对频次使用高的热数据进行加载

3、缓冲池的预读

缓冲池提升IO效率,读取数据时候存在一个局限性原理,即使用一些数据,大概率还会使用它周围的一些数据,因此采用预读机制提前加载,减少未来可能的磁盘IO操作。

二、缓冲池读取数据原理

缓冲池管理器会尽量将经常使用的数据保存起来,在数据库进行页面读操作的时候,首先会判断该页面是否在缓冲池中,如果存在就直接读取,如果不存在,就会通过内存或者磁盘将页面存放到缓冲池中再次读取。

 1、缓存池数据和磁盘同步机制

当对数据库中的记录进行修改时,首先修改缓冲池中页的记录信息,然后数据库会以一定的频率刷新到磁盘上,并不是每次更新缓冲池数据都会立刻进行磁盘回写。缓冲池会采用checkpoint机制将数据回写到磁盘上,目的是提升数据库的性能

比如,当缓冲池不够用的时候,需要释放掉一些不常使用的页,此时强制采用checkpoint将不常用的脏页回写到磁盘上,然后再从缓冲池中将这些页释放掉。这里的脏页是缓冲池中被修改过的页,与磁盘上的数据页不一致。

三、缓冲池的设置

1、MYISAM存储引擎

只缓存索引,不缓存数据,缓存参数为key_buffer_size

2、InnoDB存储引擎

缓存参数为innodb_buffer_pool_size,默认是128M

 如果想修改,则在配置文件中修改

 四、Buffer Pool实例

Buffer Pool本质是Innodb向操作系统申请的一块连续的内存空间,在多线程环境下,访问buffer pool中的数据都需要加锁处理,在buffer pool特别大而且多线程并发访问特别高的情况下,单一的buffer pool可能会影响请求的处理速度。在buffer pool 特别大的时候可以把他们拆分若干个小的buffer pool,每个buffer pool都称为一个实例,相互独立,独立的去申请内存,独立的管理各种链表,从而多线程并发访问时不会相互影响,提高并发处理能力

通过设置innodb_buffer_pool_instances来修改buffer pool实例个数

默认实例数为1

 如果想修改则在配置文件中修改,比如修改为2

 如果出现多个实例,那么每个buffer pool实例占用多少内存?

innodb_buffer_pool_size/innodb_buffer_pool_instances

即多个实例平分innodb_buffer_pool_size

buffer pool 实例不是越多越好,因为管理多个buffer pool 需要性能开销,innodb规定当innodb_buffer_pool_size小于1G设置多个实例无效。innodb会默认把innodb_buffer_pool_instances设置为1。但是当innodb_buffer_pool_size大于1G式时,可以设置多个buffer pool 实例

五、buffer pool异常处理

1、更新数据流程

查询数据时候,会先去buffer pool中查询,如果buffer pool 中不存在,存储引擎会先将数据从磁盘加载到buffer pool中,然后将数据返回给客户端,当更新数据时,如果这个数据不在buffer pool中,同样会先将数据加载进来,然后修改内存数据,被修改过的数据会在之后统一刷入磁盘

 假如修改buffer pool中的数据成功,但是还没有将数据刷入磁盘mysql挂了,此时更新的数据只存在buffer pool中,这部分数据将永久丢失

假如更新一半突然发生错误,想回滚到更新前的版本,但是buffer pool数据已经被改了,怎么办?

mysql引入redo log和undo log来解决上面的问题