searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享

PostgreSQL:物理结构

2022-06-21 07:34:11
246
0

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

 

文件和目录相关作用描述

 

files description
PG_VERSION 包含 postgresql 主版本号的文件
pg_hba.conf 控制 postgresql 客户端验证的文件
pg_ident.conf 控制 postgresql 用户名映射的文件<br/>配置操作系统用户和数据库服务器上的用户名的映射
postgresql.conf 配置参数文件
postgresql.auto.conf 用于存储在 ALTER SYSTEM(版本9.4或更高版本)中设置的配置参数的文件
postmaster.opts 记录服务器最后一次启动时使用的命令行参数
postmaster.pid 伴随数据库服务器一同启动,记录数据库服务器进程编号、PGDATA、端口等信息的文件
subdirectories description
base/ 包含每个数据库子目录的子目录
global/ 包含群集范围的表的子目录,例如 pg_database、pg_control
pg_commit_ts/ (Version 9.5 or later) 包含事务提交时间戳数据的子目录。
pg_clog/ (Version 9.6 or earlier) \| pg_xact/ (Version 10 or later) 包含事务提交状态数据的子目录。
pg_dynshmem/ (Version 9.4 or later) 包含动态共享内存子系统使用的文件的子目录。
pg_logical/ (Version 9.4 or later) 包含逻辑复制的状态数据的子目录。
pg_multixact/ 包含多事务状态数据的子目录(用于 shared row locks)
pg_notify/ 包含 LISTEN / NOTIFY 状态数据的子目录
pg_repslot/ (Version 9.4 or later) 包含复制槽数据的子目录
pg_serial/ (Version 9.1 or later) 包含已提交的可序列化事务信息的子目录
pg_snapshots/ (Version 9.2 or later) 包含导出的快照的子目录。 PostgreSQL 的 函数 pg_export_snapshot 在此子目录中创建快照信息文件
pg_stat/ 包含用于统计子系统永久文件的子目录
pg_stat_tmp/ 包含用于统计子系统临时文件的子目录
pg_subtrans/ 包含子事物状态数据的子目录
pg_tblspc/ 包含指向表空间的符号链接的子目录
pg_twophase/ 包含 prepare 事务状态文件的子目录
pg_xlog/ (Version 9.6 or earlier) \ | pg_wal/ (Version 10 or later) 包含预写日志

database 的物理布局设计

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[postgres@node1 base]$ pwd
/data/pg_data/base
[postgres@node1 base]$ ll
total 36
drwx------ 2 postgres postgres 8192 Apr 30 06:29 1(template 数据库)
drwx------ 2 postgres postgres 8192 Apr 30 06:29 13592
drwx------ 2 postgres postgres 8192 Apr 30 06:29 13593
# 其它:16384 开始
  
[postgres@node1 pg_data]$ psql -U postgres -d postgres
psql: error: could not connect to server: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
[postgres@node1 pg_data]$ pg_ctl -D /data/pg_data/ start -l /tmp/logfile
waiting for server to start.... done
server started
[postgres@node1 pg_data]$ psql -U postgres -d postgres
psql (12.2)
Type "help" for help.
  
postgres=# select datname,oid from pg_database;
  datname  |  oid  
-----------+-------
 postgres  | 13593
 template1 |     1
 template0 | 13592
(3 rows)
  
postgres=#
  • OID:所有数据库对象都由各自的对象标识符(OID)进行内部管理,它们是无符号的 4 字节整数。数据库的 OID 存储在 pg_database 系统表中,可以通过如下代码查询数据库的 OID:

    1
    2
    3
    SELECT oid, database
      FROM pg_database
     WHERE datname = 'mydb'
  • 表空间:在 PostgreSQL 中最大的逻辑存储单位是表空间。初始化数据库目录时会自动创建 pg_default 和 pg_global 两个表空间。

    1
    2
    3
    4
    5
    6
    postgres=# \d
            List of relations
     Schema Name | Type  |  Owner   
    --------+------+-------+----------
     public | a    | table | postgres
    (1 row)
    • pg_global:物理文件位置在数据目录的 global 目录中,它用来保存系统表。

    • pg_default:物理文件位置在数据目录中的 base 目录中,是 template0 和 template1 数据库的默认表空间。

表和索引的物理布局设计

每个表和索引如果不超过 1G 大小,都用一个文件存储,新创建的表文件以表的OID命名,对于超出的文件,会自动将其切分为多个文件,用 OID.\<顺序号\> 来命名。另外还有一个 relfilenode,这个值不会总是匹配 OID,在发生 truncate、reindex、cluster 等相关的操作时,会发生变化。见如下示例:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
postgres=# create table a(id int);
CREATE TABLE
postgres=# SELECT relname, oid, relfilenode FROM pg_class WHERE relname = 'a';
 relname |  oid  | relfilenode 
---------+-------+-------------
 a       | 16385 |       16385
(1 row)
  
postgres=# truncate table a;
TRUNCATE TABLE
postgres=# SELECT relname, oid, relfilenode FROM pg_class WHERE relname = 'a';
 relname |  oid  | relfilenode 
---------+-------+-------------
 a       | 16385 |       16388
(1 row)
  
postgres=# SELECT pg_relation_filepath('a');
 pg_relation_filepath 
----------------------
 base/14187/16388
(1 row)
  
postgres=#

如果数据数据文件超过1GB,那么就会新生成一个文件,如下:

1
2
3
ls -la -h base/14187/16388*
-rw------- 1 postgres postgres 1.0G  Apr  21 11:16 base/14187/16388
-rw------- 1 postgres postgres  45M  Apr  21 11:20 base/14187/16388.1

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

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31490526/viewspace-2716802/,如需转载,请注明出处,否则将追究法律责任。

0条评论
0 / 1000
我是小朋友
80文章数
5粉丝数
我是小朋友
80 文章 | 5 粉丝

PostgreSQL:物理结构

2022-06-21 07:34:11
246
0

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

 

文件和目录相关作用描述

 

files description
PG_VERSION 包含 postgresql 主版本号的文件
pg_hba.conf 控制 postgresql 客户端验证的文件
pg_ident.conf 控制 postgresql 用户名映射的文件<br/>配置操作系统用户和数据库服务器上的用户名的映射
postgresql.conf 配置参数文件
postgresql.auto.conf 用于存储在 ALTER SYSTEM(版本9.4或更高版本)中设置的配置参数的文件
postmaster.opts 记录服务器最后一次启动时使用的命令行参数
postmaster.pid 伴随数据库服务器一同启动,记录数据库服务器进程编号、PGDATA、端口等信息的文件
subdirectories description
base/ 包含每个数据库子目录的子目录
global/ 包含群集范围的表的子目录,例如 pg_database、pg_control
pg_commit_ts/ (Version 9.5 or later) 包含事务提交时间戳数据的子目录。
pg_clog/ (Version 9.6 or earlier) \| pg_xact/ (Version 10 or later) 包含事务提交状态数据的子目录。
pg_dynshmem/ (Version 9.4 or later) 包含动态共享内存子系统使用的文件的子目录。
pg_logical/ (Version 9.4 or later) 包含逻辑复制的状态数据的子目录。
pg_multixact/ 包含多事务状态数据的子目录(用于 shared row locks)
pg_notify/ 包含 LISTEN / NOTIFY 状态数据的子目录
pg_repslot/ (Version 9.4 or later) 包含复制槽数据的子目录
pg_serial/ (Version 9.1 or later) 包含已提交的可序列化事务信息的子目录
pg_snapshots/ (Version 9.2 or later) 包含导出的快照的子目录。 PostgreSQL 的 函数 pg_export_snapshot 在此子目录中创建快照信息文件
pg_stat/ 包含用于统计子系统永久文件的子目录
pg_stat_tmp/ 包含用于统计子系统临时文件的子目录
pg_subtrans/ 包含子事物状态数据的子目录
pg_tblspc/ 包含指向表空间的符号链接的子目录
pg_twophase/ 包含 prepare 事务状态文件的子目录
pg_xlog/ (Version 9.6 or earlier) \ | pg_wal/ (Version 10 or later) 包含预写日志

database 的物理布局设计

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[postgres@node1 base]$ pwd
/data/pg_data/base
[postgres@node1 base]$ ll
total 36
drwx------ 2 postgres postgres 8192 Apr 30 06:29 1(template 数据库)
drwx------ 2 postgres postgres 8192 Apr 30 06:29 13592
drwx------ 2 postgres postgres 8192 Apr 30 06:29 13593
# 其它:16384 开始
  
[postgres@node1 pg_data]$ psql -U postgres -d postgres
psql: error: could not connect to server: could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
[postgres@node1 pg_data]$ pg_ctl -D /data/pg_data/ start -l /tmp/logfile
waiting for server to start.... done
server started
[postgres@node1 pg_data]$ psql -U postgres -d postgres
psql (12.2)
Type "help" for help.
  
postgres=# select datname,oid from pg_database;
  datname  |  oid  
-----------+-------
 postgres  | 13593
 template1 |     1
 template0 | 13592
(3 rows)
  
postgres=#
  • OID:所有数据库对象都由各自的对象标识符(OID)进行内部管理,它们是无符号的 4 字节整数。数据库的 OID 存储在 pg_database 系统表中,可以通过如下代码查询数据库的 OID:

    1
    2
    3
    SELECT oid, database
      FROM pg_database
     WHERE datname = 'mydb'
  • 表空间:在 PostgreSQL 中最大的逻辑存储单位是表空间。初始化数据库目录时会自动创建 pg_default 和 pg_global 两个表空间。

    1
    2
    3
    4
    5
    6
    postgres=# \d
            List of relations
     Schema Name | Type  |  Owner   
    --------+------+-------+----------
     public | a    | table | postgres
    (1 row)
    • pg_global:物理文件位置在数据目录的 global 目录中,它用来保存系统表。

    • pg_default:物理文件位置在数据目录中的 base 目录中,是 template0 和 template1 数据库的默认表空间。

表和索引的物理布局设计

每个表和索引如果不超过 1G 大小,都用一个文件存储,新创建的表文件以表的OID命名,对于超出的文件,会自动将其切分为多个文件,用 OID.\<顺序号\> 来命名。另外还有一个 relfilenode,这个值不会总是匹配 OID,在发生 truncate、reindex、cluster 等相关的操作时,会发生变化。见如下示例:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
postgres=# create table a(id int);
CREATE TABLE
postgres=# SELECT relname, oid, relfilenode FROM pg_class WHERE relname = 'a';
 relname |  oid  | relfilenode 
---------+-------+-------------
 a       | 16385 |       16385
(1 row)
  
postgres=# truncate table a;
TRUNCATE TABLE
postgres=# SELECT relname, oid, relfilenode FROM pg_class WHERE relname = 'a';
 relname |  oid  | relfilenode 
---------+-------+-------------
 a       | 16385 |       16388
(1 row)
  
postgres=# SELECT pg_relation_filepath('a');
 pg_relation_filepath 
----------------------
 base/14187/16388
(1 row)
  
postgres=#

如果数据数据文件超过1GB,那么就会新生成一个文件,如下:

1
2
3
ls -la -h base/14187/16388*
-rw------- 1 postgres postgres 1.0G  Apr  21 11:16 base/14187/16388
-rw------- 1 postgres postgres  45M  Apr  21 11:20 base/14187/16388.1

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

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31490526/viewspace-2716802/,如需转载,请注明出处,否则将追究法律责任。

文章来自个人专栏
云知识的搬运工
224 文章 | 7 订阅
0条评论
0 / 1000
请输入你的评论
0
0