Postgresql管理系列-逻辑结构和物理结构

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dazuiba008/article/details/80363430

最近看到一本书,相对于官方文档,更加简洁易读一些,这里把一些重点整理成相关文章,以便更多人了解学习

1.数据库的逻辑结构

Database cluster: 由postgresql server管理的数据库的集合,下面由多个database组成

databsase: 由各种数据库对象构成,比如下图中的table,indexes, view,function,sequence...




所有数据库对象都有各自的oid(object identifiers),oid是一个无符号的四字节整数,相关对象的oid都存放在相关的system catalog表中,比如数据库的oid和表的oid分别存放在pg_database,pg_class表中。

如下所示:

sampledb=# SELECT datname, oid FROM pg_database WHERE datname = 'sampledb';
 datname  |  oid  
----------+-------
 sampledb | 16384
(1 row)

sampledb=# SELECT relname, oid FROM pg_class WHERE relname = 'sampletbl';
  relname  |  oid  
-----------+-------
 sampletbl | 18740 
(1 row)

2.数据库的物理结构

在执行initdb的时候会初始化一个目录,通常我们都会在系统配置相关的环境变量$PGDATA来表示,初始化完成后,会再这个目录生成相关的子目录以及一些文件。在postgresql中,tablespace的概念并不同于其他关系型数据库,这里一个tablespace对应的都是一个目录。如下图就是PG的物理结构


文件和目录相关作用描述

files description
PG_VERSION A file containing the major version number of PostgreSQL
pg_hba.conf A file to control PosgreSQL's client authentication
pg_ident.conf A file to control PostgreSQL's user name mapping
postgresql.conf A file to set configuration parameters
postgresql.auto.conf A file used for storing configuration parameters that are set in ALTER SYSTEM (version 9.4 or later)
postmaster.opts A file recording the command line options the server was last started with
subdirectories description
base/ Subdirectory containing per-database subdirectories.
global/ Subdirectory containing cluster-wide tables, such as pg_database and pg_control.
pg_commit_ts/ Subdirectory containing transaction commit timestamp data. Version 9.5 or later.
pg_clog/ (Version 9.6 or earlier) Subdirectory containing transaction commit state data. It is renamed to pg_xact in Version 10. CLOG will be described in Section 5.4.
pg_dynshmem/ Subdirectory containing files used by the dynamic shared memory subsystem. Version 9.4 or later.
pg_logical/ Subdirectory containing status data for logical decoding. Version 9.4 or later.
pg_multixact/ Subdirectory containing multitransaction status data (used for shared row locks)
pg_notify/ Subdirectory containing LISTEN/NOTIFY status data
pg_repslot/ Subdirectory containing replication slot data. Version 9.4 or later.
pg_serial/ Subdirectory containing information about committed serializable transactions (version 9.1 or later)
pg_snapshots/ Subdirectory containing exported snapshots (version 9.2 or later). The PostgreSQL's function pg_export_snapshot creates a snapshot information file in this subdirectory.
pg_stat/ Subdirectory containing permanent files for the statistics subsystem.
pg_stat_tmp/ Subdirectory containing temporary files for the statistics subsystem.
pg_subtrans/ Subdirectory containing subtransaction status data
pg_tblspc/ Subdirectory containing symbolic links to tablespaces
pg_twophase/ Subdirectory containing state files for prepared transactions
pg_wal/ (Version 10 or later) Subdirectory containing WAL (Write Ahead Logging) segment files. It is renamed from pg_xlog in Version 10.
pg_xact/ (Version 10 or later) Subdirectory containing transaction commit state data. It is renamed from pg_clog in Version 10. CLOG will be described in Section 5.4.
pg_xlog/ (Version 9.6 or earlier) Subdirectory containing WAL (Write Ahead Logging) segment files. It is renamed to pg_wal in Version 10.

2.1 database的物理布局设计

每个数据库都会在$PGDATA/base下面生成一个子目录,如下图,都会一一对应。

postgres@db-192-168-101-115-> pwd
/opt/pgdata9.6/pg_root/base
postgres@db-192-168-101-115-> ll
total 1.1M
drwx------ 2 postgres postgres 4.0K Aug 29  2017 1
drwx------ 2 postgres postgres 4.0K Aug 29  2017 13268
drwx------ 2 postgres postgres 976K May 14 11:36 13269
drwx------ 2 postgres postgres  12K May 14 11:36 137745
drwx------ 2 postgres postgres 4.0K Aug 29  2017 137915
drwx------ 2 postgres postgres  20K Aug 29  2017 137943
drwx------ 2 postgres postgres  16K Aug 29  2017 137945
drwx------ 2 postgres postgres  12K Aug 29  2017 137947
drwx------ 2 postgres postgres 4.0K Aug 29  2017 139298
drwx------ 2 postgres postgres  20K May 14 11:36 139312
drwx------ 2 postgres postgres  12K Aug 29  2017 17220
drwx------ 2 postgres postgres 4.0K Aug 29  2017 17289
drwx------ 2 postgres postgres 4.0K Aug 29  2017 177374
drwx------ 2 postgres postgres 4.0K Jul 10  2017 pgsql_tmp
hank=> select datname,oid from pg_database; 
  datname  |  oid   
-----------+--------
 postgres  |  13269
 template1 |      1
 template0 |  13268
 hank      |  16395
 rmt_db    |  17220
 loc_db    |  17289
 pgcluster | 137745
 swrd      | 137915
 scm       | 137943
 hive      | 137945
 oozie     | 137947
 sqoop     | 139298
 hue       | 139312
 zabbix    | 177374
(14 rows)

2.2 表和索引的物理布局设计

每一个表和索引如果不超过1G大小,都只有一个文件。表和索引也有和数据库一样的OID,另外还有一个relfilenode,这个值不会总是匹配OID,在发生一truncate,reindex,cluster等相关的操作,会发生变化,见如下示例:

可以看到开始oid和relfilenode是一样的,truncate后,relfilenode发生了变化.

hank=> SELECT relname, oid, relfilenode FROM pg_class WHERE relname = 'a';   
 relname |  oid   | relfilenode 
---------+--------+-------------
 a       | 186884 |      186884

 postgres@db-192-168-101-115-> ll -a /opt/pgdata9.6/pg_root/pg_tblspc/16393/PG_9.6_201608131/16395/186884
-rw------- 1 postgres postgres 1.5M Jan 16 17:11 /opt/pgdata9.6/pg_root/pg_tblspc/16393/PG_9.6_201608131/16395/186884


hank=> truncate table a;
TRUNCATE TABLE
hank=> SELECT relname, oid, relfilenode FROM pg_class WHERE relname = 'a';
 relname |  oid   | relfilenode 
---------+--------+-------------
 a       | 186884 |      187892
(1 row)

hank=> SELECT pg_relation_filepath('a');  
             pg_relation_filepath              
-----------------------------------------------
 pg_tblspc/16393/PG_9.6_201608131/16395/187892
如果数据数据文件超过1GB,那么就会新生成一个文件,如下:
 cd $PGDATA
$ ls -la -h base/16384/19427*
-rw------- 1 postgres postgres 1.0G  Apr  21 11:16 data/base/16384/19427
-rw------- 1 postgres postgres  45M  Apr  21 11:20 data/base/16384/19427.1

注意:表和索引的文件大小的限制可以在编译的时候通过--with-segsize设置

3.表空间物理结构

在PG中,除了base目录,自己新建的tablespace对应的目录都会再pg_tblspc下,如下图


比如新建一个tbs_hank表空间,目录是/data02/pgdata/tbs_hank
create tablespace tbs_hank owner postgres location '/data02/pgdata/tbs_hank'; 
那么就会再pg_tblspc下面有一个软连接的目录,这里16393就是这个tablespace的OID
postgres@db-192-168-101-115-> pwd
/opt/pgdata9.6/pg_root/pg_tblspc
postgres@db-192-168-101-115-> ll
total 0
lrwxrwxrwx 1 postgres postgres 23 Oct 10  2016 16393 -> /data02/pgdata/tbs_hank

再往下,就可以看到16395,是database的OID
postgres@db-192-168-101-115-> pwd
/opt/pgdata9.6/pg_root/pg_tblspc/16393/PG_9.6_201608131
postgres@db-192-168-101-115-> ls
16395  pgsql_tmp

4.堆表文件的内部结构

在表对应的datafile中,被分离为固定大小的page(or block),默认为8KB,这些page在datafile中从0开始计数,如果一个page被填充满,那么就会生成新的page以添加到文件,所以我们看到的datafile会随着表的增大,也在不断增大。

一个堆表数据文件的内部结构设计如下图:


一个表的page包括三种类型的数据

1.heap tuple: 存放数据本身,从一个page的末端有序的堆积。

2.line pointer: 一个四字节的行指针,指向每一个heap tuple,也叫item pointer,line pointer是一个简单的数组,索引page的数据文件是从1开始计数,也叫offset number,新的tuple增加到page时,line piniter就在推送到数组中,指向新的tuple.

3.header data:  header data是page生成的时候随之产生的,由pageHeaderData定义结构,24个字节长,包含了page的一般信息,主要结构描述如下:

           pd_lsn: 存储XLOG最后的改变的这个page的LSN号,是一个8字节的无符号整数,和WAL相关,后续章节会有描述

           pd_checksum:存储page的校验和

           pd_lower,pd_upper:  pd_lower指向line pointer的尾部,pd_upper指向最新heap tuple的开头

           pd_special: 此变量用于索引,在表的page中,它指向page的末尾(在索引的page中,它指向特殊空间的开头)

5.读写tuple的方法

5.1写head tuple

假设我们我们的表只有一个page,这个page里只有一个tuple,如下图,pd_lower指向line pointer尾部,pd_upper指向tuple1的头部,当tuple2插入后,2号line pointer指向tuple2的头部,pd_lower指向了2号line pointer的末尾,pd_upper指向了tuple2的头部,其他的数据(pg_lsn,pg_flags等等)也会适当的被重写。后面章节会详解


5.2 读heap tuple

两种典型的访问方法,顺序扫描和B-tree索引扫描

a. sequential  scan:表中的所有page中的所有tuple通过每个page中的所有line pointer依次读取

b. B-tree index can: 每个索引文件都包含index tuple,每个index tuple都是由索引键和一个指向目标heap tuple的point构成的TID所构成,如果索引的键值被找到,那么就从index tuple中获取TID的值去找想要的数据。如以下示例:通过索引的键值Queen,在index tuple中找到对应的TID(block=7,Offset=2),这里的意思就是第七个page的第二个tuple.因此PG不需要在page中进行没有必要的扫描。



























猜你喜欢

转载自blog.csdn.net/dazuiba008/article/details/80363430