Buffer Pools

本文围绕DBMS内存管理展开,介绍了locks与latches区别,重点阐述了buffer pool,包括其结构、元数据、内存分配策略等。还提及多种优化buffer pool的方法,如多缓冲池、预取等,以及页面替换策略,最后介绍了DBMS的其他内存池。

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

1.Introduction

DBMS负责管理内存并将数据写入或读出磁盘。因为在大多数情况下,数据无法直接在磁盘上操作,所以任何数据库都必须能够将磁盘上以文件形式表示的数据有效地移动到内存中,以便可以使用它。下图展示了上述的交互情形。DBMS所面临的困难是,如何最小化因为移动数据所造成的延迟。在理想情况下,我们希望系统表现得像是所有的数据都已经存储在了内存当中。
在这里插入图片描述
我们可以从另外一个角度思考该问题,即从时间控制和空间控制的角度。
空间控制指的是控制page在硬盘上的物理写入位置。空间控制的目标是,如果某些page经常被上层程序同时使用,那么尽可能地让它们在磁盘上的存储位置靠近。
时间控制指的是何时将page读入内存和何时将page写入磁盘。时间控制的目标在于尽量减少访问磁盘所带来的延迟。

2.Locks vs. Latches

当我们在讨论DBMS如何保护其内部对象时,我们需要明确locks与latches的区别。

  • Locks:锁是一种高级别的逻辑原语,用于保护数据库的内容(比如tuples,tables,databases)免受其它事务的侵害。事务将在整个持续时间内保持锁定状态。 数据库系统可以向用户展示在运行查询时正在持有哪些锁。锁需要能够回滚更改。
  • 锁存器是DBMS用于其内部数据结构中的临界区(例如哈希表,内存区域)的低级保护原语。 锁存仅在执行操作期间保持。锁存不需要能够回滚更改。

3.Buffer Pool

buffer pool是从磁盘读取的page的内存高速缓存。 本质上,它是数据库内部分配的一个大内存区域,用于存储从磁盘获取的page。
buffer pool的内存区域组织为固定大小的page数组。 每个数组条目都称为一个frame。当DBMS请求一个page时,会将精确的副本放置到buffer pool的一个frame中。 然后,当请求page时,数据库系统可以首先搜索buffer pool。 如果找不到该page,则系统从磁盘获取该page的副本。 有关buffer pool的内存结构图,请参见下图。
在这里插入图片描述
Buffer Pool Meta-data
buffer pool必须维护某些元数据,以便有效且正确地使用。
首先,page table是一个in-memory哈希表,用于追踪存储在内存中的page。它将page id映射到buffer pool中的frame位置。因为buffer pool中的page顺序和磁盘中的page存储顺序不一定相同,所以这个额外中间层允许标识buffer pool中的page位置。注意不要将page table和page directory混淆,page directory的作用是将page id映射为page在数据库文件中的存储位置。
page table还会维护每个page其它元数据,脏标志,引用计数器等。
线程修改page时会设置脏标志。这向存储管理器指示必须将page写回到磁盘。
引用计数器追踪了当前正在访问某个page的线程数(无论是修改还是读取)。一个线程在访问一个page之前必须先将该page对应的引用计数器加一。如果某个page的引用计数器大于0,那么该page将不能被存储管理器移出内存。

Memory Allocation Policies
数据库中的内存根据两种策略分配给buffer pool。
global policies会处理决策,这些决策是DBMS为使正在执行的整个工作负载受益而应做出的决策,它会考虑所有活跃事务以找到分配内存的最佳决策。
另一种选择是local policies,它制定的决策将使单个查询或事务运行得更快,即使这并不适合整个工作负载。 local policies将frame分配给特定事务,而不考虑并发事务的行为。
大多数系统结合使用全局视图和局部视图。

4.Buffer Pool Optimizations

有多种方法可以优化buffer pool,以使其适合应用程序的工作负载。

Multiple Buffer Pools
DBMS可以根据不同的目标维护不同的buffer pool(例如per-database buffer pool,per-page type bufferpool)。这样每个buffer pool可以为其中存储的数据量身打造local policies。这种方法可以帮助减少latch竞争,并提高locality。
将所需page的id映射到相应buffer pool的方法有两种,object IDs和哈希。
Object IDs指的是,扩展record id,让它包含一种元数据,这种元数据表明了每个buffer pool正在处理什么样的数据库对象。然后,通过object id,可以维护从对象到特定buffer pool的映射。
在这里插入图片描述
另一个方法是哈希,DBMS直接将page id映射到相应的buffer pool当中。
在这里插入图片描述
Pre-fetching
DBMS还可以通过基于查询计划预获取page的方法来进行优化。 然后,在处理第一组page时,可以将第二组page预获取到buffer pool中。 当顺序访问许多page时,DBMS通常使用此方法。

Scan Sharing
查询游标可以重用存储计算和操作计算所产生的数据。这将允许多个查询附加到同一个扫描某个table的查询游标上。如果一个查询开始进行扫描,而在开始之前已经有一个查询在做相同的事,那么DBMS会将第二个查询的游标附加到已经存在的查询游标上。DBMS会记录第二个查询的查询游标是在什么位置被附加到已经存在的查询游标上的,这样可以帮助其完成整个查询操作。

Buffer Pool Bypass
为了避免过多的开销(访问hash table可能会带来较多的开销),为了避免污染现存的buffer pool(buffer pool中存储的数据在本次操作中可能不需要,但在不久的将来会非常需要,也就是说当前查询的局部性会导致buffer pool的全局性受到较大影响),在执行顺序性扫描操作时,系统不会将fetched page存储在buffer pool中。相反,系统会为该查询单独分配一小块内存。如果操作需要读取磁盘上连续的大量page,则此方法效果很好。Buffer Pool Bypass还可以用于临时数据(sort,join)。

5.OS Page Cache

大多数磁盘操作都通过OS API进行。 除非另有明确说明,否则操作系统会维护自己的文件系统缓存。
大多数DBMS使用直接I / O绕过操作系统的缓存,以避免page的冗余副本,并且必须管理不同的page置换策略。
Postgres是使用操作系统的page缓存的数据库系统的示例。

6.Buffer Replacement Policies

当DBMS需要释放一个frame来为新page留出空间时,它必须决定应当将哪个page从buffer pool中移出。
替换策略是DBMS实施的一种算法,该算法可以决定在需要空间时从buffer pool中退出哪些page。
替换策略的实施目标是改善正确性,精确性,速度和元数据开销。

Least Recently Used (LRU)
LRU将保留最后一次访问每个page的时间戳。可以将此时间戳存储在单独的数据结构(例如队列)中,以进行排序并提高效率。DBMS选择退出具有最旧时间戳记的page。此外,page保持排序顺序以减少逐出page时的排序时间。

CLOCK
LRU的近似实现。

Alternatives
LRU和CLOCK替换策略存在许多问题。
LRU和CLOCK容易受到sequential flooding的影响。在顺序读取场景下,我们最近访问过的page,事实上是我们最不需要的page,因为顺序读取只会读取某个page一次。但LRU和CLOCK会使buffer pool保存这种最近访问过、却最不需要的page,导致buffer pool空间的浪费。
有三种解决方案可以解决LRU和CLOCK策略的缺点。

  • LRU-K:跟踪每个page最近K个引用的历史记录作为时间戳,并计算访问之间的间隔。此历史记录用于预测下一次将要访问page的时间。
  • localization:使用multiple buffer pool。
  • priority hints:允许事务在查询执行期间根据每个page的上下文告诉buffer pool该page是否重要。

Dirty Pages
有两种处理带有脏位的page的方法。 最快的选择是删除缓冲池中不脏的任何page。 一种较慢的方法是将脏页写回磁盘以确保其更改得以保留。
这两种方法体现了快速移出page和写出不再被使用的脏页之间的权衡。
避免不必要写出page的问题的一种方法是后台写出。 后台单独开一个线程来写出脏page。安全地写出脏页后,DBMS可以驱逐该页或仅取消设置脏标志。

7.Other Memory Pools

DBMS除了tuple和index外,还需要内存来做其他事情。 这些其他buffer pool可能并不总是由磁盘支持,具体取决于实现方式。

  • Sorting + Join Buffers
  • Query Caches
  • Maintenance Buffers
  • Log Buffers
  • Dictionary Caches
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值