PostgreSQL(十四)数据文件与块存储结构

本文详细解释了PostgreSQL数据库中表的OID与数据文件的关系,包括表和索引的文件映射、数据文件存储方式、空闲空间和可见性地图的用途,以及插入、更新操作对块空间的影响。同时,强调了全表扫描与索引扫描在性能优化中的区别。

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

目录

一、表的OID与数据文件对应关系

1、概念简述

2、重点系统表与函数

二、PG数据文件存储方式

三、数据文件、空闲空间地图和可见性地图

1、free space map:

2、Visibility map:

3、关系的分叉-fork

四、块空间使用方法

1、数据块内部结构

(1)header data:

(2)line pointer(s):

(3)heap tuple(s):

2、文件与块的变化过程

(1)insert操作,写heap tuples

(2)update操作

3、读操作的过程

(1)全表扫描:Sequential Scan(即顺序扫描)

(2)索引扫描:index scan


一、表的OID与数据文件对应关系

1、概念简述

与 Oracle集中式的存储方式不同,PG数据库的一张表或者索引对应一个数据文件,两者各有优缺点;

作为数据库对象的表和索引,在内部由各个oid管理,而这些数据文件则由变量 relfilenode管理;

表和索引的 relfilenode值开始时基本上与相应的od匹配,但并不绝对,truncate、reindex、cluster等操作会造成relfilenode号的改变。

SELECT relname,oid,relfilenode FROM pg_class;

2、重点系统表与函数

系统表:

        pg_class:记录对象的详细信息

        pg_database:记录数据库的详细信息

        pg_tablespace:记录表空间的详细信息

函数:

        pg_relation_filepath('$table_name')       --查看表的文件路径

select pg_relation_filepath('$table_name'); 

二、PG数据文件存储方式

1、大数据文件切割规则

当单个数据文件超过1G后,将会产生新的文件,在oid后加上后缀,例如$oid.1、$oid.2以此类推

三、数据文件、空闲空间地图和可见性地图

在PG的数据文件存储路径下,会发现有两个和数据文件同一个relfilenode但多了个后缀的文件,这两个文件就是空闲空间地图(’_fsm’,free space map)和可见性地图(’_vm’,Visibility map)

1、free space map:

记录当前分配给数据表的所有数据块的可用空间情况;     

当进行insert操作时,空闲空间文件用来查看哪些数据块有空闲空间存放新行;

当某个块存储满了,则此块的id,将会从fsm去除。

2、Visibility map:

用于空间碎片管理,即vacuum后台进程所做的事;

当进行vacuum操作时,可见性地图文件用来提高操作的效率;

3、关系的分叉-fork

相关的三类文件在内部称为每个关系的分叉(fork);

数据文件的fork为0号,空闲空间文件_fsm的fork为1号,可见性地图文集_vm的fork号为2.

四、块空间使用方法

1、数据块(page)的内部结构

page:数据文件内部被划分为一个个固定长度的页(或块),每个页(块)缺省8192字节(8kb);可以在编译数据库时通过--with-blocksize参数指定

单张表的数据文件,最多有2^324294967296个)个page,即32T;

page的内部布局取决于数据文件类型,示例如下:

(1)header data

        由 page header data结构定义的头数据在页面的开头分配。一般长度为24字节,包含有关该页的一般信息、空闲指针等,例如:

        --pd_lsn:8 bytes;记录了事务号txid(=oracle的scn号)等,最后修改此页面的WAL记录最后一字节后的第一个字节;

        --pd_lowder:2b;当前最小的行(到空闲空间开头的偏移量);

        --pd_upper:2b;当前最大的行(到空闲空间结尾的偏移量);

        --pd_checksum:2b;页面校验码;

        --pd_flags:2b;标志位;

        --pd_special:2b;到特殊空间开头的偏移量;

        --pd_pagesize_version:2b;页面大小和布局版本号信息;

        --pd_prune_xid:4b;page上最早删除/修改tuple的事务id,在vacuum操作的时候会用到,0=没有;

(2)line pointer(s)

行指针。4字节长,保存指向每个堆行的指针。它也被称为项指针。

行指针形成一个简单的数组,它起到元组索引的作用。每个索引从1开始按顺序编号,称为偏移量编号。当一个新的行被添加到页面中时,一个新的行指针也被推到数组中以指向新的行;

(3)heap tuple(s)

        堆元组(行)是记录数据本身。PG对数据的存储类似堆表,它们从页面底部开始按顺序堆叠。

2、文件与块的变化过程

图示在进行insert、update操作后,数据库块内的变化

(1)insert操作,写heap tuples

(2)update操作

PG会把update操作拆解为 先delete后insert,但被删除的行空间不会立刻被释放,而是在vacuum操作时释放。

3、读操作的过程

(1)全表扫描:Sequential Scan(即顺序扫描)

SELECT * FROM $table;

需要扫描几个块,就IO几次,性能消耗极高。

(2)索引扫描:index scan

SELECT * FROM $table WHERE $col='$queen';

此案例中,整个过程只需要I/O 2次,比起全表扫描,性能明显提升。

因此将全表扫描改为索引扫描,也是优化操作的重要手段之一。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值