postgresql 使用之 存储架构 触摸真实数据的存储结构以及组织形式,存入数据库的数据原来在这里

news2024/10/7 2:20:00

存储架构

在这里插入图片描述

专栏内容
postgresql内核源码分析
手写数据库toadb
并发编程
个人主页:我的主页
座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

概述

postgresql 数据库服务运行时,数据在磁盘上是如何存储的呢?这就涉及到了存储架构。
在文件系统中,我们可以看到以目录和文件为形式的存储单元,这是物理存储架构,
这些目录和文件实际上有一定的联系和组织形式,比如最外层目录就是集群数据目录,每个数据库会有一个目录,这就是逻辑存储架构。

逻辑存储架构,维护着物理磁盘文件的组织形式,物理存储架构是具体的磁盘文件的呈现方式。

逻辑存储架构

命名空间

在逻辑上,数据库有几层组织管理命名空间

在这里插入图片描述

集簇->表空间tablespace->数据库database->模式schema
其中 模式是数据库内核中通过数据字典来区分,所以前三项都是通过存储架构的组织,来实现物理上的空间独立。
这在前面内核分析文章中也提到,表文件的定位,也是通过tablespace/database/relation三级来唯一标识。

对于集簇这个概念,通过initdb创建的就是集簇,也就是数据存入的目录,在数据库服务启动时需要指定,它通常叫做PGDATA。

数据文件

用户数据文件

有表,索引,还有对应的vm,fsm文件,都是按照命名空间的层级目录来存储

事务相关数据

由集簇级层级的空间管理,在集簇目录下有公共目录存放

其它组织文件

如表空间文件,数据字典文件,模版库,运行日志等文件,都是集簇层级的空间进行管理,在集簇目录下有各自的目录

配置文件

  • 数据库配置文件

postgresql.conf

  • 客户端访问控制配置文件

pg_hba.conf和pg_ident.conf

辅助文件

如版本文件,运行信息文件等,都在PGDATA根目录下

物理存储架构

  1. 通常用PGDATA来引用(用的是可以定义它的环境变量的名字)。PGDATA的一个常见位置是/var/lib/pgsql/data。由不同数据库实例所管理的多个集簇可以在同一台机器上共存。
  2. 在表或者索引超过 1GB 之后,它就被划分成1G大小的段。
    第一个段的文件名和文件节点相同;随后的段被命名为 filenode.1、filenode.2等等。这样的安排避免了在某些有文件大小限制的平台上的问题(实际上,1GB只是默认的段尺寸。段尺寸可以在编译PostgreSQL时使用配置选项–with-segsize进行调整)。原则上,空闲空间映射和可见性映射分支也可以要求多个段,但实际上这很少发生。
  3. 每个数据库都会有一个单独的目录,其中存放该库的表文件。

集簇文件结构

先初始化一个全新的数据库集簇,下面初始化并启动数据库

# 初始化postgres数据库集簇 
/opt/postgres/bin/initdb -D pgtest -W

# 启动数据库,监听端口指定为 8888 
/opt/postgres/bin/pg_ctl -D pgtest -l logfile -o "-p 8888" start

# 以命令行客户端,登陆数据库,指定端口和数据库
/opt/postgres/bin/psql -p 8888 -d postgres

下面是initdb完成后,新建了一个表空间后的集簇目录结构,
然后为了看到一些文件类型,建了临时表,unlogged表,以及索引;
中间省略了一些表的文件列表,保留了目录层级和关键的文件。

-- 表空间 
create tablespace tblspc_test location '/mnt/sda1/data/pgdata/pgtblspc';

-- 普通表 
create table tbl_account(id integer, name varchar, address varchar, tel varchar);

-- 临时表 会话退出后就会删除 
create temporary table tmptbl_test(id int, c_id int);

-- unlogged 表,不会记录WAL,恢复时数据全部丢失 
create unlogged table unlogtbl_test(c_id int ,consumer varchar);
create index on unlogtbl_test (c_id);

经过上面的场景构造之后,现在来看一下数据库集簇下的文件和目录层次

[senllang@hatch pgdata]$ tree pgtest
pgtest
├── base
│   ├── 1
│   │   ├── 112
│   │   ├── 113
│   │   ├── 1247
│   │   ├── 1247_fsm
│   │   ├── 1247_vm
│   │   ├── 1249
......
│   │   ├── 827
│   │   ├── 828
│   │   ├── pg_filenode.map
│   │   ├── pg_internal.init
│   │   └── PG_VERSION
│   ├── 4
│   │   ├── 112
│   │   ├── 113
│   │   ├── 1247
│   │   ├── 1247_fsm
│   │   ├── 1247_vm
......
│   │   ├── 6238
│   │   ├── 6239
│   │   ├── 826
│   │   ├── 827
│   │   ├── 828
│   │   ├── pg_filenode.map
│   │   └── PG_VERSION
│   └── 5
│       ├── 112
│       ├── 113
│       ├── 1247
│       ├── 1247_fsm
│       ├── 1247_vm
│       ├── 16403
│       ├── 16403_init
│       ├── 16406
│       ├── 16406_init
│       ├── 16407
│       ├── 16407_init
│       ├── 16408
│       ├── 16408_init
│       ├── t3_16409
│       └── t3_16412
......
│       ├── 827
│       ├── 828
│       ├── pg_filenode.map
│       ├── pg_internal.init
│       └── PG_VERSION
├── global
│   ├── 1213
│   ├── 1213_fsm
│   ├── 1213_vm
│   ├── 1214
│   ├── 1232
│   ├── 1233
│   ├── 1260
│   ├── 1260_fsm
│   ├── 1260_vm
......
│   ├── pg_control
│   ├── pg_filenode.map
│   └── pg_internal.init
├── pg_commit_ts
├── pg_dynshmem
├── pg_hba.conf
├── pg_ident.conf
├── pg_logical
│   ├── mappings
│   ├── replorigin_checkpoint
│   └── snapshots
├── pg_multixact
│   ├── members
│   │   └── 0000
│   └── offsets
│       └── 0000
├── pg_notify
├── pg_replslot
├── pg_serial
├── pg_snapshots
├── pg_stat
├── pg_stat_tmp
├── pg_subtrans
│   └── 0000
├── pg_tblspc
│   └── 16388 -> /mnt/sda1/data/pgdata/pgtblspc
├── pg_twophase
├── PG_VERSION
├── pg_wal
│   ├── 000000010000000000000001
│   └── archive_status
├── pg_xact
│   └── 0000
├── postgresql.auto.conf
├── postgresql.conf
├── postmaster.opts
└── postmaster.pid

详细介绍

文件/目录描述
PG_VERSION一个包含PostgreSQL主版本号的文件
base包含每个数据库对应的子目录的子目录
current_logfiles记录当前被日志收集器写入的日志文件的文件
global包含集簇范围的表的子目录,比如pg_database
pg_commit_ts包含事务提交时间戳数据的子目录
pg_dynshmem包含被动态共享内存子系统所使用的文件的子目录
pg_logical包含用于逻辑复制的状态数据的子目录
pg_multixact包含多事务(multi-transaction)状态数据的子目录(用于共享的行锁)
pg_notify包含LISTEN/NOTIFY状态数据的子目录
pg_replslot包含复制槽数据的子目录
pg_serial包含已提交的可序列化事务信息的子目录
pg_snapshots包含导出的快照的子目录
pg_stat包含用于统计子系统的永久文件的子目录
pg_stat_tmp包含用于统计信息子系统的临时文件的子目录
pg_subtrans包含子事务状态数据的子目录
pg_tblspc包含指向表空间的符号链接的子目录
pg_twophase包含用于预备事务状态文件的子目录
pg_wal包含 WAL (预写日志)文件的子目录
pg_xact包含事务提交状态数据的子目录
postgresql.auto.conf一个用于存储由ALTER SYSTEM 设置的配置参数的文件
postmaster.opts一个记录服务器最后一次启动时使用的命令行参数的文件
postmaster.pid一个锁文件,记录着当前的 postmaster 进程ID(PID)、集簇数据目录路径、postmaster启动时间戳、端口号、Unix域套接字目录路径(Windows上为空)、第一个可用的listen_address(IP地址或者*,或者为空表示不在TCP上监听)以及共享内存段ID(服务器关闭后该文件不存在)

表空间

在表空间中创建了一个临时表,一个普通表,还有一个数据库

-- 创建数据库,指定存储的表空间 
create database test tablespace tblspc_test ;

-- 在指定表空间创建临时表 
create temporary table tmptbl_test1(id int, c_id int) tablespace tblspc_test;

-- 在指定表空间创建普通表 
create table tbl_salary(id integer, level float, performance float) tablespace tblspc_test;

物理结构

查看表空间目录中文件,目录层次和文件列表如下

[senllang@hatch pgdata]$ tree pgtblspc/
pgtblspc/
└── PG_16_202306141
    ├── 16389
    │   ├── 112
    │   ├── 113
    │   ├── 1247
    │   ├── 1247_fsm
    │   ├── 1247_vm
    │   ├── 1249
    │   ├── 1249_fsm
    │   ├── 1249_vm
    ......
    │   ├── 826
    │   ├── 827
    │   ├── 828
    │   ├── pg_filenode.map
    │   └── PG_VERSION
    └── 5
        ├── 16395
        └── t3_16413

可以看到,在表空间的目录下,是一个目录 PG_16_202306141,命名以PG开头,然后是数据库版本,再加创建的日期。
用户定义的表空间都在PGDATA/pg_tblspc目录里面有一个符号连接,它指向物理的表空间目录(就是在CREATE TABLESPACE命令里指定的那个目录)。
这个符号连接是用表空间的 OID 命名的。

原理说明

在物理表空间目录中有一个名称取决于PostgreSQL服务器版本的子目录,例如PG_16_202306141(使用该子目录的原因是后续版本的数据库可以使用CREATE TABLESPACE指定相同的目录位置而不会造成冲突)。

在这个版本相关的子目录中,为每个在这个表空间里有元素的数据库都有一个子目录, 以数据库的OID命名。该目录里的表和索引遵循文件节点命名模式。

初始化集群后,有两个默认的表空间,pg_default和pg_global,当我们没有指定表空间时,创建的数据库,表等都是存放在pg_default表空间。
pg_default不需要通过pg_tblspc来访问,而是对应于PGDATA/base。类似地,pg_global表空间也不通过pg_tblspc访问,而是对应于PGDATA/global。

数据库

在这里插入图片描述

对于集簇里的每个数据库,在PGDATA/base里都有一个子目录对应,子目录的名字为该数据库在 pg_database里的 OID。
这个子目录是该数据库文件的缺省位置;特别值得一提的是,该数据库的系统目录存储在此。

数据文件

pg_relation_filepath()函数显示任何关系的完整路径(相对于PGDATA)。
它可以作为记住上面这么多规则的替代方法。

但是记住该函数只给出关系的主分支的第一个段的名称 — 你也许需要追加一个段号或_fsm、_vm、_init来找到与该关系相关的所有文件。

表和索引文件

每个表和索引都存储在独立的文件里。
对于普通表,这些文件以表或索引的filenode号命名,它可以在pg_class.relfilenode中找到。

临时表

对于临时表,文件名的形式为tBBB_FFF,其中BBB是创建该文件的后台的后台ID,FFF是文件节点号。

空闲空间映射fsm

在每种情况下,在主文件(a/k/a 主分支)之外,每个表和索引有一个空闲空间映射,它存储表中可用空闲空间的信息。
空闲空间映射存储在一个文件中,该文件以节点号加上后缀_fsm命名。

可见性映射vm

表还有一个可见性映射,存储在一个该文件以节点号加上后缀为_vm的文件中,它用于跟踪哪些页面已知含有非死亡元组。

unlogged 表

不被日志记录的表和索引,也就是unloged table 还有第三个分支,即初始化分支,它存储在该文件以节点号加上后缀为_init的分支文件中。

初始化分支是一个适当类型的空表或空索引。
当一个不被日志记录的表由于崩溃必须被重置为空时,初始化分支被随着主分支复制,而任何其他分支则被擦除(它们会在需要时自动被重建)。

toast表

如果一个表的列中可能存储相当大的项,那么该表就会有个与之相关联的TOAST表,
它用于存储无法保留在在表行中的域值的线外存储。

如果表有TOAST表,该表的pg_class.reltoastrelid链接到它的TOAST表;

临时文件

临时文件(用于如排序不能放在内存中的数据等操作)被创建在PGDATA/base/pgsql_tmp中,如果临时文件被指定在一个非pg_default表空间中则它们会被创建在该表空间的pgsql_tmp子目录中。临时文件的名称的形式为pgsql_tmpPPP.NNN,其中PPP是其所属后端的PID,而NNN用于区别该后端的不同临时文件。

结尾

非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!

作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。

注:未经同意,不得转载!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/842383.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

对返回引用函数的进一步解释

#include <iostream> #include <string> using namespace std; class Box { public:Box(string name,int age):name(name),age(age){}string& getname() //返回引用的函数{cout << "&name: " << (int)&name << endl;retur…

Maven入职学习

一、什么是Maven&#xff1f; 概念&#xff1a; Maven是一种框架。它可以用作依赖管理工具、构建工具。 它可以管理jar包的规模、jar包的来源、jar包之间的依赖关系。 它的用途就是管理规模庞大的jar包&#xff0c;脱离IDE环境执行构建操作。 具体使用&#xff1a; 工作机…

Clickhouse 存储引擎

一、常用存储引擎分类 1.1 ReplacingMergeTree 这个引擎是在 MergeTree 的基础上&#xff0c;添加了”处理重复数据”的功能&#xff0c;该引擎和MergeTree的不同之处在于它会删除具有相同主键的重复项。 特点: 1使用ORDERBY排序键作为判断重复的唯一键 2.数据的去重只会在合并…

复习之selinux的管理

一、什么是selinux? SELinux&#xff0c;Security Enhanced Linux 的缩写&#xff0c;也就是安全强化的 Linux&#xff0c;是由美国国家安全局&#xff08;NSA&#xff09;联合其他安全机构&#xff08;比如 SCC 公司&#xff09;共同开发的&#xff0c;旨在增强传统 Linux 操…

x光下危险物品/违禁物品目标识别的模型训练与推理代码

前言 1.安检在公共场合的重要性不言而喻&#xff0c;保障群众人身安全是其首要任务。在各种场合&#xff0c;安检都是不可或缺的环节。x光安检机作为安检的重要工具&#xff0c;尽管其具有人工监控判断成像的特性&#xff0c;但是其局限性也十分明显。 为了解决这一局限性为出…

面试题:bind、call、apply 区别?如何实现一个 bind?

面试题&#xff1a;bind、call、apply 区别&#xff1f;如何实现一个 bind? 一、call()代码描述&#xff1a; 二、apply()代码描述&#xff1a; 三、bind()—最重要代码描述&#xff1a; 四、call、apply、bind 总结 一、call() 代码描述&#xff1a; 二、apply() 代码描述&am…

广州VR制作 | 利用VR元宇宙平台开展林地管理培训的优势

在林业领域&#xff0c;实地调查是获取准确数据和深入了解森林生态的重要手段。然而&#xff0c;传统的实地调查方法存在诸多问题&#xff0c;如时间成本高、人力物力投入大、安全风险高等。为了解决这些教学痛点&#xff0c;我们引入了虚拟现实(VR)技术&#xff0c;通过虚拟林…

PO模式在selenium自动化测试框架有什么好处

PO模式是在UI自动化测试过程当中使用非常频繁的一种设计模式&#xff0c;使用这种模式后&#xff0c;可以有效的提升代码的复用能力&#xff0c;并且让自动化测试代码维护起来更加方便。 PO模式的全称叫page object model&#xff08;POM&#xff09;&#xff0c;有时候叫做 p…

解读百胜中国2023年第二季度财报:聚焦下沉市场,扩店实力几何?

从全网玩梗的“肯德基疯狂星期四”文学&#xff0c;到大小朋友疯狂抢购的六一三丽鸥玩具联名&#xff0c;再到不久前爆火的必胜客原神联名活动&#xff0c;肯德基、必胜客这两大家喻户晓的快餐品牌&#xff0c;被不少新闻调侃为“顶流制造机”。而近日&#xff0c;这两大顶流背…

【c++进阶】--哈希

1.unordered系列关联式容器 在C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;在查询时效率可达到 &#xff0c;即最差情况下 需要比较红黑树的高度次&#xff0c;当树中的节点非常多时&#xff0c;查询效率也不理想。最好的查询是&#xff0c;进行…

【Linux】五种IO模型

文章目录 1. IO基本概念2. 五种IO模型2.1 五个钓鱼的例子2.2 五种IO模型2.2.1 阻塞IO2.2.2 非阻塞IO2.2.3 信号驱动IO2.2.4 IO多路转接2.2.5 异步IO 1. IO基本概念 认识IO IO就是输入和输出&#xff0c;在冯诺依曼体系结构中&#xff0c;将数据从输入设备拷贝到内存就叫输入&am…

解决MAC M1处理器运行Android protoc时出现的错误

Protobuf是Google开发的一种新的结构化数据存储格式&#xff0c;一般用于结构化数据的序列化&#xff0c;也就是我们常说的数据序列化。这个序列化协议非常轻量级和高效&#xff0c;并且是跨平台的。目前&#xff0c;它支持多种主流语言&#xff0c;比传统的XML、JSON等方法更具…

【数模】主成分分析PCA

主成分分析(Principal Component Analysis,PCA)&#xff0c;是一种降维算法&#xff0c;它能将多个指标转换为少数几个主成分&#xff0c;这些主成分是原始变量的线性组合&#xff0c;且彼此之间互不相关&#xff0c;其能反映出原始数据的大部分信息。使用场景&#xff1a;一般…

详解Quest 2积分与奖励规则

7月28日&#xff0c;在万众期待中&#xff0c;Mysten Labs在Quest门户网站上宣布了Quest 2的到来。经过严密的筹划&#xff0c;本着真实、公平以及用户至上的原则&#xff0c;现在向大家介绍Quest 2的积分规则以及奖励规则。 温馨提示&#xff1a;第一轮Bullshark Quest是一次精…

SpringBoot+Vue实现软件工程课程在线考试系统

博主主页&#xff1a;一季春秋博主简介&#xff1a;专注Java技术领域和毕业设计项目实战、Java、微信小程序、安卓等技术开发&#xff0c;远程调试部署、代码讲解、文档指导、ppt制作等技术指导。主要内容&#xff1a;毕业设计(Java项目、小程序等)、简历模板、学习资料、面试题…

利用appium抓取app中的信息

一、appium简介 二、appium环境安装 三、联调测试环境 四、利用appium自动控制移动设备并提取数据

mysql转sqlite3

在项目中需要将mysql迁移到sqlite3中&#xff0c;此时需要作数据转换 准备工作 下载mysql2sqlite转换工具 https://github.com/dumblob/mysql2sqlite/archive/refs/heads/master.zip 下载sqlite3 https://www.sqlite.org/download.html 转换 命令行中输入如下命令 1、cd …

6.6 实现卷积神经网络LeNet训练并预测手写体数字

模型架构 代码实现 import torch from torch import nn from d2l import torch as d2lnet nn.Sequential(nn.Conv2d(1,6,kernel_size5,padding2),nn.Sigmoid(),#padding2补偿5x5卷积核导致的特征减少。nn.AvgPool2d(kernel_size2,stride2),nn.Conv2d(6,16,kernel_size5),nn.S…

[疑难杂症2023-007]multiprocessing.Process使用时遇到的几个棘手问题

本文由Markdown编辑器编辑完成。 1. 背景 近日&#xff0c;为了解决自己负责的一个组件&#xff0c;在处理大量数据时&#xff0c;由于内存释放不及时&#xff0c;而导致整个组件占用了较高的内存。 这主要是因为目前我们在使用python的一个采用多进程的框架——Celery. 关于…

解决Map修改key的问题

需求 现在返回json数据带有分页的数据&#xff0c;将返回data属性数据变更为content&#xff0c;数据不变&#xff0c;key发生变化 实现1&#xff0c;源数据比较复杂&#xff0c;组装数据比较麻烦 说明&#xff1a;如果使用这种方式完成需求&#xff0c;需要创建对象&#xff0…