深度理解Mysql(三):Buffer pool内部结构

一.概述

在前面的讲述中,我们已经连接到innodb引擎中,会有缓冲池(buffer pool),undo log,redolog,binlog,并且在修改事务的时候,会把数据相应的写到对应的日志中,这篇文章,我们将继续深入理解buffer pool内部结构

二.Buffer pool 内部结构

2.1 buffer pool 大小

默认大小是128M,这个设置一般而言,对于线上部署的项目是有些偏小的,如果线上是16核32G,可以设置buffer pool的大小为2G,或者根据压测结果合理设置

2.2 buffer pool存储数据

我们知道数据库模型是 表+字段+行,一个表又会有很多行数据,每行数据又有多个字段,可能有人认为数据就是一行一行存放在bufferpool中,但是实际上又不是这种; 实际上mysql对数据又抽象了一层叫数据页的概念,就是会把很多数据存放在数据页中,在查询和更新数据的时候,是以数据页为单位进行操作的,如图所示:

实际上,当我们要更新一行数据的时候,会把包含这行数据所在的数据页,一起加载到buffer pool中,如下图:

一个数据页大小是16k,当数据页存入缓冲池中,叫做缓存页,并且每个缓存页都会有一个对应的描述信息,如下图:

每个缓存页对应的描述数据,大概占缓存页大小的5%左右,也就是800字节,如果使用默认的buffer pool是128M,实际上buffer pool大小会超过一些,大概有130多M,因为会存放一些描述信息.

2.3 buffer pool 哪些是空闲?

在mysql服务起来的时候,mysql会向操作系统申请128M的空间作为buffer pool,最开始的时候,里面都是空的,但是在运行很多sql后, 就会不停的把数据从磁盘读取到buffer pool中,同时IO线程也会定时的刷新bufferpool数据到磁盘中,必然会涉及一个问题,哪些缓存页是空闲的,因此数据库会设计一个free链表,他是一个双向链表接口,在这个free链表中,每个节点就是一个空闲的缓存页的描述信息的地址,也就是说,只要这个缓存页是空闲的,他的描述信息地址就会放在这个free连中

2.4 怎么知道数据页是否已经加载到缓存页中

我们在crud的时候,首先看数据页是否被缓存,如果没有缓存,就会从free中找一个空闲页,然后从磁盘读取数据,写入缓存页中,把这个缓存页从free链表中删除,如果已经被缓存过,就直接使用,那么是怎么知道是都被缓存的呢??

数据库还有一个hash结构,key = 表空间号+数据页号,value =缓存页的地址

当你要使用一个数据页时候,通过"表空间+数据页号"去hash中查一下,如果有就说明被缓存过了,如图所示

2.5 flush链表: 记录那些缓存页被修改

数据被加载到缓存页后,程序执行的时候,会先对内存中数据进行修改,然后在某个时间将数据刷新到磁盘中,这个时候,就需要有一个地方记录哪些缓存页被修改了,参考free链表,有一个flush链表,会记录哪些缓存页被修改,如下图所示:

三.淘汰策略

通过上面的讲解,我们知道在缓冲池中,会有free链表记录哪些是空闲的缓存页,fursh链表记录哪些是修改过数据的缓存页,会有这样一个问题:

在刚开始时候,所有的缓存页都在free链表中,随着数据不停的从磁盘加载到内存中,free链表的数量会越来越少,最后一刻,free链表为空了,这个时候说明已经没有可用的缓存页了,怎么办??

这个时候,就需要淘汰一些缓存数据,就是把缓存页中,修改过的数据给刷新到磁盘中,然后这个缓存页就能被再次使用了,问题又来了,要先清空哪些缓存页呢??

3.1 LRU判断缓存是否需要清空

作为开发人员

相关推荐
jdbcaaa9 分钟前
Go 语言 runtime 包的使用与注意事项
开发语言·后端·golang·runtime
青云计划7 小时前
知光项目知文发布模块
java·后端·spring·mybatis
Victor3567 小时前
MongoDB(9)什么是MongoDB的副本集(Replica Set)?
后端
Victor3567 小时前
MongoDB(8)什么是聚合(Aggregation)?
后端
yeyeye1119 小时前
Spring Cloud Data Flow 简介
后端·spring·spring cloud
Tony Bai9 小时前
告别 Flaky Tests:Go 官方拟引入 testing/nettest,重塑内存网络测试标准
开发语言·网络·后端·golang·php
+VX:Fegn089510 小时前
计算机毕业设计|基于springboot + vue鲜花商城系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
程序猿阿伟10 小时前
《GraphQL批处理与全局缓存共享的底层逻辑》
后端·缓存·graphql
小小张说故事10 小时前
SQLAlchemy 技术入门指南
后端·python
识君啊10 小时前
SpringBoot 事务管理解析 - @Transactional 的正确用法与常见坑
java·数据库·spring boot·后端