返回顶部
首页 > 资讯 > 精选 >怎么从零学习PostgreSQL Page结构
  • 285
分享到

怎么从零学习PostgreSQL Page结构

2023-05-31 18:05:28 285人浏览 独家记忆
摘要

这篇文章主要为大家展示了“怎么从零学习postgresql Page结构”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“怎么从零学习Postgresql Page结构”这篇文章吧。一、Pagepg

这篇文章主要为大家展示了“怎么从零学习postgresql Page结构”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“怎么从零学习Postgresql Page结构”这篇文章吧。

一、Page

pg中的page和oracle中的数据块一样,指的是数据库的块,操作系统块的整数倍个,默认是8K也就是两个操作系统块(4k的文件系统块)。这个大小在pg编译安装configure的时候通过--with-blocksize参数指定,单位是Kb。

二、Page的内部结构

2.1 page结构

怎么从零学习PostgreSQL Page结构

2.2 PageHeaderData数据结构 (页头)

可以看到一个Page有 Pager header(页头),后面是linp(行指针),pd_lower和pd_upper分别是空闲空间的开始位置和结束位置;后面就是行数据(pg里面的行就是tuple)和special空间。整个page的结构比Oracle的数据块结构简单多了。

typedef struct PageHeaderData

{

    

    PageXLogRecPtr pd_lsn;      

    uint16      pd_checksum;    

    uint16      pd_flags;       

    LocationIndex pd_lower;     

    LocationIndex pd_upper;     

    LocationIndex pd_special;   

    uint16      pd_pagesize_version;

    TransactionId pd_prune_xid; 

    ItemIdData  pd_linp[FLEXIBLE_ARRAY_MEMBER]; 

} PageHeaderData;

 具体的长度和描述也都有详细说明:

Field

Type

Length

Description

pd_lsn

PageXLogRecPtr

8 bytes

LSN: next byte after last byte of WAL record for last change to this page

pd_checksum

uint16

2 bytes

Page checksum

pd_flags

uint16

2 bytes

Flag bits

pd_lower

LocationIndex

2 bytes

Offset to start of free space

pd_upper

LocationIndex

2 bytes

Offset to end of free space

pd_special

LocationIndex

2 bytes

Offset to start of special space

pd_pagesize_version

uint16

2 bytes

Page size and layout version number infORMation

pd_prune_xid

TransactionId

4 bytes

Oldest unpruned XMAX on page, or zero if none

简单来说,pd_lsn是指最后修改过这个page的lsn(log sequence number),这个和wal(write ahead log,同oracle redo)中记录的lsn一致。数据落盘时redo必须先刷到wal,这个pd_lsn就记录了最后data落盘时的相关redo的lsn。

pd_checksum是校验和,在initdb初始化实例的时候通过-k参数指定开启,默认是关闭的,initdb之后不能修改,它基于FNV-1a hash算法,做了相应的更改。这个校验和与Oracle的checksum一样用于数据块在读入和写出内存时的校验。比如我们在内存中修改了一个数据块,写入到磁盘的时候,在内存里面先计算好checksum,数据块写完后再计算一遍cheksum是否和之前在内存中的一致,确保整个写出过程没有出错,保护数据结构不被破坏。

pd_flags有以下的值:

#define PD_HAS_FREE_LINES   0x0001  

#define PD_PAGE_FULL        0x0002  

#define PD_ALL_VISIBLE      0x0004  

 

#define PD_VALID_FLAG_BITS  0x0007  

 

pd_lower和pd_upper分别表示空闲空间起始位置和结束位置;pd_special在索引page才有效;pd_pagesize_version是page大小和page version的存储位,在不同数据库版本中,page version不一样:

数据库版本

pd_pagesize_version



<7.3

0



3 & 7.4

1



0

2



1

3



>8.3

4



prune_xid表示这个page上最早删除或者修改tuple的事务id,在vacuum操作的时候会用到。(pg没有undo,旧的数据也在page中,用vacuum来清理)

2.3 linp结构(行指针)

怎么从零学习PostgreSQL Page结构

lp_off是tuple的开始的偏移量;lp_flags是标志位;lp_len记录了tuple的长度。

Field

Length

Description

lp_off

15 bits

offset to tuple

lp_flags

2 bits

State of iteam pointer

lp_len

15 bits

Byte length of tuple

2.4 tuple header结构(行头)

typedef struct HeapTupleFields

{

    TransactionId t_xmin;       

    TransactionId t_xmax;       

    uNIOn

    {

        CommandId   t_cid;      

        TransactionId t_xvac;   

    }           t_field3;

} HeapTupleFields;

 

typedef struct DatumTupleFields

{

    int32       datum_len_;     

    int32       datum_typmod;   

    Oid         datum_typeid;   

 

    

} DatumTupleFields;

 

struct HeapTupleHeaderData

{

    union

    {

        HeapTupleFields t_heap;

        DatumTupleFields t_datum;

    }           t_choice;

 

    ItemPointerData t_ctid;     

    

    uint16      t_infomask2;    

    uint16      t_infomask;     

    uint8       t_hoff;         

    

    bits8       t_bits[FLEXIBLE_ARRAY_MEMBER];  

    

};

(*这部分代码在src/include/access/htup_details.h)

也有对应的长度和描述的相详细说明:

Field

Type

Length

Description

t_xmin

TransactionId

4 bytes

insert XID stamp

t_xmax

TransactionId

4 bytes

delete XID stamp

t_cid

CommandId

4 bytes

insert and/or delete CID stamp (overlays with t_xvac)

t_xvac

TransactionId

4 bytes

XID for VACUUM operation moving a row version

t_ctid

ItemPointerData

6 bytes

current TID of this or newer row version

t_infomask2

uint16

2 bytes

number of attributes, plus various flag bits

t_infomask

uint16

2 bytes

various flag bits

t_hoff

uint8

1 byte

offset to user data

union是共享结构体,起作用的变量是最后一次赋值的成员。来看看tuple header的结构。

在HeapTupleFields中,t_xmin是插入这行tuple的事务id;t_xmax是删除或者住tuple的事务id;union结构中的t_cid是删除或者插入这个tuple的命令id,也就是命令序号;t_xvac是以前格式的vacuum full用到的事务id。

在DatumTupleFields中,datum_len_ 指tuple的长度;datum_typmod是记录的type;datum_typeid是记录的id。

页头HeapTupleHeaderData包含了union结构体中的两个变量HeapTupleFields和DatumTupleFields。t_ctid是tuple id,类似oracle的rowid,形式为(块号,行号)。

t_infomask2 表示属性和标志位

t_infomask 是flag标志位,具体值如下:

#define HEAP_HASNULL            0x0001  

#define HEAP_HASVARWIDTH        0x0002  

#define HEAP_HASEXTERNAL        0x0004  

#define HEAP_HASOID             0x0008  

#define HEAP_XMAX_KEYSHR_LOCK   0x0010  

#define HEAP_COMBOCID           0x0020  

#define HEAP_XMAX_EXCL_LOCK     0x0040  

#define HEAP_XMAX_LOCK_ONLY     0x0080  

 

 

#define HEAP_XMAX_SHR_LOCK  (HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_KEYSHR_LOCK)

 

#define HEAP_LOCK_MASK  (HEAP_XMAX_SHR_LOCK | HEAP_XMAX_EXCL_LOCK | \

                         HEAP_XMAX_KEYSHR_LOCK)

#define HEAP_XMIN_COMMITTED     0x0100  

#define HEAP_XMIN_INVALID       0x0200  

#define HEAP_XMIN_FROZEN        (HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID)

#define HEAP_XMAX_COMMITTED     0x0400  

#define HEAP_XMAX_INVALID       0x0800  

#define HEAP_XMAX_IS_MULTI      0x1000  

#define HEAP_UPDATED            0x2000  

#define HEAP_MOVED_OFF          0x4000  

#define HEAP_MOVED_IN           0x8000  

#define HEAP_MOVED (HEAP_MOVED_OFF | HEAP_MOVED_IN)

 

#define HEAP_XACT_MASK          0xFFF0  

t_hoff表示tuple header的长度

t_bits记录了tuple中null值的列

三、实验

3.1 安装pageinspect

它在源码的crontrib目录下面

postgres@cs-> cd postgresql-10.4/contrib/pageinspect

 

make && make install

postgres@cs-> make

postgres@cs-> make install

 

create extension就好了

postgres@cs-> psql

psql (10.4)

Type "help" for help.

 

postgres=# CREATE EXTENSION pageinspect;

CREATE EXTENSION

 

postgres=# \x

Expanded display is on.

postgres=# \dx

List of installed extensions

-[ RECORD 1 ]------------------------------------------------------

Name        | pageinspect

Version     | 1.6

Schema      | public

Description | inspect the contents of database pages at a low level

-[ RECORD 2 ]------------------------------------------------------

Name        | plpgsql

Version     | 1.0

Schema      | pg_catalog

Description | PL/pgSQL procedural language

 3.2 创建建测试表t1,插入数据

怎么从零学习PostgreSQL Page结构

这里可以看到1000行数据用了6个数据块来存储(这里数据块从0开始),第6个数据块包含了73条记录(tuple)

3.3 Pageinspect查看page

这里我们通过两个函数来查看

page_header 可以看到页头的数据

heap_pageitems 可以看到具体tuple的数据

3.3.1 page_header

postgres=# \xExpanded display is on.postgres=# select * from page_header(get_raw_page('t1',0));-[ RECORD 1 ]--------lsn       | 0/1671188checksum  | 0flags     | 0lower     | 772upper     | 784special   | 8192pagesize  | 8192version   | 4prune_xid | 0postgres=#

可以看到第0个page的pd_lsn为0/1671188,checksum和flags都是0,这里没有开启checksum;tuple开始偏移是772(pd_lower),结束偏移是784(pd_upper),这个page是个表,所以它没有special,我们看到的sepcial就是8192了;pagesize是8192就是8K,version是4,没有需要清理的tuple,所以存储需要清理的tuple的最早事务的id就是0(prune_xid)。

3.3.2 heap_page_items

怎么从零学习PostgreSQL Page结构

我们来看一行记录,可以看到它是第1行记录(lp=1),tuple的开始偏移量8160(lp_off),tuple的长度是32 bytes(lp_len为32,这个tuple是第一个插入的tuple,所以lp_off+lp_len=8160+32=8192),这行记录的插入事务id是557(t_min),和tuple的删除事务id是0(tmax),这里数据没有被删除,所以都是0。我们还可以看到t_ctid是(0,1),这里表示这个tuple是这个page中第一个块的第一条tuple;tinfomask2是2,t_infomask为2306,十六进制就是 0x0902 ,这个我们可以根据上面提到的值去看看具体的含义,0x0902 = 0x0100 + 0x0800 +0x0002;tuple头部结构(行头)的长度是24(t_hoff),t_data就是16进制存储的真正的数据了。

3.4 删除一行数据观察prune_xid

怎么从零学习PostgreSQL Page结构

我们删除一行tuple可以看到prune_xid有了值,为559,这个559就是删除这个tuple的事务id(当前最早的删除或更改了tuple的事务id)

怎么从零学习PostgreSQL Page结构

同样,我们可以看到lp为1的这个tuple的t_xmax为559,这里就是删除这行tuple的事务id。

PostgreSQL Page的物理结构相比Oracle的数据块来说简单很多了,源代码开放也便于学习和研究,pg是个很好很强大的数据库,值得好好学习。

以上是“怎么从零学习PostgreSQL Page结构”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网精选频道!

--结束END--

本文标题: 怎么从零学习PostgreSQL Page结构

本文链接: https://lsjlt.com/news/227360.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 怎么从零学习PostgreSQL Page结构
    这篇文章主要为大家展示了“怎么从零学习PostgreSQL Page结构”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“怎么从零学习PostgreSQL Page结构”这篇文章吧。一、Pagepg...
    99+
    2023-05-31
  • 从零学习cmake构建系统
    目录什么是cmake入门实践构建单个源文件同一个目录,多个源文件多个目录多个源文件自定义编译选项最后什么是cmake 根据其官网的定义,cmake是一个开源跨平台的,用于构建、测试...
    99+
    2023-02-07
    cmake构建系统 cmake从零学习
  • 怎么从零开始学习Java语言
    这篇文章将为大家详细讲解有关怎么从零开始学习Java语言,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1、如何从零开始学习Java语言许多朋友在学习新的语言上有些困惑,如何学好Java语言。如何学好Jav...
    99+
    2023-06-17
  • 从零开始学习PHP构建简易网站
    从零开始学习PHP构建简易网站 随着互联网的普及,网站已经成为人们获取信息和交流的重要平台。学习如何构建网站,对于有志于进入Web开发领域的人来说是非常重要的。PHP作为一种流行的服务...
    99+
    2024-04-02
  • 从零学习构造系统之bazel示例详解
    目录什么是bazelBazel的基本概念WORKSPACE fileBUILD fileBazel的C++事例单个目标,单个软件包单个软件包,多个目标多个软件包,多个目标最后什么是b...
    99+
    2023-02-07
    bazel构造系统 bazel构造系统从零学习
  • 从零开始的 Java 学习笔记:NumPy 与 Windows 的完美结合
    Java 是一种流行的编程语言,因其跨平台性和可靠性而备受推崇。在 Java 中,数组是一种基本的数据结构,但是 Java 数组的操作和 Python 中的 NumPy 数组相比较较为繁琐。本文将介绍如何将 NumPy 和 Windows...
    99+
    2023-09-29
    学习笔记 numpy windows
  • 从零开始学Python:第九课-常用数据结构之字符串
    接着上期的Python教程讲,视频教程你们私我要的,整理出来了:Python 900集全套视频教程(全家桶)https://pan.baidu.com/s/1cU5lDWq9gh0cQ7hCnXUiGA,你们好好学。第二次世界大战促使了现代...
    99+
    2023-06-01
  • 零基础怎么学习Python爬虫
    本篇内容主要讲解“零基础怎么学习Python爬虫”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“零基础怎么学习Python爬虫”吧!  零基础如何学爬虫技术?对于迷茫的初学者来说,爬虫技术起步学习...
    99+
    2023-06-01
  • 从搬砖工到架构师,Java全栈学习路线总结
    🌇文章目录 前言一、前置知识二、 Web前端基础示例:1.文本域2.密码字段 三、后端基础一. Java基础二. 数据库技术三. Web开发技术四. 框架技术五. 服...
    99+
    2023-09-02
    java 学习 jvm spring spring boot
  • 小白零基础怎么系统的学习 Python
    小白零基础怎么系统的学习 Python?这个话题相信困扰很多想学习python的人,今天主要给大家说下一个零基础的小白,应该如何系统化的学习python编程语言,然后找到工作,在学习的过程不浪费时间少走弯路。首先我们要了解python是什...
    99+
    2023-01-31
    基础 系统 小白零
  • 从零开始学 Java:打包、NPM、编程算法应该怎么学?
    Java 是一种广泛应用的编程语言,适用于各种应用程序和网络应用。如果你想要学习 Java,那么打包、NPM 以及编程算法都是必须要掌握的技能。本文将介绍从零开始学 Java 的一些基础知识,并提供一些示例代码来帮助你更好地理解这些概念。...
    99+
    2023-07-31
    打包 npm 编程算法
  • 0基础应该怎么学Linux?Linux如何从零开始?
      在Linux学习路上,有很多朋友都是从0基础转行开始学的,那么,0基础应该怎么学Linux如何从零开始  练就扎实的基本功。  不管是学习什么语言,扎实的基本功都是必须的,俗话说“基础不牢,地动山摇”,牢固的基础可以提高效率,也可以帮助...
    99+
    2023-06-05
  • 怎么从db2数据库查询表结构
    小编给大家分享一下怎么从db2数据库查询表结构,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!SELECT    a.TABNAME,a.REMARKS...
    99+
    2024-04-02
  • 从零开始学习GO与Apache索引接口:如何快速构建一个高质量的搜索引擎?
    在当今信息化的时代,搜索引擎是人们获取信息的主要途径之一,而构建一个高质量的搜索引擎是每个搜索引擎从业者的梦想。本文将介绍如何使用GO语言和Apache索引接口快速构建一个高质量的搜索引擎。 一、GO语言简介 GO语言是Google开发的...
    99+
    2023-10-19
    apache 索引 接口
  • 从零开始学习Go语言:如何使用面向对象编程来构建复杂的应用程序?
    Go语言是近年来备受关注的一门编程语言,它的高效性和简洁性使得它成为了很多开发者的首选语言。而面向对象编程则是一种广泛使用的编程范式,它可以帮助我们更好地组织和管理代码。在本篇文章中,我们将介绍如何使用面向对象编程来构建复杂的应用程序。 ...
    99+
    2023-11-10
    对象 bash npm
  • 你知道怎么从Python角度学习Java基础
    目录1.变量赋值数据类型2.符号计算运算符比较运算符代码符注释文本符3.if一行if一次判断多次判断4.for5.while6.数组7.程序结构8.输入输出9.异常捕获总结1. 变量...
    99+
    2024-04-02
  • 怎么对Python程序学习过程进行总结
    今天就跟大家聊聊有关怎么对Python程序学习过程进行总结,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。你需要注意一些问题,比如代码编程和调试过程中的问题,这些一定要仔细和认真,Py...
    99+
    2023-06-17
  • 怎么从开发者的角度学习Linux内存管理
    今天就跟大家聊聊有关怎么从开发者的角度学习Linux内存管理,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。内存管理一向是所有操作系统书籍不惜笔墨重点讨论的内容,无论市面上或是网上都充...
    99+
    2023-06-16
  • TFLearn怎么简化深度学习模型的构建过程
    TFLearn是一个基于TensorFlow的深度学习库,它可以帮助简化深度学习模型的构建过程。以下是使用TFLearn简化深度学习...
    99+
    2024-04-02
  • 怎么用命令从mysql中导出/导入表结构及数据
    这篇文章给大家分享的是有关怎么用命令从mysql中导出/导入表结构及数据的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 在命令行下mysql的数据导出有个很好用命令mysqld...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作