当前位置: 首页 > news >正文

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

存储架构

在这里插入图片描述

专栏内容
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
如有错误或者疏漏欢迎指出,互相学习。

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

相关文章:

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

存储架构 ​专栏内容: postgresql内核源码分析 手写数据库toadb 并发编程 个人主页:我的主页 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物. 概述 postgresql 数据库服务运行时,数据在磁…...

Node.Js安装与配置教程

目录 1.下载官网 2.选择安装路径 3.添加环境变量 4.验证是否安装成功 5.修改模块下载位置 (1)查看npm默认存放位置 6.在node.js安装目录下,创建两个文件夹 7.修改默认文件夹 8.测试默认位置是否更改成功 9.安装报错解决办法 10.路径未更改成功解决办法 …...

Element-Plus DatePicker获取时间戳

文章目录 0、先上答案1、渔&#xff1f;1-1 Element-Plus 官网1-2 溯源 Day.js 0、先上答案 <!-- 秒 --><el-date-pickerv-model"timeStamp"type"datetime"value-format"X"/><!-- 毫秒 --><el-date-pickerv-model"tim…...

【算法第十五天7.29】513.找树左下角的值 112. 路径总和 106.从中序与后序遍历序列构造二叉树

链接力扣513-找树左下角的值 思路 class Solution {public int findBottomLeftValue(TreeNode root) {Queue<TreeNode> queue new LinkedList<>();queue.offer(root);int res 0;while(!queue.isEmpty()){int size queue.size();for(int i 0; i < size; i)…...

Java thymeleaf bug排查记录

刚学Java 做项目时报了一个错误 一时间看的莫名其妙 EL1008E: Property or field createTime cannot be found on object of type java.util.HashMap - maybe not public or not valid? 随即向上排查至第一个报错&#xff0c;发现是thymeleaf渲染时报错。 Exception proces…...

互感和励磁电感(激磁电感)的关系

互感器&#xff0c;变压器&#xff0c;他们之间有着千丝万缕的联系&#xff0c;自感&#xff0c;互感&#xff0c;激磁电感&#xff0c;漏感、耦合系数、理想互感器、理想变压器&#xff0c;这些东西的概念理解和相互之间的关系式。都搞明白了吗&#xff1f;...

stdexcept和exception,两个头文件的区别?

stdexcept和exception是C标准库中的两个头文件&#xff0c;它们的区别如下&#xff1a; 1. 引用方式&#xff1a;stdexcept是exception的父类&#xff0c;引用时可以通过引用stdexcept来自动引用exception&#xff0c;也可以直接引用exception。 2. 异常处理&#xff1a;std…...

openCV图像的读写操作

文章目录 一、数组下标二、指针 void QuickDemo::pixel_visit_demo(cv::Mat &image) {int w image.cols;int h image.rows;int dim image.channels();for (int row 0; row < h; row){for (int col 0; col < w; col){if (dim 1)//灰度图像{int pv image.at<…...

Android平台GB28181设备接入端如何降低资源占用和性能消耗

背景 我们在做GB28181设备接入模块的时候&#xff0c;考虑到好多设备性能一般&#xff0c;我们一般的设计思路是&#xff0c;先注册设备到平台侧&#xff0c;平台侧发calalog过来&#xff0c;获取设备信息&#xff0c;然后&#xff0c;设备侧和国标平台侧维持心跳&#xff0c;…...

Android Studio安装AI编程助手Github Copilot

csdn原创谢绝转载 简介 文档链接 https://docs.github.com/en/copilot/getting-started-with-github-copilot 它是个很牛B的编程辅助工具&#xff0c;装它&#xff0c;快装它&#xff0e; 支持以下IDE: IntelliJ IDEA (Ultimate, Community, Educational)Android StudioAppC…...

windows部署springboot项目 jar项目 (带日志监听和开机自起脚本)

windows部署springboot项目 jar项目 &#xff08;带日志监听&#xff09; 1.把项目打包成jar包&#xff0c;本例演示打包后的jar文件名为demo.jar ———————————————— 2.需要装好java环境&#xff0c;配置好JAVA_HOME&#xff0c;CLASSPATH&#xff0c;PATH等…...

【数据结构和算法】排序算法

说明&#xff1a;以下排序如无特别说明&#xff0c;都是从小到大升序排序 1. 冒泡排序 核心思想&#xff1a;每个元素与其相邻元素比较&#xff0c;如果前者大于后者则交换&#xff0c;每次循环结束后会将最大值放到最后&#xff0c;像小水泡从底下冒到上面成大水泡一样&…...

Error: Cannot find module ‘@babel/core’处理

Error: Cannot find module babel/core’处理 问题产生的原因如何解决 在安装babel的时候&#xff0c;遇到个**Error: Cannot find module babel/core’**问题&#xff0c;查了很多资料才解决&#xff0c;希望能够帮助到各位兄弟。 问题产生的原因 babel-loader和babel-core版…...

K8S系列文章之 自动化运维利器 Fabric

Fabric 主要用在应用部署与系统管理等任务的自动化&#xff0c;简单轻量级&#xff0c;提供有丰富的 SSH 扩展接口。在 Fabric 1.x 版本中&#xff0c;它混杂了本地及远程两类功能&#xff1b;但自 Fabric 2.x 版本起&#xff0c;它分离出了独立的 Invoke 库&#xff0c;来处理…...

flask--->CBV/模板/请求响应/session

CBV 1 cbv写法-1 写个类&#xff0c;继承MethodView-2 在类中写跟请求方式同名的方法-3 注册路由&#xff1a;app.add_url_rule(/home, view_funcHome.as_view(home)) #home是endpoint&#xff0c;就是路由别名2 cbv加装饰器-方式一&#xff1a;class Home(MethodView):decor…...

Go语言基础:运算符、文件操作、接口、Packages、if else、for循环

文章目录 1.运算符2.文件操作3.接口4.Packages5.If else6.For循环 1.运算符 func main() {// 算术运算符a, b : 3, 7c : a bd : a - be : a * bf : a / bg : a % baa--fmt.Println(c, d, e, f, g)// 关系运算符fmt.Println(a b)fmt.Println(a ! b)fmt.Println(a < b)fmt.…...

2308C++学习简单协程文档

调试 用gdb/lldb p __coro_frame p __promise试 Try有三种状态:无状态,有异常,有值. 条件变量 主要区别在简单异步中条件变量面向Lazy协程.在条件变量上阻塞协程时,不会阻塞当前线程.用于多个协程间交互协作.基于协程版条件变量,多个协程可实现典型生产者消费者模型. 通知…...

C++笔记之从数组指针到函数数组指针(使用using name和std::function)

C笔记之从数组指针到函数数组指针(使用using name和std::function) 参考笔记&#xff1a; C之指针探究(三)&#xff1a;指针数组和数组指针 C之指针探究(十三)&#xff1a;函数指针数组 C之指针探究(二)&#xff1a;一级指针和一维数组 C之指针探究(十一)&#xff1a;函数名的…...

【数据结构】常见的排序算法

常见的排序算法 常见的排序算法插入排序之直接插入排序时间复杂度特性总结 插入排序之希尔排序时间复杂度 选择排序之直接选择排序特性总结 选择排序之堆排序时间复杂度特性总结 交换排序之冒泡排序特性总结 交换排序之快速排序hoare版本挖坑法双指针法快速排序的优化1&#xf…...

CentOS 安装 Jenkins

本文目录 1. 安装 JDK2. 获取 Jenkins 安装包3. 将安装包上传到服务器4. 修改 Jenkins 配置5. 启动 Jenkins6. 打开浏览器访问7. 获取并输入 admin 账户密码8. 跳过插件安装9. 添加管理员账户 1. 安装 JDK Jenkins 需要依赖 JDK&#xff0c;所以先安装 JDK1.8。输入以下命令&a…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...

MySQL的pymysql操作

本章是MySQL的最后一章&#xff0c;MySQL到此完结&#xff0c;下一站Hadoop&#xff01;&#xff01;&#xff01; 这章很简单&#xff0c;完整代码在最后&#xff0c;详细讲解之前python课程里面也有&#xff0c;感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...

规则与人性的天平——由高考迟到事件引发的思考

当那位身着校服的考生在考场关闭1分钟后狂奔而至&#xff0c;他涨红的脸上写满绝望。铁门内秒针划过的弧度&#xff0c;成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定"&#xff0c;构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...