暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

《2401学习》postgresql的堆表结构

原创 大树666 2024-01-10
322

table file表示的是“文件段”就是我上篇物理结构的文章中说的“relfilenode”,block number就是说这个“文件段”按照每8K分为一个“区块”,从1到N的编号就是区块号(block number)。“区块号”还是挺重要得,在tid中会用到。



看“区块的内容”,我觉得这块内容可以分成四个部分。

从上往下说“header info”也就是蓝色部分是从pd_lsn到pd_prune_xid。是“区块”的头部信息。

* pd_lsn:本区块最后一次变更得记录。就是说有一个区块得lsn是1,然后前台一个sql改变了这个区块得数据,也许是insert或者update无所谓。此时或者lsn就会变成2,再变再增。改变多少次加多少次。用数字1和2只是比喻实际上是一个8字节无符号整数,lsn号记录在wal日志中。

* pd_lower:空闲空间开始位置。看图中得黑线,指向最新得行指针。

* pd_upper:空闲空间结束位置。看图中得黑线,指向最新得元组。

* pd_special:在堆表页中指向页尾,在索引页中它指向特殊空间的起始位置,特殊空间是仅由索引使用的特殊数据区域,包含特定的数据,具体内容依索引的类型而定,如B树,GiST,GiN等。

下面得不是很重要。就引用一下源码得解释。

* pd_checksum:页面校验和。默认不开启,默认值是0。

* pd_flags - 标记位

* pd_pagesize_version - 页面的大小,以及页面布局的版本号

* pd_prune_xid - 本页面中可以修剪的最老的元组中的XID.


橘色那块就是行指针,在数据库中行指针起到索引得作用,每当新增一个元组就会新增一个行指针与之对应。而行指针得排序称之为“偏移号”。行指针是从前往后依次递增。


灰白相间那块就是元组(tuple),每个元组代表一行数据,元组从后往前依次递增。需要注意得是,在pg中这样得增加是无序的。在pg中的索引结构是B树而不是B+树,pg中索引是一个像表文件一样单独的索引文件。


最后在行指针和元组之间的就是“空闲空间”,未使用的页,也叫空洞。


堆元组的写入


看图a当一个页中只有一个元组时,有一个指针指向这个元组,同时pd_lower指向该指针,pd_upper指向元组。

看图b当页插入一个新的元组时会生成一个新的行指针,这个指针指向最新的元组。而pd_lower指向最新的指针,pd_upper指向最新的元组。依此往复。


读取堆元组


顺序扫描,就是通常说的全表扫注意看我圈起来的sequential scan,如果有一张表没有索引,执行explain select * from tb1';看执行计划就会提示这个。表示一个个页(区块)一个个元组依次扫描。



索引扫描,在给一个字段建立索引后,这个索引文件会保留这个字段每个数据的“tid”,这个“tid”是由block(block number页面号),Offset(偏移量)组成。索引扫描时会直接根据“Tid”来查找数据,比顺序扫描快很多。



仅索引扫描(Index-Only Scan),sql查询的所有字段在索引键中。就是说像图中的sql select id,key from tb1 where id bwteen 18 and 19;这张tb1表有个联合索引就是包含id,key列的,直接查索引就能查出来。有点类似mysql中的无需回表查询。需要注意因为pg库中实现mvcc的机制的原因,pg数据库需要有一个Visibility Map文件(可见性预测)。这个文件是用来记录一个页面(区块)有没有死元组,如果有就标记为0没有标记为1,是为了方便vacuum 清理,在执行vacuum命令时检测vm(Visibility Map)文件,对于标记为1的直接跳过。

因此在仅索引扫描(Index-Only Scan)时也要检测,这个页面是否被标记为0,如果为0就要访问表的页面。因为表文件才有t_xmin t_xmax字段来判断些数据是可见的那些是不可见的,而索引文件没有这样的字段。如果没有死元组也就是vm为1的话,直接访问索引文件就可以了。


Bitmap Scan(位图索引扫描),直接看同站的帖子就行了,讲解的很清楚。https://www.modb.pro/db/611186


以上图片引用铃木启修《postgresql指南:内幕探索》

最后修改时间:2024-01-10 16:30:11
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

目录
  • 堆元组的写入
  • 读取堆元组