PostgreSQL数据库体系架构

2022-07-14 14:33:02 浏览数 (1)

一 PostgreSQL进程结构

1 进程结构图谱和分类

PostgreSQL数据库的进程可以分为三类:后台进程、后端进程或叫服务器进程、客户端进程或用户进程。

a 后台进程:

代码语言:javascript复制
[postgres@Centos ~]$ id
uid=1002(postgres) gid=1002(postgres) groups=1002(postgres) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[postgres@Centos ~]$ ps -ef|grep postgres
root      18605  17328  0 15:48 pts/0    00:00:00 su postgres
postgres  18606  18605  0 15:48 pts/0    00:00:00 bash
root      18690  18606  0 15:51 pts/0    00:00:00 su - postgres
postgres  18710  18690  0 15:52 pts/0    00:00:00 -bash
postgres  18783      1  0 15:54 ?        00:00:00 /data/postgres/13.2/bin/postgres -D /data/postgres/13.2/data
postgres  18785  18783  0 15:54 ?        00:00:00 postgres: checkpointer 
postgres  18786  18783  0 15:54 ?        00:00:00 postgres: background writer 
postgres  18787  18783  0 15:54 ?        00:00:00 postgres: walwriter 
postgres  18788  18783  0 15:54 ?        00:00:00 postgres: autovacuum launcher 
postgres  18789  18783  0 15:54 ?        00:00:00 postgres: stats collector 
postgres  18790  18783  0 15:54 ?        00:00:00 postgres: logical replication launcher 
postgres  19523  18710  0 16:54 pts/0    00:00:00 ps -ef
postgres  19524  18710  0 16:54 pts/0    00:00:00 grep --color=auto postgres
[postgres@Centos ~]$ pstree -p 18783
postgres(18783)─┬─postgres(18785)
                ├─postgres(18786)
                ├─postgres(18787)
                ├─postgres(18788)
                ├─postgres(18789)
                └─postgres(18790)
[postgres@Centos ~]$ 

其中,/data/postgres/13.2/bin/postgres是数据库服务器的master进程,其它诸如checkpoint,background writer,walwrite,autovacuum launcher,stats collector,logical replication launcher都是由它fork的子进程。当然,数据库运行模式不同,配置不同,也可能有其它后台进程,如归档进程等。

postgres:PostgreSQL数据库的核心进程,也是整个cluster的父进程,该进程出现问题,整个cluster就over了。该进程由操作系统的守护进程1号进程派生。Linux下的1号进程是整个服务器的守护进程,类比于Java程序中的Object类,一切类的父类。

checkpointer:检查点进程,等价于Oracle的CKPT进程,负责完成数据库的检查点,通知数据库的写进程DBWR将内存中的脏数据写出到磁盘。

background writer :等价于Oracle的DBWR进程,负责将内存中的脏数据写出到磁盘。

walwriter :等价于Oracle的LGWR进程,负责将日志缓冲区中的记录关于数据库的修改的日志写出到日志文件中去,确保数据的修改不会丢失,用于恢复使用。

autovacuum launcher:自动清理工作进程。由于PostgreSQL不像Oracle那样有undo的机制,将数据被修改前的信息写入到undo,然后修改数据。PostgreSQL采取的是在原数据块上进行保留旧的数据,并作标记,等到将来修改提交生效之后,旧的数据(dead tuple翻译为死元组)不需要的话,就得清理,由该进程来完成。

stats collector:统计信息收集进程。用于及时的更新数据库中的统计信息,如表、index有多少条记录,数据分布等,给优化器提供最新的信息,便于优化器选择最优的执行计划。避免统计信息不准确,导致优化器选择错误的执行计划,导致SQL性能下降或偏差。

logical replication launcher:逻辑复制进程。用于完成逻辑复制的工作。

archiver:归档进程,等价于Oracle的ARCH进程,用于完成数据库日志文件的归档。当数据库配置了归档模式之后,可以看到该进程。

b 后端进程(backend)或服务器进程:

当我们的应用程序和图形界面的客户端工具,连接到PostgreSQL数据库服务器时。

master进程会为该应用程序创建1个服务器进程,用于处理和响应该客户端应用程序的请求。

代码语言:javascript复制
[postgres@Centos ~]$ psql
psql (13.2)
Type "help" for help.
​
postgres=# select pg_backend_pid();
 pg_backend_pid 
----------------
          19843
(1 row)
​
postgres=# ! ps -ef|grep postgres
root      18605  17328  0 15:48 pts/0    00:00:00 su postgres
postgres  18606  18605  0 15:48 pts/0    00:00:00 bash
root      18690  18606  0 15:51 pts/0    00:00:00 su - postgres
postgres  18710  18690  0 15:52 pts/0    00:00:00 -bash
postgres  18783      1  0 15:54 ?        00:00:00 /data/postgres/13.2/bin/postgres -D /data/postgres/13.2/data
postgres  18785  18783  0 15:54 ?        00:00:00 postgres: checkpointer 
postgres  18786  18783  0 15:54 ?        00:00:00 postgres: background writer 
postgres  18787  18783  0 15:54 ?        00:00:00 postgres: walwriter 
postgres  18788  18783  0 15:54 ?        00:00:00 postgres: autovacuum launcher 
postgres  18789  18783  0 15:54 ?        00:00:00 postgres: stats collector 
postgres  18790  18783  0 15:54 ?        00:00:00 postgres: logical replication launcher 
postgres  19842  18710  0 17:21 pts/0    00:00:00 psql
postgres  19843  18783  0 17:21 ?        00:00:00 postgres: postgres postgres [local] idle
postgres  19885  19842  0 17:25 pts/0    00:00:00 sh -c ps -ef|grep postgres
postgres  19886  19885  0 17:25 pts/0    00:00:00 ps -ef
postgres  19887  19885  0 17:25 pts/0    00:00:00 grep postgres
postgres=# 

如上,可以看到服务器进程号是19843,通过select pg_backend_pid()查询。同时,看到服务器上该进程的父进程是18783,由/data/postgres/13.2/bin/postgres这个主进程派生。

后端进程或服务器进程的数量由max_connections参数决定。

每一个后端进程一次只能访问一个数据库。它和客户端进程进行TCP通信,开户端断开之后,该进程自动回收消失。客户端重新连接或发起新连接时重新创建新的后端进程。

由于进程的创建或回收,比较消耗操作系统的资源,因此,多数情况下,应用系统都会通过连接池的方式和数据库建立连接。

从PostgreSQL官方给后端进程的命名可以看到还是一脉相承的,比如,我们查看当前会话所在的后端进程号或者叫服务器进程的时候,我们调用的是pg_backend_pid()函数,杀会话所在进程时,调用的是pg_terminate_backend(),或者pg_cancel_backend()。

代码语言:javascript复制
[postgres@Centos ~]$ psql
psql (13.2)
Type "help" for help.
​
postgres=# select pg_backend_pid();
 pg_backend_pid 
----------------
          19911
(1 row)
​
postgres=# select pg_terminate_backend(19911);
FATAL:  terminating connection due to administrator command
server closed the connection unexpectedly
    This probably means the server terminated abnormally
    before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
postgres=# c
You are now connected to database "postgres" as user "postgres".
postgres=# 
​

c 用户进程或客户端进程:

指的是连接数据库服务器的应用程序或者客户端工具等。 d 用户进程连接示意图

每个用户进程或者客户端进程对应一个服务端进程。

2 数据库服务器启动流程

当我们通过pg_ctl工具来启动PostgreSQL数据库时,先在操作系统上创建1个master进程,然后该进程派生出一系列的后台进程,同时该进程监听$PGDATA/postgresql.conf配置文件中指定的端口。并且,向操作系统申请内存,用于数据库的正常运行操作,处理客户端的连接请求操作处理。最后,数据库可以正常对外提供服务。

代码语言:javascript复制
[postgres@Centos ~]$ netstat -anp|grep 5432
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      18783/postgres      
tcp6       0      0 :::5432                 :::*                    LISTEN      18783/postgres      
unix  2      [ ACC ]     STREAM     LISTENING     66350    18783/postgres       /tmp/.s.PGSQL.5432
[postgres@Centos ~]$ 
​

$PGDATA/postgresql.conf配置文件中指定的端口是5432, listen_address=*

3 进程结构小结

PostgreSQL数据库服务器的进程结构,类似于Oracle数据库的进程结构:守护进程,后台进程,服务器进程,用户进程等。

二 PostgreSQL内存结构

1内存结构图谱

2内存结构分类

内存结构分为共享内存、本地内存。类似于Oracle的SGA和PGA。

a共享内存

是指数据库服务器向操作系统申请的共享内存段,如数据共享缓冲区、日志缓冲区、事务提交日志内存区等,提供给PostgreSQL服务器的所有进程使用。

数据共享缓冲区:PostgreSQL把要操作和处理的表、index,读入到内存中,放到该区域缓存。类似于Oracle的database buffer cache。其大小由shared_buffers参数决定。

日志缓冲区:用于缓存数据库中对数据修改的日志记录,如:update table test set id=1这条SQL语句,数据库会把这个操作的信息记录在该内存区,将来写出到日志文件中,如果配置为归档模式,则最终写出到归档日志文件中去,用于恢复使用。其大小由wal_buffers参数决定。类似于Oracle的log buffer。

提交日志缓冲区:该内存区域有别于wal buffer日志缓冲区。它用于记录数据库中所有事务的提交状态,事务是否已经提交,是否已经终止,是否进行中,子事务等状态信息。用于MVCC。

b本地内存

当我们和数据库建立一个连接请求时,数据库帮我们创建1个后端进程。并给该后端进程分配的内存区域,该内存区域只属于这一个后端进程使用,可以认为是私有的。用于处理和响应我们向数据库发起的请求操作。通常包含:工作区work mem、维护工作区、临时缓冲区。

工作区:该内存区用于处理客户端SQL语句请求的order by排序、distinct过滤、表合并连接merge-join、哈希连接hash-join操作等。由work_mem参数决定大小。

维护工作区:该内存区域用于处理重建索引reindex、vacuum空间回收操作、给表添加外键约束等。由maintenance_work_mem参数决定大小。

临时缓冲区:该内存区用于创建和访问临时表时,存放临时表的数据。该内存区和因为SQL中因为大表排序或hash table而在服务器上建立的临时文件(位于pgsql_tmp路径下)没有直接关系。由temp_buffers参数决定大小。

三 PostgreSQL数据库的存储结构

1 PostgreSQL逻辑存储结构

a 什么是PostgreSQL cluster

当我们在一台服务器上安装部署并且初始化一个PostgreSQL数据库之后,严格的讲,其实是我们安装部署了一套PostgreSQL数据库软件,然后初始化了一个PostgreSQL的database cluster。这里的cluster是什么概念呢?

首先,这里的cluster完全是个逻辑上的概念,它是指一系列的数据库的集合。它所包含的数据库就是指,当我们以pg_ctl -D /data/postgres/13.2/data start来启动数据库cluster时,由这个-D参数指定,或者是PGDATA环境变量指定的路径下的所有的数据库的集合。当然,这么说太抽象了,其实,从物理上,我们可以这么说明和解释:

代码语言:javascript复制
[postgres@Centos ~]$ env|grep PGDATA
PGDATA=/data/postgres/13.2/data
[postgres@Centos ~]$ ll /data/postgres/13.2/data/base/
total 48
drwx------. 2 postgres postgres 8192 Dec 29 20:41 1
drwx------. 2 postgres postgres 8192 Dec 29 20:41 13579
drwx------. 2 postgres postgres 8192 Jan  5 16:29 13580
drwx------. 2 postgres postgres 8192 Jan  5 15:54 16389
​
[postgres@Centos ~]$ oid2name
All databases:
    Oid  Database Name  Tablespace
----------------------------------
  13580       postgres  pg_default
  13579      template0  pg_default
      1      template1  pg_default
  16389         testdb  pg_default
[postgres@Centos ~]$ psql
psql (13.2)
Type "help" for help.
​
postgres=# l
                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
----------- ---------- ---------- ------------- ------------- -----------------------
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres           
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres           
           |          |          |             |             | postgres=CTc/postgres
 testdb    | t_user   | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
(4 rows)
​
postgres=# select oid,datname from pg_database ;
  oid  |  datname  
------- -----------
 13580 | postgres
 16389 | testdb
     1 | template1
 13579 | template0
(4 rows)
​
postgres=# 
​
​
  • 我们的PGDATA=/data/postgres/13.2/data,就是说,我们这个PostgreSQL cluster下的所有数据库都在这个路径下;
  • 查看/data/postgres/13.2/data/base/,可以看到一系列的数字命名的文件,其实它们就是这个PostgreSQL cluster所包含的所有的数据库;这些数字化的文件名,其实就是数据库的oid(object identifier),相当于数据库的编号,这个是PostgreSQL数据库本身自有的特性;
  • 执行oid2name,可以看到数据库名和oid之间的对应关系;
  • 进入psql,也可以通过l命令列出当前PostgreSQL cluster下的所有的数据库集合;
  • 从pg_database字典表中,也可以查询到当前PostgreSQL cluster下的所有的数据库集合的信息;

因此,我们说PostgreSQL cluster它是一个逻辑概念,它包含了一个或多个PostgreSQL数据库。一个数据库只能属于一个cluster。补充,这里的cluster跟Oracle Real Application Cluster里的cluster完全不挨着,是两个完全不同的概念。

b database和cluster的关系

数据库是指一些列数据库对象的集合,比如表,index,view,function等这些数据库对象隶属于一个特定的数据库。

cluster指的是一些列数据库的集合。比如:一个cluster初始化之后,包含3个默认数据库:postgres,默认的管理数据库;template0,默认的不可修改的空数据库;template1,默认的模板数据库,当我们创建数据库时,会参照该数据库来创建。

当我们在template1模板数据库中创建和安装1个数据库插件extension,uuid之后,再去创建新的数据库,那么新数据库中就会自动包含该uuid这个extension。

1个cluster可以包含多个数据库,反过来1个database只能隶属于1个cluster。

c 数据库实例和cluster的关系

我们定义数据库实例是指一堆PostgreSQL的后台进程和内存结构,cluster指的是我们在初始化数据库时,指定的PGDATA环境变量指向的操作系统上的那个路径下的一堆的文件。

一个数据库实例在其一个生命周期内(从启动到关闭)只能“挂载”一个数据库cluster,反之,一个cluster也只能被一个实例挂载访问。二者之间是严格的一对一关系。

但是,在一台服务器上,我们可以安装一套PostgreSQL数据库软件,用这个数据库软件可以创建多个实例和多个cluster。每个实例对应于一个cluster。只要每个cluster所指定的监听端口不同,我们就可以同时运行多个实例和cluster。

如:我们可以在这套环境上再初始化一个实例和cluster,将其指向另外一个监听端口即可

创建和初始化一个新的cluster,让其指向/data/postgres/13.2/newdata

代码语言:javascript复制
/data/postgres/13.2/bin/initdb -D /data/postgres/13.2/newdata

修改/data/postgres/13.2/newdata/postgresql.conf 中的port = 5433 ,然后就可以启动一个新的实例和cluster。启动时,显示指定新的PGDATA=/data/postgres/13.2/newdata/即可。

代码语言:javascript复制
pg_ctl start -D /data/postgres/13.2/newdata/
ps -ef|grep postgres
netstat -anp|grep postgres
​
关闭实例
pg_ctl stop -m fast -D /data/postgres/13.2/newdata/

d PostgreSQL的tablespace

  • 定义:tablespace依然是一个逻辑概念,它是隶属于cluster的。
  • 查看:通过pg_tablespace字典表来查看cluster下表空间的信息,或者是db命令也可查看表空间的信息;
代码语言:javascript复制
postgres=# db 
                                  List of tablespaces
    Name    |  Owner   | Location | Access privileges | Options |  Size  | Description 
------------ ---------- ---------- ------------------- --------- -------- -------------
 pg_default | postgres |          |                   |         | 31 MB  | 
 pg_global  | postgres |          |                   |         | 559 kB | 
(2 rows)
​
postgres=# select oid,datname from pg_database ;
  oid  |  datname  
------- -----------
 13580 | postgres
 16389 | testdb
     1 | template1
 13579 | template0
(4 rows)
​
postgres=# 
​
​
  • 默认表空间:每个cluster默认情况下有2个表空间,分别命名为pg_default用于存放各个数据库私有的数据库对象,pg_global用于存放cluster全局共享的数据库对象信息,例如:cluster中数据库本身的信息,表空间的信息,数据库订阅信息,数据库复制信息,数据库认证授权信息、控制文件等。
  • 专用表空间:pg_global表空间是专表空间专用的,只能存放全局共享的数据库对象,不能存放用户数据,否则报错:

pg_default,表空间,默认存放cluster下所有数据库的所有数据库对象。这一点儿上,倒是有点儿类似于Oracle数据库的专表空间专用。

  • 表空间和数据库的关系:一个表空间可以给多个数据库使用,一个数据库里的不同数据库对象也可以存放在不同的表空间下。表空间和数据库的关系,不严格的讲,可以说是多对多的关系。不像Oracle数据库中,一个数据库可以包含多个表空间,且每个表空间只能属于一个数据库使用。
  • 如何创建表空间:OS上路径需提前创建,postgres用户得有读写操作系统文件系统权限,数据库管理员权限
代码语言:javascript复制
[postgres@Centos ~]$ pwd
/home/postgres
[postgres@Centos ~]$ ll
total 26912
drwxrwxr-x. 6 postgres postgres     4096 Dec 29 20:54 postgresql-13.2
-rw-r--r--. 1 postgres root     27548921 Dec 29 20:15 postgresql-13.2.tar.gz
-rw-------. 1 postgres postgres     3983 Jan  5 19:44 startup.log
[postgres@Centos ~]$ mkdir tbs_dir
[postgres@Centos ~]$ ll
total 26912
drwxrwxr-x. 6 postgres postgres     4096 Dec 29 20:54 postgresql-13.2
-rw-r--r--. 1 postgres root     27548921 Dec 29 20:15 postgresql-13.2.tar.gz
-rw-------. 1 postgres postgres     3983 Jan  5 19:44 startup.log
drwxrwxr-x. 2 postgres postgres        6 Jan  5 20:10 tbs_dir
[postgres@Centos ~]$ psql
psql (13.2)
Type "help" for help.

postgres=# create tablespace newtbs location '/home/postgres/tbs_dir';
CREATE TABLESPACE
postgres=# db 
                                         List of tablespaces
    Name    |  Owner   |        Location        | Access privileges | Options |  Size   | Description 
------------ ---------- ------------------------ ------------------- --------- --------- -------------
 newtbs     | postgres | /home/postgres/tbs_dir |                   |         | 0 bytes | 
 pg_default | postgres |                        |                   |         | 31 MB   | 
 pg_global  | postgres |                        |                   |         | 559 kB  | 
(3 rows)

postgres=# select oid,spcname from pg_tablespace;
  oid  |  spcname   
------- ------------
  1663 | pg_default
  1664 | pg_global
 16399 | newtbs
(3 rows)

postgres用户,在家目录下创建了一个tbs_dir,保证postgres用户对该路径的读写权限,以postgres用户访问postgres数据库(即以数据库管理员身份访问系统数据库,关于数据库的更多使用,后面再讲)。查看到,目前数据库内部自带两个默认表空间pg_default和pg_global。通过create tablespace newtbs location ‘/home/postgres/tbs_dir’;创建名为newtbs的表空间,存储在/home/postgres/tbs_dir路径下,见名知意,直观易懂。

  • 如何使用表空间:由于表空间和数据库是不严格的多对多的关系,所以,我们可以在创建数据库的时候,指定数据库的表空间存储信息,也可以在创建数据库对象时,指定其存储的所在表空间。

创建数据库对象时,显示指定表空间信息,如create table test_tbs(id int) tablespace newtbs ;

代码语言:javascript复制
postgres=# c
You are now connected to database "postgres" as user "postgres".
postgres=# create table test_tbs(id int) tablespace newtbs ;
CREATE TABLE
postgres=#  d test_tbs
              Table "public.test_tbs"
 Column |  Type   | Collation | Nullable | Default 
-------- --------- ----------- ---------- ---------
 id     | integer |           |          | 
Tablespace: "newtbs"
​
​

创建数据库时,指定其存储所在的表空间信息:

代码语言:javascript复制
postgres=# create database newdb tablespace newtbs;
CREATE DATABASE
​

当然,数据库创建之后,或者数据库对象(表、index等)创建之后,也可以分别通过alter database/table/index来修改表空间信息。

2 PostgreSQL物理存储结构

a cluster的物理结构图谱 b cluster在文件系统上的结构

代码语言:javascript复制
[postgres@Centos ~]$ echo $PGDATA
/data/postgres/13.2/data
[postgres@Centos ~]$ ll /data/postgres/13.2/data/
total 60
drwx------. 6 postgres postgres    54 Dec 30 17:49 base
drwx------. 2 postgres postgres  4096 Jan  5 19:45 global
drwx------. 2 postgres postgres     6 Dec 29 20:41 pg_commit_ts
drwx------. 2 postgres postgres     6 Dec 29 20:41 pg_dynshmem
-rw-------. 1 postgres postgres  4760 Dec 29 20:41 pg_hba.conf
-rw-------. 1 postgres postgres  1636 Dec 29 20:41 pg_ident.conf
drwx------. 4 postgres postgres    68 Jan  5 20:29 pg_logical
drwx------. 4 postgres postgres    36 Dec 29 20:41 pg_multixact
drwx------. 2 postgres postgres     6 Dec 29 20:41 pg_notify
drwx------. 2 postgres postgres     6 Dec 29 20:41 pg_replslot
drwx------. 2 postgres postgres     6 Dec 29 20:41 pg_serial
drwx------. 2 postgres postgres     6 Dec 29 20:41 pg_snapshots
drwx------. 2 postgres postgres     6 Jan  5 19:44 pg_stat
drwx------. 2 postgres postgres    84 Jan  5 20:31 pg_stat_tmp
drwx------. 2 postgres postgres    18 Dec 29 20:41 pg_subtrans
drwx------. 2 postgres postgres    19 Jan  5 20:23 pg_tblspc
drwx------. 2 postgres postgres     6 Dec 29 20:41 pg_twophase
-rw-------. 1 postgres postgres     3 Dec 29 20:41 PG_VERSION
drwx------. 3 postgres postgres    60 Dec 29 20:41 pg_wal
drwx------. 2 postgres postgres    18 Dec 29 20:41 pg_xact
-rw-------. 1 postgres postgres    88 Dec 29 20:41 postgresql.auto.conf
-rw-------. 1 postgres postgres 27982 Dec 29 21:56 postgresql.conf
-rw-------. 1 postgres postgres    65 Jan  5 19:44 postmaster.opts
-rw-------. 1 postgres postgres    83 Jan  5 19:44 postmaster.pid
[postgres@Centos ~]$ cd /data/postgres/13.2/data/
[postgres@Centos data]$ ll base/
total 48
drwx------. 2 postgres postgres 8192 Dec 29 20:41 1
drwx------. 2 postgres postgres 8192 Dec 29 20:41 13579
drwx------. 2 postgres postgres 8192 Jan  5 19:44 13580
drwx------. 2 postgres postgres 8192 Jan  5 19:45 16389
[postgres@Centos data]$ oid2name 
All databases:
    Oid  Database Name  Tablespace
----------------------------------
  16403          newdb      newtbs
  13580       postgres  pg_default
  13579      template0  pg_default
      1      template1  pg_default
  16389         testdb  pg_default
[postgres@Centos data]$ ll /home/postgres/tbs_dir/
total 0
drwx------. 4 postgres postgres 32 Jan  5 20:29 PG_13_202007201
[postgres@Centos data]$ ll /home/postgres/tbs_dir/PG_13_202007201/
total 12
drwx------. 2 postgres postgres   19 Jan  5 20:25 13580
drwx------. 2 postgres postgres 8192 Jan  5 20:29 16403
​

$PGDATA/base:用于存放当前cluster下所有的数据库,数字化命名的路径表示各个数据库,每个数字表示数据库的oid。最重要!oid2name列出的16401这个newdb数据库不在$PGDATA/base路径下,而在/home/postgres/tbs_dir/PG_13_202007201/的原因是,前面我们新建这个数据库的时候,将其存储指定为newtbs下。我们只需执行alter database newdb tablespace pg_default;就可以将其从newtbs表空间迁移至pg_default表空间下。进而,其物理上也将自动从/home/postgres/tbs_dir/PG_13_202007201/迁移至$PGDATA/base路径:

代码语言:javascript复制
[postgres@Centos data]$ psql 
psql (13.2)
Type "help" for help.
​
postgres=# alter database newdb tablespace pg_default;
ALTER DATABASE
postgres=# q
[postgres@Centos data]$ ll /home/postgres/tbs_dir/PG_13_202007201/
total 0
drwx------. 2 postgres postgres 19 Jan  5 20:25 13580
[postgres@Centos data]$ oid2name
All databases:
    Oid  Database Name  Tablespace
----------------------------------
  16403          newdb  pg_default
  13580       postgres  pg_default
  13579      template0  pg_default
      1      template1  pg_default
  16389         testdb  pg_default
[postgres@Centos data]$ ll base/
total 60
drwx------. 2 postgres postgres 8192 Dec 29 20:41 1
drwx------. 2 postgres postgres 8192 Dec 29 20:41 13579
drwx------. 2 postgres postgres 8192 Jan  5 19:44 13580
drwx------. 2 postgres postgres 8192 Jan  5 19:45 16389
drwx------. 2 postgres postgres 8192 Jan  5 20:44 16403
​

global:用于存放cluster级别共享的全局表,如pg_database,pg_tablespace表,其文件命名依旧采用oid的数字化格式。

我们可以从数据库中验证这些cluster级别的共享系统表的oid和global下的数字文件名匹配:

关于文件名中类似如1213_fsm、1213_vm的文件,表示空闲空间映射文件(free space map),可见性映射文件(visibility map)。后面单独讲解。

pg_commit_ts:事务提交时间戳信息;commit timestamp;

pg_dynshmem:共享内存使用的文件信息;dynamic shared memory;

pg_hba.conf:关于客户端如何访问数据库的配置文件(会单独拎出来讲解);比较重要;host based authentication;

pg_ident.conf:关于外部用户(操作系统用户)和数据库内部用户的映射配置文件,比较少用;ident;

pg_logical:数据库逻辑解码的状态数据;

pg_multixact:存放多事务状态数据,共享锁信息;multi transaction;

pg_notify:数据库配置订阅模式的LISTEN/NOTIFY状态数据;

pg_replslot:数据库复制槽信息;replication slot;

pg_serial:已提交的串行化事务信息;serializable;

pg_snapshots:导出的快照信息,内置pg_export_snapshot()函数导出;

pg_stat:统计子系统收集的统计信息;statistics;

pg_stat_tmp:统计子系统收集的临时统计信息;statistics temporary;

pg_subtrans:子事务的转态数据;sub-transactions;

pg_tblspc:表空间的映射,比较重要,实际存放的是软连接文件,创建表空间之后,会指向实际存放路径;如果没有额外创建表空间,则此路径为空。tablespace;

代码语言:javascript复制
[postgres@Centos data]$ ll pg_tblspc/
total 0
lrwxrwxrwx. 1 postgres postgres 22 Jan  5 20:23 16399 -> /home/postgres/tbs_dir

pg_twophase:两阶段提交事务的状态信息;

PG_VERSION:存放数据库版本信息;

pg_wal:存放数据库的日志文件,非常重要。类似于Oracle的redo log。write ahead log;

代码语言:javascript复制
[postgres@Centos data]$ ll pg_wal/
total 16384
-rw-------. 1 postgres postgres 16777216 Jan  5 20:49 000000010000000000000001
drwx------. 2 postgres postgres        6 Dec 29 20:41 archive_status
[postgres@Centos data]$ 
​

pg_xact:事务提交状态数据,用于控制事务的Multi Version Concurrent Contril;PostgreSQL事务有4种状态:IN_PROGRESS,COMMITED,ABORTED,SUB_COMMITTED;

postgresql.auto.conf:存放通过alter sytem命令修改的参数,不建议直接修改该文件;

postgresql.conf:数据库配置的参数文件,非常重要(后面单独拎出来讲)。类似于Oracle的参数文件spfile;

postmaster.opts:记录数据库启动时的选项,options;

代码语言:javascript复制
[postgres@Centos data]$ cat postmaster.opts
/data/postgres/13.2/bin/postgres "-D" "/data/postgres/13.2/data"

0 人点赞