Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >探索PostgreSQL数据存储存储之数据页

探索PostgreSQL数据存储存储之数据页

作者头像
用户4700054
发布于 2023-02-26 06:41:58
发布于 2023-02-26 06:41:58
4K00
代码可运行
举报
运行总次数:0
代码可运行

计算机内数据访问的时间

  • CPU L1->CPU L2->DRAM->SSD->HDD->Network Storage->Tape Archives不同层次的访问,访问的时间差距很大。上图的左边是每个层次的硬件访问数据的时间周期,上图的右边是不同硬件访问时间的放大,越上层访问越短,越下层访问时间越长;但是从容量上看越上层的容量越小,越下层的容量越大。

PG磁盘数据到内存概览

  • 任何传统传统数据库都会借助DRAM来加速数据库磁盘数据的访问。比如PG中的share_buffer,全局为PG数据库中表存储的数据page提供缓冲空间。当用户执行查询语句的时候,首先会去查询share_buffer中这个数据page是否在缓存区中,如果在就返回page;如果不在则去磁盘读取这个数据的pageshare_buffer最后返回。
  • 这里涉及到两个基本的结构,一个是share_buffer,另外一个是page.下面核心会聚焦到这2个点上,了解PG是如何实现这些逻辑

PG中的数据对象

  • PG中一般会有三种对象,分别是数据库索引.三者之间的关系如下
  • PG中一个表一般会有三种类型的数据,一个是fsm文件表示当前数据表中可用的空闲空间,另外一个是vm文件来表示数据表中数据可见性的映射,最后一个是以oid来表示的数据文件.fsm是基于page来管理空闲空间,其采用binary-tree的方式进行管理。vm中的可见性也是基于page来管理。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 创建测试表
perryn_demo=> create table email(id int,name varchar(255));
CREATE TABLE
// 查询的表的OID
perryn_demo=> select oid,relfilenode from pg_class where relname='email';
  oid  | relfilenode 
-------+-------------
 16386 |       16386
(1 row)

// 插入数据
perryn_demo=> insert into email SELECT generate_series(1,200000),repeat(chr(int4(random()*26)+65),200);
INSERT 0 190001

PG中的Page

  • PG中的Page中都有一个PageHeader,其次是多个数据指针。数据的Page是从尾部Special开始写。每个Tuple也包含了Tuple HeaderTuple Data.
  • PagePG使用了PageHeaderData来表示每个Page的头。这里存储了每个Page的meta信息,PageHeaderData->pd_linp是一个数组质指向Page内的Tuple
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef struct PageHeaderData
{
	// 上一次做更改的xlog的lsn号
	PageXLogRecPtr pd_lsn;		
	// 如果设置了page checksum这里就存储了checksun
	uint16		pd_checksum;	
	// flag的设置
	uint16		pd_flags;		
	// 执行free space的偏移量
	LocationIndex pd_lower;		
	// 执行free space的结束位置的偏移量
	LocationIndex pd_upper;		
	// 执行special space的偏移量
	LocationIndex pd_special;	
	// page的版本号
	uint16		pd_pagesize_version;
	// 最旧的xid
	TransactionId pd_prune_xid; 
	// page header的指针数组
	ItemIdData	pd_linp[FLEXIBLE_ARRAY_MEMBER]; 
} PageHeaderData;

typedef PageHeaderData *PageHeader;


typedef struct ItemIdData
{
	// 物理page的偏移量
	unsigned	lp_off:15,		
	// line poiner的状态
				lp_flags:2,		
	// tuple的长度
				lp_len:15;		
} ItemIdData;

typedef ItemIdData *ItemId;
  • 每个Tuple都有一个HeapTupleHeaderData作为Tuple的header.HeapTupleHeaderData并没有存储任何的行的属性信息,属性信息存储在TupleDescData
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 包含在tuple header中的信息
typedef struct HeapTupleFields
{
	// 插入事务ID
	TransactionId t_xmin;		
	// 删除事务ID
	TransactionId t_xmax;		

	union
	{
		// 插入或者删除的cmd id
		CommandId	t_cid;		
		TransactionId t_xvac;	/* old-style VACUUM FULL xact ID */
	}			t_field3;
} HeapTupleFields;

// 记录tuple的在位置信息
typedef struct ItemPointerData
{
	
	BlockIdData ip_blkid;
	OffsetNumber ip_posid;
}

typedef struct HeapTupleHeaderData HeapTupleHeaderData;


struct HeapTupleHeaderData
{
	// 每个元组的事务信息/记录的多少列信息
	union
	{
		// tuple事务信息存储在t_heap中
		HeapTupleFields t_heap;
		DatumTupleFields t_datum;
	}			t_choice;

	// 这个tuple的行记录所在的位置信息
	ItemPointerData t_ctid;		/* current TID of this or newer tuple (or a
								 * speculative insertion token) */


// t_infomask2和t_infomask 决定
#define FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK2 2
	uint16		t_infomask2;	

#define FIELDNO_HEAPTUPLEHEADERDATA_INFOMASK 3
	uint16		t_infomask;		
// t_hoff 表示行数据所在的位置
#define FIELDNO_HEAPTUPLEHEADERDATA_HOFF 4
	uint8		t_hoff;			

	/* ^ - 23 bytes - ^ */

#define FIELDNO_HEAPTUPLEHEADERDATA_BITS 5
	bits8		t_bits[FLEXIBLE_ARRAY_MEMBER];	/* bitmap of NULLs */

	/* MORE DATA FOLLOWS AT END OF STRUCT */
};
  • Tuple的属性信息存储在TupleDescData.
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef struct TupleDescData
{
	int			natts;			/* number of attributes in the tuple */
	Oid			tdtypeid;		/* composite type ID for tuple type */
	int32		tdtypmod;		/* typmod for tuple type */
	int			tdrefcount;		/* reference count, or -1 if not counting */
	TupleConstr *constr;		/* constraints, or NULL if none */
	/* attrs[N] is the description of Attribute Number N+1 */
	FormData_pg_attribute attrs[FLEXIBLE_ARRAY_MEMBER];
}			TupleDescData;
typedef struct TupleDescData *TupleDesc;
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-10-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 存储内核技术交流 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
PostgreSQL的元组、页面结构及索引查找原理
我们知道postgresql数据库通过数据多版本实现mvcc,pg又没有undo段,老版本的数据元组直接存放在数据页面中,这样带来的问题就是旧元组需要不断地进行清理以释放空间,这也是数据库膨胀的根本原因。本文简单介绍一下postgresql数据库的元组、页面的结构以及索引查找流程。
数据库架构之美
2019/12/18
2.5K0
PostgreSQL的元组、页面结构及索引查找原理
原 透过pageinspect了解Post
        博客 PostgreSQL的Page分析记录 有过对page的 大体介绍,可以参看之前的blog,下面主要通过插件 pageinspect 向大家进行介绍。         在此之前需要了解的名词:         page,物理文件的单位,默认大小为8K。         tuple,PG中物理行。         xid,事务号,执行操作时的顺序id。         pageinspect里边有三个函数是本文用到的,他们分别是:         a.get_raw
王果壳
2018/05/17
1.1K0
Postgresql存储结构
如果阅读过手册一定听过postgresql cluster的概念,第一次听到这个概念可能都会有一些困惑。cluster在安装数据库时,由initdb工具生成,initdb后产生的pgdata文件夹可以理解为cluster的物理存储结构。数据库启动、停止时pg_ctl -D参数指定的文件夹即cluster文件夹,所以一个PG Server可以运行在一个PG Cluster上。
mingjie
2022/05/12
1.2K0
Postgresql存储结构
如何从零学习PostgreSQL Page结构
作者 | 李亮,云和恩墨西区交付工程师,长期服务于运营商、社保、银行、医院、公积金等行业,擅长数据库备份恢复,升级迁移,性能优化,sql优化。
数据和云
2018/12/25
1.2K0
如何从零学习PostgreSQL Page结构
浅谈PostgreSQL中的并发实现
一般实现数据库的并发会采用三种方式,分别是多版本并发控制(MVCC),严格两阶段锁(S2PL),乐观并发控制(OCC).在MVCC中,每个更新操作都会创建新的一个数据版本,并保留旧版本。当事务读取数据对象时候,系统会根据一定的策略选择一个数据版本读取,这样读写都不会互相干扰。基于S2PL的数据库系统在写操作发生时会阻塞相应对象上的读操作,因为写入者获得了操作对象的互斥锁。PostgreSQL采用了基于MVCC的变体,叫做快照隔离级别(SI) 目前Oracle数据使用undo来实现快照隔离级别。当新数据写入
用户4700054
2022/08/17
2.4K0
浅谈PostgreSQL中的并发实现
Postgres 源码学习 4—表文件 Page 结构概览
前面一节主要从宏观上了解 Postgres 表数据文件的组织方式,接下来我们深入到一个表文件的 page 内部,查看 page 的具体结构表示。
roseduan
2024/06/11
1850
Postgres 源码学习 4—表文件 Page 结构概览
Postgresql中的MVCC与并发
ACID中的C即一致性在PG内部使用MVCC机制来保证。MVCC多版本并发控制为数据加上时间戳,读写需要额外的根据自身时间戳与数据时间戳对比,按照既定的规则可以知道这条数据对当前的SQL是否可见。MVCC避免了传统的锁方法,将锁竞争最小化来获得更高的性能。
mingjie
2022/05/12
4K0
Postgresql中的MVCC与并发
PG修改数据页页头等信息时是否会产生WAL?
研究PG WAL机制时想到个问题:进行插入、删除、更新等操作时,需要通过WAL来保证其一致性,以及复制构建高可用环境,当修改数据页页头等元数据信息时是否会产生WAL?
yzsDBA
2021/04/26
3500
PostgreSQL WAL解析:构建WAL记录准备
在构建WAL日志记录的过程中主要涉及2个数据变量:static XLogRecData *rdatas数组和static registered_buffer *registered_buffers数组。这两个数组分别用来保存WAL数据和管理rdatas链表。
yzsDBA
2020/10/28
7990
PostgreSQL WAL解析:构建WAL记录准备
PostgreSQL的insert解析
1、首先需要从slot中取出tuple值,HeapTupleTableSlot.tuple
yzsDBA
2020/02/24
1.6K0
PostgreSQL的insert解析
Postgresql源码(5)Xlog注册
注册数据页面相关信息 注册数据页面相关信息 注册数据页面相关信息 一个页面用一个槽位 一个页面用一个槽位 一个页面用一个槽位 一个槽位对一个registered_buffer 一个槽位对一个registered_buffer 一个槽位对一个registered_buffer
mingjie
2022/05/12
5200
Postgresql源码(5)Xlog注册
《Postgresql 内幕探索》读书笔记 - 第一章:集簇、表空间、元组
PostgreSQL天然集群,多个集群可以组成集簇,有点类似军队的连、团、旅这样的组织规则。对于我们日常学习使用的单节点则是单个集簇单个集群,自己就是集群。
阿东
2023/06/27
6560
《Postgresql 内幕探索》读书笔记 - 第一章:集簇、表空间、元组
POSTGRESQL 修改字段由大到小 为什么会 rewrite table
​最近有一位同学问关于修改字段为什么改大不 rewrite table 但是改小字段长度就会导致rewrite table , 其实这就是POSTGRESQL 在修改字段上面有一个问题,这就是人尽皆知的rewrite,rewrite本身并没有什么错误的,但是如果在线进行大表的操作者就会引起表锁,导致业务中断。那问题来了,为什么会修改表的结构对于varchar从大到小,或者数据类型变化会导致rewrite table
AustinDatabases
2021/01/22
9190
Postgresql源码(1)Tuple组装工厂
执行器会把tuple包装成tuple table slot来处理,相当于给HeapTuple包装了一层:TupleTableSlots
mingjie
2022/05/12
7680
Postgresql源码(1)Tuple组装工厂
解读年度数据库PostgreSQL:如何处理并发控制(一)
墨墨导读:最近电子工业出版社博文视点出版了《PostgreSQL指南:内幕探索》,日前「数据和云」公众号推荐了这本书并赠送了五本,百多位用户参与,几十条留言未能放出,为了让大家更好地学习开源数据PostgreSQL,经出版社官方授权,刊载本书部分章节内容以飨读者,本文节选了第五章《并发控制》5.1 -5.2。
数据和云
2019/07/09
8530
解读年度数据库PostgreSQL:如何处理并发控制(一)
POSTGRESQL 事务并发机制与 MVCC
其实这篇的的起因是源于一个问题,为什么POSTGRESQL 没有UNDO REDO,没有这样的表空间到底他怎么进行事务与相关的并发机制的。所以这篇可能会伴随着枯燥乏味。
AustinDatabases
2021/04/01
7610
POSTGRESQL   事务并发机制与 MVCC
Postgresql垃圾回收原理分析
间隔删除数据,使用ctid(页面号,lp号)作为条件,发现数据并没有真正的从页面中删除
mingjie
2022/05/12
8530
Postgresql垃圾回收原理分析
解读年度数据库PostgreSQL:如何处理并发控制(一)
原文:http://www.enmotech.com/web/detail/1/748/1.html
数据和云01
2019/07/08
1K0
PostgreSQL的Page分析记录
14155641_oBuI.png        因为工作原因,最近看了一下数据库的存储相关代码,并且对《PostgreSQL数据库内核分析》、Bean_lee的帖子进行了学习。现在记录一下,以备后用。其中后半部分基本是Bean_lee原文修改的。        首先要知道的是,数据库存储是以数据文件的方式进行存储,在data/base/子目录内能看到一些以数字命名的文件,诸如:16948、16948_fsm、16948_vm等,其中16948一般是对应表的oid,但当表的数据文件被完全重写等情况时
王果壳
2018/07/06
1K0
Postgresql页面底层数据查询方法pageinspect
https://www.postgresql.org/docs/10/pageinspect.html
mingjie
2022/05/12
3380
相关推荐
PostgreSQL的元组、页面结构及索引查找原理
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档