CMU 15-445 数据库课程第五课文字版 - 缓冲池(上)

简介: CMU 15-445 数据库课程第五课文字版 - 缓冲池(上)
熟肉视频地址:


今天的课程是关于期待已久的缓冲池的话题,其实就是 DBMS 如何管理它的内存并从磁盘来回移动数据,我们希望DBMS自己来管理这些内存与磁盘存储交换的操作,而不是把它留给操作系统。你可以从两个方面考虑数据库存储和内存管理问题:


image.png


第一个是空间控制,也就是我们从物理上考虑在磁盘上写页的位置,我们要把页面存储在磁盘的什么地方,以达到最大的收益。我们的目标是让页保持在一起,如果有一些页经常被我们的应用程序同时访问我们把它们连续地放在磁盘上。这么做的原因是顺序访问磁盘比随机访问消耗小得多野快得多


我们需要考虑的第二个方面是时间控制。这意味着当我们从磁盘取页到内存时,我们希望 DBMS 能够以一种最小化磁盘 I/O 的方式来实现这一点:如果有一个您需要访问的页,而它目前不在内存中,那么就需要从磁盘读取,会有一个等待页从磁盘载入内存的 I/O 阻塞,我们想尽量避免这些,也就是 DBMS 需要找到一种有效的方法,将在同一时间被访问的页面以最少的 I/O 次数同时保存在内存中。


image.png


我们这样做的主要原因也是因为相对于访问内存,直接访问磁盘的耗时大太多了,是不可以接受的。所以,作为 DBMS 工程师,找出一种有效的方法来维护这个缓冲池,尽可能地将数据保存在内存中,这对我们来说是非常重要的


image.png


到目前为止,我们一直在讨论磁盘上面的数据库文件,这些文件被分成了很多页,并且有目录页,它存储从页 id 到文件中的物理位置或偏移量的映射。在磁盘文件上面有我们的缓冲池(Buffer Pool),它为执行引擎(Execution Engine)服务

例如:我们有一个执行引擎发出一个请求访问第二页,缓冲池中没有第二页,缓冲池要做的是,首先将文件目录加载到内存中,找出第二页的物理位置,然后获取它,这样我们就能返回一个内存中的第二页的指针给执行引擎

以上是整个缓冲池如何工作的一个大概的例子,具体来说,我们今天这节课要讲的主题还是关于缓冲池的高级概念:


image.png


特别是缓冲池管理器(Buffer Pool Manager),即软件中负责管理缓冲池的部分,我们会看一下缓冲池管理器使用的不同算法。包括替换策略,如何决定哪些页要读取到内存,哪些页要从内存中删除,最后我们会看一些其他类型的可能存在于 DBMS 中的内存池。


image.png


缓冲池的结构是一个固定大小的页的数组,每一个数组条目都被称为一个(Frame):它是磁盘上的数据库文件的页的大小,这样我们就可以把磁盘上的页映射到缓冲池的数组槽中。当 DBMS 请求一个页时,我们要做的就是将页复制到缓冲池中的这些帧中。

实际上,我们现在还需要一个间接层才能访问这些页,即通过页表(Page Table)


image.png


页表实际上记录了存储在内存中的页的映射,类似于数据库磁盘文件的文件头的槽页。页目录记录页在磁盘上的位置,页表则是会记录页的布局,以及它们在内存缓冲池中的位置。这里我们有从第一页和第三页到缓冲池中的帧的映射,页表还将负责维护关于每个页的一些额外元数据,例如:

  • dirty 标记:是一个布尔值,告诉我们页在加载到内存后是否被修改过
  • pin 标记或者引用计数:如果我们想要一个还会被使用的页留在缓冲池的内存中,我们不希望它被删除,我们可以用 pin 标记这一页。或者通过记录引用计数让我们知道哪些页还在被查询使用
  • Latch锁存器:如果我们有一堆并发的查询,我们有多个线程或查询都访问试图修改这个页表,一般需要在页表的一个位置设置一个锁存器,来防止并发修改

这里我们需要理清一个重要的概念区别,即(Lock)与锁存器(Latch)


image.png


在数据库世界中的锁与锁存器,与操作系统中的锁与锁存器的概念是不一样的。在数据库的世界中:

  • (Lock):指的是对于数据库的逻辑抽象的保护,例如锁的可以是整张表,也可以是索引,也可以是元组,这些都是与DBMS相关的逻辑抽象。锁通常在事务期间获取并保持,并且要考虑事务回滚
  • 锁存器(Latch):我们通常指的是保护某些底层关键部分的短暂的锁存器,比如保护一个内部数据结构或者数据库管理系统中发生的修改,我们不需要能够回滚这些改变。有点类似于 Mutex(互斥锁)

下一个我们想搞清楚的是页目录(Page Directory)与页表(Page Table)的区别:


image.png


页目录就是从页id到页物理位置的映射,它需要被持久化,这样就算重启我们也可以加载以便追踪我们可能需要的各个页。

页表在内存中,它是临时的。我们不需要持久化这个页表,页表可以在我们执行查询时逐步建立。

一个问题:在内存中设置了页表某一帧的 dirty 位后,如果掉电,我们会丢失对页面的更新吗?会的,如果在缓冲池中有一些页被设置了脏位,这意味着它们被一些查询修改了,它们还没有持久化到磁盘上。但是后面我们会讨论到事务保证,如果你有一个事务,那么这个事务直到所有的更改都以某种方式(后面我们会知道通过一种类似于写入提前写日志(WAL,Write Ahead Log)的方式)持久化到磁盘上之前才会提交完成,以保证事务的完整性不受宕机影响。


image.png


我们如何决定哪些页会存在于我们的缓冲池中?一般有两种策略:

  • 全局策略(Global Policies):根据系统中在同一时间并发运行的所有查询进行综合考虑
  • 本地策略(Local Policies):基于每个查询来加载和移除页,但是也会有页的共享


image.png



相关文章
|
3月前
|
SQL 关系型数据库 MySQL
学成在线笔记+踩坑(3)——【内容模块】课程分类查询、课程增改删、课程计划增删改查,统一异常处理+JSR303校验
课程分类查询、课程新增、统一异常处理、统一封装结果类、JSR303校验、修改课程、查询课程计划、新增/修改课程计划
学成在线笔记+踩坑(3)——【内容模块】课程分类查询、课程增改删、课程计划增删改查,统一异常处理+JSR303校验
|
3月前
|
前端开发 应用服务中间件 API
|
5月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的《数据库原理及应用》课程平台的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的《数据库原理及应用》课程平台的详细设计和实现(源码+lw+部署文档+讲解等)
|
6月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的数据库课程在线教学的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue的数据库课程在线教学的详细设计和实现(源码+lw+部署文档+讲解等)
64 2
|
6月前
|
JavaScript Java 测试技术
基于SpringBoot+Vue的《数据库原理及应用》课程平台的详细设计和实现
基于SpringBoot+Vue的《数据库原理及应用》课程平台的详细设计和实现
42 1
|
6月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的数据库课程在线教学附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的数据库课程在线教学附带文章和源代码部署视频讲解等
51 4
|
5月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的《数据库原理及应用》课程平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的《数据库原理及应用》课程平台附带文章源码部署视频讲解等
54 0
|
3天前
|
存储 Oracle 关系型数据库
数据库传奇:MySQL创世之父的两千金My、Maria
《数据库传奇:MySQL创世之父的两千金My、Maria》介绍了MySQL的发展历程及其分支MariaDB。MySQL由Michael Widenius等人于1994年创建,现归Oracle所有,广泛应用于阿里巴巴、腾讯等企业。2009年,Widenius因担心Oracle收购影响MySQL的开源性,创建了MariaDB,提供额外功能和改进。维基百科、Google等已逐步替换为MariaDB,以确保更好的性能和社区支持。掌握MariaDB作为备用方案,对未来发展至关重要。
13 3
|
3天前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
20 3
|
3天前
|
SQL 关系型数据库 MySQL
数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog
《数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog》介绍了如何利用MySQL的二进制日志(Binlog)恢复误删除的数据。主要内容包括: 1. **启用二进制日志**:在`my.cnf`中配置`log-bin`并重启MySQL服务。 2. **查看二进制日志文件**:使用`SHOW VARIABLES LIKE 'log_%';`和`SHOW MASTER STATUS;`命令获取当前日志文件及位置。 3. **创建数据备份**:确保在恢复前已有备份,以防意外。 4. **导出二进制日志为SQL语句**:使用`mysqlbinlog`
23 2