PostgreSQL体系结构--物理结构

奋斗吧
奋斗吧
擅长邻域:未填写

标签: PostgreSQL体系结构--物理结构 博客 51CTO博客

2023-07-25 18:24:13 212浏览

PostgreSQL体系结构--物理结构,物理结构对应在操作系统中组成的数据库目录和相关文件来构成一、基础目录$PGDATA:baseglobalpg_commit_tspg_walpg_tblspc:alternativedatabasefiles二、目录布局base--存放默认数据库的目录global--存放的数据库相关的字典视图或者表文件pg_commit_ts--事务存放的提交的

物理结构
对应在操作系统中组成的数据库目录和相关文件来构成

一、 基础目录

$PGDATA:
base global pg_commit_ts pg_wal

pg_tblspc:
alternative database files

二、 目录布局

base 				--存放默认数据库的目录
global				--存放的数据库相关的字典视图或者表文件		
pg_commit_ts		    --事务存放的提交的时间戳数据
pg_dynshmem		--动态内存分配存放的空间(dynamic share memeory)
pg_hba.conf			--基于主机的配置文件
pg_ident.conf		    --基于对等认证的配置文件
pg_logical			--存储数据库内部状态的逻辑解码数据
pg_multixact		    --存放多事务状态的数据
pg_notify			    --消息通知目录(LISTEN状态目录)
pg_replslot			--存放复制槽的数据
pg_serial			    --提交的可串行化事务的状态数据
pg_snapshots		    --执行导出快照函数时的状态信息数据
pg_stat 			    --统计信息目录
pg_stat_tmp 		    --临时统计信息目录
pg_subtrans	        --子事务目录
pg_tblspc            --表空间映射目录
pg_twophase         --两阶段提交状态的数据
PG_VERSION	        --存放主版本编号的文件
pg_wal				--存储 WAL 文件的目录
pg_xact 			    --事务提交的状态数据
postgresql.auto.conf --存储通过 ALTER SYSTEM 命令修改的参数文件(可以手动修改)
postgresql.conf       --数据库的参数配置文件
postmaster.opts       --上一次数据库启动状态的命令
postmaster.pid        --存放当前数据库的主进程编号及相关目录及端口的信息

三、 表和索引

OID:对象标识符

数据库的OID→pg_database

表、索引、序列的OID→pg_class

创建表并查看表路径

postgres=# create table test(id int,name varchar);
CREATE TABLE

postgres=# select oid,relname from pg_class where relname='test';
  oid  | relname 
-------+---------
 16405 | test
(1 row)

postgres=# select pg_relation_filepath('test');
 pg_relation_filepath 
----------------------
 base/14187/16405
(1 row)

查看对应文件

[postgres@training ~]$ cd $PGDATA/base/14187

[postgres@training 14187]$ ls -lh 16405
-rw------- 1 postgres postgres 0 Feb 19 10:40 16405

插入数据,查看表大小

postgres=# insert into test values (1,'postgresql');
INSERT 0 1

postgres=# select pg_size_pretty(pg_relation_size('test'));
 pg_size_pretty 
----------------
 8192 bytes
(1 row)

查看对应文件

[postgres@training 14187]$ ls -lh 16405
-rw------- 1 postgres postgres 8.0K Feb 19 10:45 16405

刚开始创建表不会分配空间,只有插入数据才会为表分配空间

插入1000w数据

postgres=# insert into test select id,id||'dagedaged' from generate_series(1,10000000) as id;

postgres=# select pg_size_pretty(pg_relation_size('test'));
 pg_size_pretty 
----------------
 498 MB
(1 row)

查看对应文件

[postgres@training 14187]$ ls -lh 16405*
-rw------- 1 postgres postgres 498M Feb 19 10:54 16405
-rw------- 1 postgres postgres 144K Feb 19 10:53 16405_fsm

插入1500w数据

postgres=# insert into test select id,id||'dageaged' from generate_series(10000000,25000000) as id;
INSERT 0 15000001

postgres=# select pg_size_pretty(pg_relation_size('test'));
 pg_size_pretty 
----------------
 1244 MB
(1 row)

查看对应文件

[postgres@training 14187]$ ls -lh 16405*
-rw------- 1 postgres postgres 1.0G Feb 19 10:58 16405
-rw------- 1 postgres postgres 221M Feb 19 10:57 16405.1
-rw------- 1 postgres postgres 336K Feb 19 10:57 16405_fsm

postgres=# select oid,relfilenode from pg_class where relname='test';
  oid  | relfilenode 
-------+-------------
 16405 |       16405
(1 row)

表和索引都是通过oid来管理,而oid是通过relfilenode去管理,默认oid和relfilenode一致。如果超过1GB,第二文件将会以relfilenode.编号[从1开始]

清空表

postgres=# truncate table test;
TRUNCATE TABLE

postgres=# select oid,relfilenode from pg_class where relname='test';
  oid  | relfilenode 
-------+-------------
 16405 |       16411
(1 row)

查看对应文件

[postgres@training 14187]$ ls -lh 16405*
-rw------- 1 postgres postgres 0 Feb 19 11:04 16405
[postgres@training 14187]$ ls -lh 16411*
-rw------- 1 postgres postgres 0 Feb 19 11:04 16411

**思考:16405 16411文件大小为0,16405文件还有用吗?

插入数据

postgres=# insert into test select id,id||'dagedaged' from generate_series(1,1000000) as id;
INSERT 0 1000000

postgres=# select oid,relfilenode from pg_class where relname='test';
  oid  | relfilenode 
-------+-------------
 16405 |       16411
(1 row)

查看对应文件

[postgres@training 14187]$ ls -lh 16405*
ls: cannot access 16405*: No such file or directory

[postgres@training 14187]$ ls -lh 16411*
-rw------- 1 postgres postgres 50M Feb 19 11:08 16411
-rw------- 1 postgres postgres 32K Feb 19 11:08 16411_fsm

如果对表做truncate操作,relfilenode也将发生相应的改变,同时,原有的relfilenode在重新对表插入数据后将被丢弃。

默认的表和索引的大小可以通过 –with-segsize调整

四、 表空间布局

表空间:存储数据库的一个逻辑空间

创建数据库时可以指定数据库对象的表空间,如果不指定则使用默认的表空间

postgres=# \db
          List of tablespaces
    Name    |  Owner   |    Location    
------------+----------+----------------
 pg_default | postgres | 
 pg_global  | postgres |

pg_global:global目录,保存系统表

pg_default:base目录,template0和template1数据库默认的表空间

未指定表空间的数据库

test_db=# \c mydb
You are now connected to database "mydb" as user "postgres".

mydb=# create table test1(id int,name varchar);
CREATE TABLE

mydb=# \d
         List of relations
 Schema | Name  | Type  |  Owner   
--------+-------+-------+----------
 public | test1 | table | postgres
(1 row)

mydb=# select pg_relation_filepath('test1');
 pg_relation_filepath 
----------------------
 base/16393/16420
(1 row)

指定表空间的数据库

postgres=# \c test_db
You are now connected to database "test_db" as user "postgres".

test_db=# create table test1(id int,name varchar);
CREATE TABLE

test_db=# \d
         List of relations
 Schema | Name  | Type  |  Owner   
--------+-------+-------+----------
 public | test1 | table | postgres
(1 row)

test_db=# select oid,datname from pg_database where datname='test_db';
  oid  | datname 
-------+---------
 16403 | test_db
(1 row)

test_db=# select pg_relation_filepath('test1');
            pg_relation_filepath             
---------------------------------------------
 pg_tblspc/16402/PG_12_201909212/16403/16414
(1 row)

[postgres@training 14187]$ cd $PGDATA/pg_tblspc

[postgres@training pg_tblspc]$ ll
total 0
lrwxrwxrwx 1 postgres postgres 14 Feb 19 00:13 16402 -> /data/tbs_test

表空间可以放在$PGDATA目录下,也可以放在$PGDATA目录外,对于表空间的管理,都是通过oid来管理,为了方便管理,postgresql将所有$PGDATA内部或者外部的表空间都放在pg_tblspc目录下,实际上该目录下存放的就是一个表空间的软链接。

五、 堆表文件的内部结构

pd_lsn:该页中最近变更wal记录的标识

pd_checksum:页面的校验和

pd_flags:标记位

pd_lower:空闲空间的起始位置

pd_upper:空闲空间的结束位置

pd_special:特殊空间的起始位置

pd_pagesize_version:页面大小及页面的版本信息

pd_prune_xid:可以修改的最早的元组的xid

PostgreSQL体系结构--物理结构_体系结构

六、 元组的读写方式

如何写入一个堆元组?

表由页构成,假设页面只有一个元组,页面中的第一个linep指向第一个元组,pd_lower指向第一个linep,pd_upper指向第一个元组

PostgreSQL体系结构--物理结构_物理结构_02

读取数据(扫描块)

顺序扫描:

PostgreSQL体系结构--物理结构_体系结构_03

索引扫描(B-Tree)

PostgreSQL体系结构--物理结构_体系结构_04

postgres=# select ctid,id,name from test where id=5;
 ctid  | id |    name    
-------+----+------------
 (0,5) |  5 | 5dagedaged
(1 row)

ctid:格式(blockid,itemid),表示数据记录的物理行当信息,指的是一条记录位于哪个数据块的哪个位移上面。

好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695