03、BufferPool内存结构的样子

本文介绍了数据库BufferPool的内存结构,包括默认128MB的BufferPool大小、free链表用于查找空闲缓存页、磁盘数据的读取与缓存、flush链表处理脏数据以及LRU算法的应用来优化缓存页使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、BufferPool 大概的样子

1.1、buffer pool 默认大小为128MB(大小可设置),里面会包含很多个缓存页(一个数据对应一个缓存页,每个缓存页16kb),同时每个缓存页还有一个描述数据,也可以叫做控制数据
1.2、 buffer pool 在数据库启动是会按照 设置的buffer pool大小开辟内存(会比设置的 buffer pool 大一些)
1.3、buffer pool中的数据是对数据库操作的时候,才会把数据对应的页从磁盘里读取出来,放到 buffer poll 的缓存页中

2 通过free链表查找空闲缓存页

2.1、随着数据库的运行缓存页势必越来越少,所以数据库为BufferPool 设计了free链表(双向链表数据结构),既每个节点便就是一个空闲缓存页的描述数据块的地址。
2.2、free 链表有一个基础节点(40字节大小 它不属于Buffrt Pool),它会引用链表的头结点和尾节点,还存储了链表中有多少个空闲的缓存页(描述数据块)
2.3、Buffer Pool里面的描述数据块组成有两个指针,一个是 free_pre ,一个是free_next,分别指向自己的上一个free链表节点,以及下一个free链表的节点。

3、磁盘上的数据读取到缓存到BuffrtPool 缓存页中

3.1、首先从free 链表里获取一个描述数据块,然后就能获取到对应的缓存页
3.2、然后就可以将磁盘中的数据,读取到找到的缓存页中了
3.3、最后把这个描述数据块在free链表中剔除掉

  1. 其实数据库有一个哈希表数据结构,它会用 表空间号+ 数据页号,作为一个key,然后缓存页的地址最为value。
  2. 使用 表空间号+数据页号 作为key 去哈希表里查,如没有值就读取数据页,有值则表明数据页已经被缓存了
  3. 也即在每次读取一个数据页到缓存之后,都会在这个哈希表中写入一个key-vakue

4、flush 链表指BufferPool缓存页中的数据

1、凡是在BufferPool 被修改过的数据,在没有被刷新回磁盘时,对数据库来说都是脏数据
2、被修改过的缓存页的数据描述块会形成flush链表,后续flush 刷新到磁盘上

5、当free链表没有空闲的描述数据(无空闲的缓存页)时,还有要加载的数据怎么办

  1. 一种是 直接把 flush链表的数据刷新到磁盘中(将命中率低的数据刷新到磁盘中),并在flush 链表中剔除,得到新的空闲缓存页来,然后磁盘加载的数据就可以加载到新的空闲缓存页中。

6、引入LRU 算法来判断哪些缓存页是不常用的

全名是:Least Recently Used 最近最少使用的意思。
LRU原理:假设从磁盘加载一个数据页到缓存页的时候,就把这个缓存页的描述数据块放到LRU链表头部去,那么只要有数据的缓存页,都会在LRU链表里了,而且最近被访问的数据缓存页的描述数据块,都会放到LRU 链表的头部去。

<think>好的,我需要回答用户关于Buffer Pool是否属于数据库系统中的共享内存概念的问题。首先,我应该明确Buffer Pool的定义和作用。Buffer Pool,也就是数据库缓冲池,主要用于缓存磁盘上的数据页,减少物理I/O操作,提升性能。在像Oracle这样的数据库中,Buffer Pool属于SGA(系统全局区),而SGA是共享内存区域,被所有服务器进程共享。 接下来,我需要参考用户提供的引用内容。引用[1]提到VLM(Very Large Memory)在32位环境下不能使用HugePages作为Buffer Cache,但其他SGA部分如shared_pool可以使用HugePages。这里提到Buffer Cache使用共享文件系统(如ramfs/tmpfs/shmfs),而HugePages不被使用。这说明Buffer Cache确实是SGA的一部分,属于共享内存。 引用[3]描述了Redo日志写入的过程,其中提到Log Buffer属于SGA,这也属于共享内存。虽然Log Buffer和Buffer Pool不同,但都属于SGA的结构,进一步支持Buffer Pool属于共享内存的观点。 然后,我需要确认不同数据库系统的情况。比如,MySQL的InnoDB也有Buffer Pool,同样属于共享内存,被所有线程访问。因此,可以得出结论:Buffer Pool在大多数数据库系统中属于共享内存概念。 用户可能还想了解Buffer Pool的具体组成、管理方式或与其他内存结构的区别,所以需要生成相关问题。例如,如何配置Buffer Pool的大小,或者与共享池的区别等。 最后,确保回答结构清晰,引用正确,并按照要求使用中文,避免使用Markdown格式,使用$...$和$$...$$处理数学表达式,但当前问题不涉及数学公式,所以这部分可能不需要。不过要注意引用标识的添加位置,如引用[^1]、[^3]。</think>在数据库系统中,**Buffer Pool(缓冲池)** 确实属于共享内存(Shared Memory)的核心组成部分。以下从概念、实现和引用依据展开说明: --- ### 1. **Buffer Pool 的定义与作用** - **功能**:Buffer Pool 用于缓存频繁访问的数据页,减少直接读写磁盘的开销。例如,当用户查询数据时,数据库优先从 Buffer Pool 获取数据;若未命中,则从磁盘加载到 Buffer Pool 后再返回。 - **共享性**:所有数据库进程(如用户会话、后台进程)均可访问同一 Buffer Pool,因此它是共享内存的一部分。 --- ### 2. **在主流数据库中的实现** #### **Oracle 数据库** - Buffer Pool 属于 **SGA(System Global Area)** 的 `DB_CACHE_SIZE` 组件,而 SGA 是全局共享的内存区域[^1]。 - 例如,通过参数 `DB_CACHE_SIZE` 可配置其大小: ```sql ALTER SYSTEM SET DB_CACHE_SIZE = 2G; ``` #### **MySQL InnoDB** - InnoDBBuffer Pool 通过参数 `innodb_buffer_pool_size` 设置,同样由所有线程共享: ```sql SET GLOBAL innodb_buffer_pool_size = 2147483648; -- 2GB ``` --- ### 3. **与共享内存其他组件的关联** - **共享池(Shared Pool)**:存储 SQL 执行计划、元数据等,与 Buffer Pool 同属 SGA,但分工不同[^2]。 - **日志缓冲区(Log Buffer)**:用于暂存事务日志(Redo Log),也属于 SGA 的共享内存结构。 --- ### 4. **引用依据** - **共享内存文件系统**:如引用[1]所述,Oracle 的 VLM(用于扩展 Buffer Cache)通过 `ramfs/tmpfs/shmfs` 实现共享内存分配,这表明 Buffer Cache(即 Buffer Pool 的一部分)依赖共享内存机制[^1]。 - **并发控制机制**:引用[3]提到,Redo 日志写入需通过 `Redo Copy Latch` 和 `Redo Allocation Latch` 协调对共享内存(Log Buffer)的访问,类似机制也存在于 Buffer Pool 的管理中。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值