PHP实战中知识总结 / PgSQL - 存储结构

一、逻辑结构

如图,postgresql逻辑结构层级划分:databse cluster --> database --> schema --> table(index) --> segments --> pages --> tuples。

(1)segment:数据文件会被切割成多个segmemts, 默认1G;

(2)page(block):每个segment内部都会被划分成多个pages,默认8k,page是IO操作的最小单位;

(3)tuple:每行记录叫tuple,每个tuple对应一个tid(tuple identififiers);

(4)relation:table、index、sequence, view, function等叫relation;

(5)oid:object identififiers (OIDs),每个relation都是通过对应的oid进行管理;

(6)relfifilenode:一般情况 relfifilenode = oid,用于管理具体的数据文件;

PostgreSQL 中的所有数据库对象都由各自的对象标识符 (OID) 内部管理,它们是无符号的 4 字节整数。 根据对象的类型,数据库对象和相应 OID 之间的关系存储在适当的系统目录中。 例如,数据库和堆表的OID分别存储在pg_database和pg_class中。

// 查看database cluster,不同的db之间的数据是不能访问的
postgres=# \l
                 List of databases
  Name  | Owner  | Encoding |  Collate  |  Ctype  |  Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
postgres | postgres | UTF8   | zh_CN.UTF-8 | zh_CN.UTF-8 |
template0 | postgres | UTF8   | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/postgres     +
      |     |     |       |       | postgres=CTc/postgres
template1 | postgres | UTF8   | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/postgres     +
      |     |     |       |       | postgres=CTc/postgres
test   | postgres | UTF8   | zh_CN.UTF-8 | zh_CN.UTF-8 |
(4 rows)
// 查看schemas,同一个db下的不同schema的数据是可以访问的
postgres=# \dn
  List of schemas
  Name  | Owner
----------+----------
myschema | postgres
public  | postgres
(2 rows)
postgres=# \d
         List of relations
Schema |    Name    |  Type  | Owner
--------+--------------------+----------+----------
public | alerts       | table  | postgres
public | alerts_id_seq   | sequence | postgres
public | goods       | table  | postgres
public | pg_stat_statements | view   | postgres
public | products      | table  | postgres
public | test        | table  | postgres
(6 rows)
// 每个tuple都有一个tid,表示第0个page的第1行
postgres=\# select ctid, name, age from t001;
ctid | name | age
-------+-----------+-----
(0,1) | damon0668 | 1
(0,2) | damon0669 | 2
// 查看database的oid
postgres=# select oid, datname from pg_database where datname = 'test';
 oid | datname
-------+---------
16411 | test
(1 row)
// 查看table的oid和relfilenode,一般情况 oid = relfilenode
postgres=# select oid, relfilenode, relname from pg_class where relname = 'test';
 oid | relfilenode | relname
-------+-------------+---------
16384 |    16550 | test
(1 row)
// truncate之后,oid不变,relfilenode变了,此时oid != relfilenode
postgres=# TRUNCATE test;
TRUNCATE TABLE
postgres=# select oid, relfilenode, relname from pg_class where relname = 'test';
 oid | relfilenode | relname
-------+-------------+---------
16384 |    16720 | test
(1 row)

二、物理结构

[root@izwz91quxhnlkan8kjak5hz postgres]# tree -L 2
.
├── base
│  ├── 1            // 数据库oid
│  │  ├── 112         // 数据文件,对应表的relfilenode
│  │  ├── 113
│  │  ├── 113.1        // 被截取的数据文件段
│  │  ├── 1247
│  │  ├── 1247_fsm       // free space map,记录每一个page的空闲空间
│  │  ├── 1247_vm       // 可见性映射表,显示占用的tuple,扫描的时候会跳过这些tuple
│  ├── 13579
│  ├── 13580
│  ├── 16411
│  └── pgsql_tmp        // 临时文件存储目录
├── global
│  ├── 1213
│  ├── 1213_fsm
│  ├── 1213_vm
│  ├── 1214
│  ├── 1214_fsm
│  ├── 1214_vm
│  ├── 1232
│  ├── pg_control        // 用于存储全局控制信息
│  ├── pg_filenode.map      // pg_class里relfilenode为0的系统表,OID与文件的硬编码映射
│  └── pg_internal.init     // 系统表的cache文件,用于加快读取。默认不存在,查询系统表后自动产生
├── pg_commit_ts         // 该目录包含已提交事务的时间
├── pg_dynshmem          // 该目录包含动态共享内存子系统使用的文件
├── pg_hba.conf          // 客户端认证控制文件
├── pg_ident.conf         // 用来配置哪些操作系统用户可以映射为哪个数据库用户
├── pg_logical          // 逻辑复制的状态数据的目录
│  ├── mappings
│  ├── replorigin_checkpoint
│  └── snapshots
├── pg_multixact         // 存储多事务状态数据的子目录(用户共享的行锁)
│  ├── members
│  └── offsets
├── pg_notify           // 包含LISTEN/NOTIFY状态数据的目录
├── pg_replslot          // 该目录包含了复制槽的数据
├── pg_serial           // 已提交的可序列化事务信息的目录
├── pg_snapshots         // 储存导出的快照
├── pg_stat            // 统计信息的存储目录
├── pg_stat_tmp          // 统计信息的存储临时目录
│  ├── db_0.stat
│  ├── db_13580.stat
│  ├── db_16411.stat
│  ├── global.stat
│  └── pgss_query_texts.stat
├── pg_subtrans          // 存储子事务状态数据的目录
│  └── 0000
├── pg_tblspc           // 存储表空间的符号链接
├── pg_twophase          // 用于存储预备事务状态文件的目
├── PG_VERSION
├── pg_wal             // 保存预写日志的目录
│  ├── 000000010000000400000050
...

PHP实战中知识总结