这一章主要介绍四个概念:

数据库集群的逻辑结构

数据库集群的物理结构

表文件的内部布局

读写数据元组的方法

01

数据库集群的逻辑结构

Pg中的集群,也即database cluster,是由PostgreSQL服务端来管理的一组数据库(database)的集合。注意这里是数据库(database)的集合,不是数据库服务(database servers)的集合。一个PostgreSQL服务器运行在单个主机上,管理单个数据库集群。

Pg与大多数的关系型数据库一样都是由表来存储数据,一个表(table)属于某个数据库(database),数据库(database)又同属于一个database cluster。

图1.1.数据库集群的逻辑结构

图片来源:https://www.interdb.jp/pg/pgsql01.html

在一个数据库集群中,除了有表、数据库这些数据库对象,还有比如索引、视图、函数、序列等对象,pg对这些对象统一采用对象标识符(OIDs)来管理,oid是无符号的4字节整数。数据库对象和各自的oid存储在各自的system catalogs中,比如table是存储在pg_class, 而dababase存储在pg_database中。

02

数据库集群的物理结构

上面我们谈的是集群的逻辑结构,也即抽象概念。现在我们聊聊的物理结构也即真实存在的结构。实际上,pg的数据库集群本质上是一个目录。目录中包含一些子目录和很多的文件。

在我们安装pg时,我们一般使用initdb的命令去初始化一个新的数据库集群。initdb 有个-D参数,通过它来指定应该存储数据库集群的目录。(initdb命令可以参考我之前的一篇博客:

https://blog.csdn.net/qq_35462323/article/details/104059818)

而集群中的database对应$PGDATA/base目录下的一个文件夹,文件夹的名称即我们上面提到的oid。

比如我的pg数据上有下面四个数据库(使用\l命令查看所有数据库):

分别查看其oid:

select datname,oid from pg_database where datname in ('postgres','template0','template1','testextenddb');

可以发现查询到的oid是与base子目录下文件夹名是一一对应的。

图1.2.数据库集群示例

图片来源:https://www.interdb.jp/pg/pgsql01.html

那么database中的table是否也是对应base目录下的一个路径呢?答案是是的。

pg中size小于1GB的表或者索引都是存储在其所属的数据库目录下的某个文件。表和索引作为数据库对象在内部由单独的oid管理,而这些数据文件由变量relfilenode管理。

比如查看postgres数据库下的autotest_check表的oid和relfilenode

select oid,relfilenode  from pg_class where relname = 'autotest_check' limit 1;

此时,autotest_check对应文件的路径为'base/13287/21415'

注意:表和索引的relfilenode值并不总是与各自的oid匹配,因为表和索引的relfilenode值会因为TRUNCATE, REINDEX, CLUSTER等命令而改变。

在9.0或更高版本中,可以使用pg_relation_filepath函数返回某个table对应的oid路径。

比如此处的autotest_check,确实是为上面分析的'base/13287/21415'。

当表和索引的文件大小超过1GB时,PostgreSQL会创建一个名为relfilenode.1 的文件,如果新文件已被填满,则下一个名为relfilenode.2的文件将被创建,以此类推(注:在构建PostgreSQL时,可以使用选项——with-segsize来更改表和索引的最大文件大小)。

除了database对应于$PGDATA下的base文件夹,我们还要了解下,$PGDATA下的其他文件或者文件夹的含义和作用。

下表来源官方文档:https://www.postgresql.org/docs/current/storage-file-layout.html。

表1.1.$PGDATA目录下的文件和子目录的布局

PG_VERSION 包含PG大版本号的文件
postgresql.auto.conf 用于存储由ALTER SYSTEM设置的配置参数
postmaster.opts 记录服务器上次启动时使用的命令行参数的文件
postmaster.pid 一个锁文件,记录当前postmaster进程的pid,cluster data目录路径,postmaster进程启动时的时间戳,端口号,Unix-domain socket目录路径,有效的listen_address(ip地址或者*,如果为空表示server不基于tcp),共享内存端id。
current_logfiles 记录日志采集器当前写入的日志文件的文件
base 包含每个数据库的子目录
global 包含集群范围表的子目录,例如pg_database
pg_commit_ts 包含事务提交时间戳数据的子目录
pg_dynshmem 包含动态共享内存子系统使用的文件的子目录
pg_logical 包含用于逻辑解码的状态数据的子目录
pg_multixact 包含多事务状态数据的子目录(用于共享行锁)
pg_notify 包含监听/通知状态数据的子目录
pg_replslot 包含复制槽位数据的子目录
pg_serial 包含关于已提交的可序列化事务信息的子目录
pg_snapshots 导出快照的子目录
pg_stat 包含统计子系统永久文件的子目录
pg_stat_tmp 包含统计子系统临时文件的子目录
pg_subtrans 包含子事务状态数据的子目录
pg_tblspc 包含到表空间的符号链接的子目录
pg_twophase 包含已准备事务状态文件的子目录
pg_wal 包含WAL (Write Ahead Log)文件的子目录
pg_xact 包含事务提交状态数据的子目录

03

表文件的内部布局

在table数据文件内部,文件是被划分为固定长度的页(或块),默认是8kb大小。每个文件中的页面从0开始按顺序编号,这些数字称为块号。如果文件被填满,PG会在文件的末尾添加一个新的空页来增加文件的大小。

图1.3.表文件的页面布局

图片来源:https://www.interdb.jp/pg/pgsql01.html

表中的页面包含三种数据:

heap tuples: 堆元组,用于记录数据,从页面底部开始按顺序排列,tuple的内部结构将在第5章和第9章详细介绍。

line pointers: 行指针,占4个字节,保存着指向每个堆元组的指针。行指针构成一个简单的数组,它扮演元组索引的角色。每个索引从1开始按顺序编号,称为偏移量号。当一个新的元组被添加到页面时,一个新的行指针也被推到数组上以指向新的元组。

header data:Header数据,占24个字节,用于存储页面的基本信息。

源码中由PageHeaderData结构定义。该结构中主要变量:

pd_lsn: 这个变量存储该页面最后一次更改时写入的xlog记录的lsn。是一个8字节的无符号整数。

pd_checksum: 这个变量存储这个页面的检验和值。

pd_lower:指向行指针的末尾。

pd_upper:  执行最新的堆元祖的开始。

pd_special: 在表中的页面中,它指向页面的末尾。

另:行指针的末尾和最新元组的开始之间的空白称为空闲空间或空洞。

04

读写数据元组的方法

文章最后,介绍下写和读数据元组的方法。

首先是写元组:

假设一个表由一个页面组成,其中只包含一个堆元组。这个页面的pd_lower指向第一个行指针,而line指针和pd_upper都指向第一个堆元组。见图1.4 (a)。

插入第二个元组时,它被放置在第一个元组之后。第二行指针被压入第一行,它指向第二个元组。pd_lower指向第二行指针,而pd_upper指向第二个堆元组。见图1.5 (b)。这个页面中的其他头数据(例如,pd_lsn, pg_checksum, pg_flag)也被重写为合适的值; 更多详情见第5章和第9章。

图1.4.写数据元组

再来是读数据元组:

读数据两种典型的访问方法,顺序扫描和b树索引扫描,概述如下:

顺序扫描——通过扫描每个页面中的所有行指针,顺序地读取所有页面中的所有元组。见图1.5(a)。

B-tree索引扫描——索引文件包含索引元组,每个索引元组由一个索引键和一个指向目标堆元组的TID组成。如果您正在寻找的键的索引元组已经找到,PostgreSQL将使用获得的TID值读取所需的堆元组。例如在图1.5(b)中,得到的索引元组的TID值为' (block = 7, Offset = 2) '。这意味着目标堆元组是表中第7页的第2个元组,因此PostgreSQL可以读取所需的堆元组,而无需在页面中进行不必要的扫描。

图1.5.读数据元组

postgresql保存图片_第一章 PostgreSQL中的数据库集群、数据库和表相关推荐

  1. 翻译【ElasticSearch Server】第一章:开始使用ElasticSearch集群(2)

    安装和配置集群(Installing and Configuring your Cluster) 第一步是确保正确安装了 Java SE环境.ElasticSearch需要版本6或更高的版本,可以从下 ...

  2. 第一章、Kubernetes基础之集群搭建(二进制安装)

    集群安装 基本环境配置 10.103.236.201 k8s-master01 # 2C2G 40G 10.103.236.202 k8s-master02 # 2C2G 40G 10.103.236 ...

  3. nginx工作笔记005---nginx配置负载均衡_在微服务中实现网关集群_实现TCP传输层协议__http协议的负载均衡

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 我们在微服务中,由于网关的存在,后来,在nginx中都不需要在配置其他服务的地址了,只需要,配置一 ...

  4. c++语言编程,一个电灯两个开关控制,[理学]四川大学计算机学院精品课程_面向对象程序设计C++课件_游洪越_第一章绪论.ppt...

    [理学]四川大学计算机学院精品课程_面向对象程序设计C课件_游洪越_第一章绪论 主讲教师: 游洪跃 个人主页: /~youhongyue 邮件地址: youhongyao@ 教材:<C++面向对 ...

  5. 第一章 SQL中使用的符号

    文章目录 第一章 SQL中使用的符号 符号表 第一章 SQL中使用的符号 SQL中用作运算符等的字符表 符号表 每个符号的名称后跟其ASCII十进制代码值. 符号 名称和用法 [space] or [ ...

  6. 读书笔记|《金字塔原理》_第一章

    读书笔记|<金字塔原理>_第一章 [章节]--第一章为什么要用金字塔结构 [讲了什么] 1.首先是为什么要用金字塔结构? 2.如何将思想组织成金字塔结构? 2.1 归类分组,将思想组织成金 ...

  7. 【笔记】Cocos2d-x高级开发教程:制作自己的捕鱼达人 笔记一:序_前言_第一章

    [笔记]Cocos2d-x高级开发教程:制作自己的<捕鱼达人> 笔记一:序_前言_第一章 转载请注明出处:http://blog.csdn.net/l_badluck/article/de ...

  8. 马丁福勒《UML精粹》读书笔记_第一章

    马丁福勒<UML精粹>读书笔记_第一章 UML的使用场景 必须遵从UML规则吗? 在上述草图.蓝图的场景下,不必过多强调遵从UML规则.因为我们使用UML的目的是为了一个好的设计,所以应将 ...

  9. 计算机中的数制与编码教程,第一章计算机中的数据和编码教程.doc

    第一章计算机中的数据和编码教程 第一章 计算机中的数据和编码 1.1计算机中的数制 1.2计算机中数的表示 1.3计算机中的编码 1.1 计算机中的数制之进位计数制 进位制: 按照进位的方法进行计数的 ...

  10. 最小类型的微型计算机是什么,第一章-微型计算机中的数据类型.ppt

    第一章-微型计算机中的数据类型 第一章 微型计算机中的数据类型 第一章 微型计算机中的数据类型 1.1 常用数据类型 带符号整数.无符号整数. BCD数(包括压缩的和非压缩 的二–十进制码). 字符串 ...

最新文章

  1. [汇编语言学习笔记][第二章寄存器]
  2. 一个初学者的SAP Cloud Platform学习笔记
  3. 曝光!衡中教室高清摄像头记录:不想一辈子吃苦,就必须闻鸡起舞!(转给学生)...
  4. unoconv 在线预览 doc,doxc,xls,xlsx,ppt,pptx 文件功能环境搭建
  5. python不支持prelu_MTCNN(九)更改python与c代码的PReLU为ReLU
  6. top、kill实现进程结束
  7. 西安理工大学计算机考研备考指南(863数据结构)
  8. Centos 关闭密码字典检查
  9. manjaro安装nvidia显卡驱动
  10. wav音频文件转换为sbc音频文件
  11. HighCharts柱状图显示百分比
  12. 使用Wps切分单页PDF文件为多页pdf
  13. 大写金额转换成阿拉伯数字金额
  14. Ant Design 实现表格合并
  15. 什么是正向代理和反向代理
  16. excel如何选中从当前单元格第一行跳到内容最后一行或者从选的最后一行跳到第一行
  17. arduino平衡车超声波_制作Arduino自平衡车(一)
  18. MySQL性能问题以及查找和处理
  19. RabbitMQ高可用集群搭建
  20. 200-Smart学习笔记:比较传送移位指令的用法案例(3)

热门文章

  1. Java不适合于作为主要编程教学语言 -- 孟岩
  2. 再议 封装、继承、多态
  3. Atitit 读取数据库的api orm SQL Builder sql对比 目录 1.1. 提高生产效率的 ORM 和 SQL Builder 1 1.2. SQL Builder 在 SQL
  4. Atitit it软件领域职称评级规定,广博方向。 目录 1. 软件工程师资格证 1 1.1. 法规规范 十大标准,三级五晋制。 1 1.2. 组织架构 域职称评级委员会 2 1.3. 人员职责流程表
  5. Atitit 提升开发效率总结 目录 1. declara dynamic Dsl化 fp script 1 1.1. 各种语法新特性 linq等 2 1.2. duck typing。 2
  6. atitit 国家与社区发展战略研究attilax 总结 v2 .docx
  7. Atitit 图像处理类库大总结attilax qc20
  8. Atitit 在线支付系统功能设计原理与解决方案 与目录
  9. atitit。流程图的设计与制作 attilax 总结
  10. atitit.提升开发效率---MDA 软件开发方式的革命(3)----自动化建表