<PostgreSQL数据库内核分析>之第三章:存储管理

2024-06-08 05:18

本文主要是介绍<PostgreSQL数据库内核分析>之第三章:存储管理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 一、存储管理器的体系结构
    • 二、外存管理
      • 1.表和元组的组织方式
      • 2.磁盘管理器
    • 3.内存管理

一、存储管理器的体系结构

存储管理器是DBS与物理存取设备的接口

  • 存储管理器的体系结构如下
    (1)本地内存是每个后台进程所专有,存储属于该进程的高速缓存Cache、事务管理信息、进程信息等
    (2)内存上下文:用于统一管理内存的分配和回收
    (3)PG中每个表都用一个表文件来存储,并以表的OID命名,若超出OS文件大小限制,PG会将其切分为多个文件来存储;
    每个表除了表文件外,还拥有两个附属文件:
    可见性映射表文件VM(作用:加快VACUUM的执行速度)
    空闲空间映射表文件FSM作用:(管理表文件的空闲空间)。
    在这里插入图片描述
  • 存储管理器使用了虚拟文件描述符机制VFD,使得后台进程可以打开“无限多个”文件。
  • 缓冲池:进程间共享缓冲池
    (1)为了防止多个进程并发访问共享内存中的数据时产生的冲突,PG提供了轻量级锁,用于支持对共享内存中同一数据的互斥访问
  • 缓冲池:进程私有的本地缓冲池
    (1)PG中的数据在内存中是以页面块的形式存在,每个表空间由多个BLCKSZ(一个可配置的常量)字节大小的文件块组成,每个文件块可以包含多个元组,但是PG不支持元组的跨块存储,每个元组最大为MaxHeadTupleSize,保证了每个文件块中存储的是多个完整的元组。
    (2)表文件以文件块为单位读入内存中,每一个文件块在内存中形成一个页面块。
    (3)PG在内存中开辟了缓冲区域(缓冲池):磁盘上的文件块读入内存后被存放在缓冲区中,缓冲池被划分为与文件块的尺寸相同的若干个固定大小的缓冲区,一个标准缓冲块的默认大小是8K。

一个PG进程(postmaster、postgres)从数据库读写一个元组的流程:

  • 进程的本地内存有2种Cache:存储系统表元组、存储系统表的基本信息

  • PG的共享缓冲池与本地缓冲池:本地缓冲池用于缓冲临时表数据以及其他进程不可见的数据

  • 若缓冲池中没有包含所需元组的缓冲块,则需通过存储介质管理器SMGR来从存储介质中读取,并写入到缓冲区中。

  • 磁盘管理器负责管理所有存储在磁盘上的文件的操作

  • 虚拟文件管理:虚拟文件描述符VFD机制。VFD通过合理使用有限个实际文件描述符来满足无限的VFD访问需求,VFD通过维持一个LRU池来管理FD
    在这里插入图片描述

  • 在PG中,为每个表增加了一个附属文件,即空闲空间映射表FSM,用于记录每个表文件中块的空闲空间大小,通过一定的查找机制和数据组织实现了文件块的快速选择

  • PG使用标记删除的方式来处理元组的删除,即:对元组打上删除标记,而非从物理上删除元组。
    元组的物理删除是由VACUUM机制来完成的,由于VACUUM操作时会去遍历所有文件块,去查找被删除的元组效率低,所以也为表设计了可见性映射表VM,用以加快查找的速度。

二、外存管理

每个表文件在磁盘中都以一定的结构进行存储

  • 外存管理体系结构
    在这里插入图片描述

1.表和元组的组织方式

PG中同一个表中的元组是顺序依次插入到表文件中的。

  • 元组之间不关联的表文件,称之为堆文件。
    PG包括四种堆文件:普通堆ordinary cataloged heap、临时堆temporary heap、序列sequence relation(特殊的单行表)、TOAST表(toast table)。
    (1)临时堆仅在会话过程中创建、在会话结束时自动删除;
    (2)序列是一种元组值自动增长的特殊堆
    (3)TOAST表其实也是一种普通堆,但是它被专门用于存储变长数据。
  • 堆文件的物理结构如下,
    (1)每个堆文件由多个文件块组成
    (2)Linp是ItemIdData类型的数组,每一个ItemIdData结构用来指向文件块中的一个元组
    (3)Freespace是空闲空间,新插入页面的元组都从这部分空间来分配
    (4)Special space是特殊空间,用于存放与索引方法相关的特定数据
    (5)元组信息:存放元组的实际数据和元组的头部信息(事务ID+命令ID等信息)
    在这里插入图片描述
  • 从堆中删除一个元组:采用标记删除的方法,为每个元组使用额外的数据位作为删除标记。
    当删除元组时,只需设置相应的删除标记(在元组头部,记录了删除这个元组的事务ID和命令ID),即可设置相应的删除标记。
    若上述两个ID有效,则表明该元组应该被删除。

2.磁盘管理器

磁盘管理器并非对磁盘上的文件直接进行操作,而是通过VFD机制进行文件操作。

  • 因为一个进程打开的fd数量有限(受限于OS规定的最大值),所以设计了VFD机制
  • VFD、真实文件描述符、文件之间的关系
    (1)虚拟文件描述符是指:一个叫做VFD的数据结构,其中记录了操作系统为文件分配的真实fd;
    (2)多个进程打开同一个文件,那么每个进程将获得一个真实fd,每个真实fd对应一个VFD;
    在这里插入图片描述

LRU池

  • 每一个PG后台进程都使用一个LRU(Last Recently Used,最近最少使用)池来管理所有已经打开的VFD,池中每一个VFD都对应物理上已经打开的文件;
  • 每个进程都拥有其私有的LRU池和一系列VFD,进程需要打开文件时都是从自己私有的LRU池中申请VFD
    (1)在LRU池中,使用替换最长时间未使用的VFD策略
    (2)进程在VfdCache上保持了两个链表,一个是LRU池(双向链表,通过Vfd数据结构的IruMoreRecently属性和IruLessRecently属性链接),另一个是FreeList(空闲链表,记录了所有可被分配的VFD,通过Vfd数据结构中的nextFree属性来连接)。
    (3)PG中将一个进程当前正打开的所有文件的VFD都连成一个环,即LRU池;
    每个方框代表一个VFD(一个VfdCache数组元素),方框里的符号表示该VFD在数组中的下标。
    在LRU池中,每一个VFD都通过指针链接两个VFD,通过指针IruMoreRecently链接最近最常用的VFD,通过指针IruLessRecently链接最近不长使用的VFD;
    (4)LRU池的大小与操作系统对于进程打开文件数的限制保持一致,在postmaster进程的启动过程中会调用max_safe_fds函数来检测操作系统限制;
    (5)插入:新的VFD在VFD[0]后插入;
    删除:在LRU池中删除VFD;若LRU池已满,而又要打开新的fd,则将池中末尾的VFD删除(最少使用的VFD)
    在这里插入图片描述

空闲空间映射表FSM

  • 对于每个表文件(包括系统表在内),同时创建一个名为“关系表OID_fsm”的文件,用以记录该表的空闲空间大小,称之为空闲空间映射表文件FSM。
  • FSM物理块与逻辑地址对照
    (1)为了实现快速查找,FSM文件不太大且使用了树结构;
    FSM中存储的不是实际的文件块空间的大小,而是仅用一个字节来记录,该字节的值用于描述对应文件块中空闲空间的范围:
    所以对于任意一个表块,根据该字节的值就可以知道这个表块中空闲空间的范围;
    对于任意一个表块,根据其空闲空间的大小可以计算出它对应的FSM字节的取值,eg,N字节空闲空间的表块,FSM中记录的值为(31+N)/32;
    在这里插入图片描述
    (2)FSM块之间使用了一个三层树结构:
    第0层和第1层是辅助层:快速定位满足需要表块的FSM块
    第2层FSM块:实际存放各表块的空闲空间值;
    每一个FSM快内构成一个局部的最大堆二叉树,每个叶子节点表示一个表块的空闲空间值,按照从左至右的顺序,所有第2层FSM块中的叶子节点排列起来就一一对应了表文件中的每一个表块。
    第1层FSM块中的叶子节点从左至右顺序对应第2层FSM块的跟节点,第0层与第一层关系类似。
    (3)每个FSM块大小默认是8KB,出去头部等信息,每个叶子节点用一个字节记录,假设一个FSM块内可以保存4000个叶子节点,所以,一个FSM文件(有三个FSM块:0层FSM块、1层FSM块、2层FSM块)可以记录4000^3个叶子节点(表块);
    这是远远大于2^32,单个表的最大块数(PG的块号长度为32bit,所以单个表最多只能有2^32个块)
    (4)FSM文件中第一个文件块中二叉树(0层的0号FAM块)根节点存储的是所有表块空闲空间的最大值。
    在这里插入图片描述

可见性映射表vm

  • PG为了实现多版本的并发控制,当事务删除或者更新元组时,并非从物理上删除,而是通过将其标记为无效的方式进行标记删除,最终对这些无效的清理操作则需调用VACUUM(VACUUM查找包含无效元组的文件块)
  • VACUUM有2种情况方式:快速清理Lazy VACUUM和完全清理Full VACUUM。
    vm仅在Lazy VACUUM中使用到,Full VACUUM由于要执行跨块清理等操作,需要对整个表文件进行扫描,此时vm文件作用不大。
  • vm文件也被划分为若干个文件块(vm块),vm块中除了必要的标记信息外,其他的每一位都对应一个表块,当表块中所有的元组对当前的事务都是可见的时,表块对应的位才设为1
    当对某个表块中的元组进行更新或者删除后,那么该表块在vm文件中的对应位置的标志位将被置0。
  • vm文件仅仅是作为一个提示hint,加快vacuum的速度
    在这里插入图片描述

大数据存储

  • toast机制(the oversi-attribute storage technique,数据压缩和线外存储)和大对象机制(使用一个专门的系统表来存储大对象数据)
  • toast机制
    (1)这类数据类型必须有变长(varlena类型),eg:text类型,只有在准备向支持TOAST的属性中存储超过BLOCKSZ/4字节(2KB),TOAST机制才会被触发。
    TOAST机制会试图对将要存储的数据进行压缩或线外存储数据(即:把数据存储在其他的表中),直到数据比BLOCKSZ/4字节短,或者无法得到更好的结果的时候才停止
    (2)如果一个表中的属性是可以TOAST的,那么该表的将有一个关联的TOAST表。
    (3)TOAST机制优点:可以有效地节省查询时所占的内存空间,TOAST数据只是在向用户显示结果时才被取出来,在查询过程中并不需要检查TOAST数据的具体取值
    (4)TOAST技术保障了PG中的元组大小足以存放在一个文件块中,so,TOAST技术必须被设置为一种系统自动处理的机制。
    TOAST机制主要集中于变长的数据类型。
  • 大对象
    (1)PG的大对象存储机制可以支持三种数据类型的存储:
    二进制大对象BLOB:eg:图片、视频
    字符大对象CLOB:存储大的单字节字符集数据,eg文档
    双字节字符大对象DBCLOOB:存储大的双字节字符集数据,eg变长双字节字符图形字符串
    (2)一个大对象会被分成若干个元组存放在系统表pg_largeobject中,每一个元组也称为一个页面。
    一个元组大小为2KB,设置成2KB的原因是:可以触发TOAST的压缩机制。

TOAST与对象的区别

  • TOAST是可变长数据类型的一种大数据存储机制,属于自动触发机制;
    大对象属于用于手动调用机制
  • TOAST中的数据不能丢失,一旦丢失则报错;大对象中运行数据丢失,若丢失,则用0替代;
  • 文件不适合使用TOAST技术,原因:二进制读-》将二进制当做字符串存储到变长数据类型的属性中-》转变成文件;大对象操作是将文件作为一个对象存储到大对象表中,读取时直接读取成一个文件。
  • TOAST和大对象操作保存大数据时,都是采用了将数据切片成了片段存储到表中的方式。

3.内存管理

尽可能让使用的文件停留在内存中,这样就能有效地减少磁盘I/O代价。

  • PG内存管理
    在这里插入图片描述
  • 一个内存上下文实际上就相当于一个进程环境
    PG每个子进程都拥有多个私有的内存上下文,每个子进程的内存上下文组成一个树形结构。
    在这里插入图片描述
    高速缓存
  • 当数据库访问表时,需要表的模式信息,比如表的列属性、OID、统计信息等。
    PG将表的模式信息存放在系统表中,因此要访问表,就需要首先在系统表中取得表的模式信息。
    PG设立了高速缓存Cache来提高对系统表和普通表模式的访问效率。
    Cache中包括一个系统表元组SysCache和一个表模式信息RelCache:
    SysCache主要用于缓存系统表元组;
    RelCache存放的不是元组,而是RelationData数据结构;
  • 每一个PG进程都维护着自己的SysCache和RelCache。

Cache同步

  • PG中,每一个进程都有自己的Cache。同一个进程表在不同的进程中都有对应的Cache来缓存它的元组。桶一个系统表的元组可能被多个进程的Cache所缓存,当其中某个Cache中的一个元组被删除或更新,需要通知其他进程对其Cache进行同步。
    PG中会记录下已被删除的无效元组,并通过共享消息队列的方式在进程之间传递消息,收到无效消息的进程同步地把无效元组(RelationData结构,因为RelCache缓存的是一个RelationData数据结构)才能够自己的Cache中删除。
  • 当一个元组被删除或者更新时,在同一个SQL命令的后续执行步骤中,我们依然认为该元组是有效的,直到下一个命令开始或者事务提交时改动才生效。
    在命令的边界,旧元组变为失效,同时新元组变为有效。so,当执行heap_delete或者heap_update时,不能简单地刷新cache,正确的做法是:保持一个无效链表用于记录元组的delete/update操作。
    事务完成后,将无效链表中的信息广播该事务过程中产生的无效信息,其他进程通过消息队列读取无效信息对各自的Cache进行刷新。
    当子事务提交时,只需要将该事务产生的无效消息提交到父事务,最后由最上层的事务广播无效消息。

缓冲池管理

这篇关于<PostgreSQL数据库内核分析>之第三章:存储管理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1041293

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

MySQL数据库宕机,启动不起来,教你一招搞定!

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 MySQL数据库宕机,数据页损坏问题,启动不起来,该如何排查和解决,本文将为你说明具体的排查过程。 查看MySQL error日志 查看 MySQL error日志,排查哪个表(表空间

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57

衡石分析平台使用手册-单机安装及启动

单机安装及启动​ 本文讲述如何在单机环境下进行 HENGSHI SENSE 安装的操作过程。 在安装前请确认网络环境,如果是隔离环境,无法连接互联网时,请先按照 离线环境安装依赖的指导进行依赖包的安装,然后按照本文的指导继续操作。如果网络环境可以连接互联网,请直接按照本文的指导进行安装。 准备工作​ 请参考安装环境文档准备安装环境。 配置用户与安装目录。 在操作前请检查您是否有 sud

线性因子模型 - 独立分量分析(ICA)篇

序言 线性因子模型是数据分析与机器学习中的一类重要模型,它们通过引入潜变量( latent variables \text{latent variables} latent variables)来更好地表征数据。其中,独立分量分析( ICA \text{ICA} ICA)作为线性因子模型的一种,以其独特的视角和广泛的应用领域而备受关注。 ICA \text{ICA} ICA旨在将观察到的复杂信号

深入理解数据库的 4NF:多值依赖与消除数据异常

在数据库设计中, "范式" 是一个常常被提到的重要概念。许多初学者在学习数据库设计时,经常听到第一范式(1NF)、第二范式(2NF)、第三范式(3NF)以及 BCNF(Boyce-Codd范式)。这些范式都旨在通过消除数据冗余和异常来优化数据库结构。然而,当我们谈到 4NF(第四范式)时,事情变得更加复杂。本文将带你深入了解 多值依赖 和 4NF,帮助你在数据库设计中消除更高级别的异常。 什么是