PostgreSQL 是最像 Oracle 的开源数据库,咱们能够拿 Oracle 来比拟学习它的体系结构,比拟容易了解。PostgreSQL 的次要构造如下:
一、存储构造
PG 数据存储构造分为:逻辑存储构造和物理存储存储。其中:逻辑存储构造是外部的组织和治理数据的形式;物理存储构造是操作系统中组织和治理数据的形式。
1、逻辑存储构造
所有数据库对象都有各自的 oid(object identifiers),oid 是一个无符号的四字节整数,相干对象的 oid 都寄存在相干的 system catalog 表中,比方数据库的 oid 和表的 oid 别离寄存在 pg\_database,pg\_class 表中。
在逻辑存储构造中有几个术语须要解释:
- 数据库集群 -Database cluster
也叫数据库集簇。它是指有单个 PostgreSQL 服务器实例治理的数据库汇合,组成数据库集群的这些数据库应用雷同的全局配置文件和监听端口、共用过程和内存构造。一个 DataBase Cluster 能够包含:多个 DataBase、多个 User、以及 Database 中的所有对象。如上图所示。
- 数据库 -Database
在 PostgreSQL 中,数据库自身也是数据库对象,并且在逻辑上彼此拆散,除数据库之外的其余数据库对象(例如:表、索引等等)都属于他们各自的数据库。
- 表空间 -tablespace
数据库在逻辑上分成多个存储单元,称作表空间。表空间用作把逻辑上相干的构造放在一起。数据库逻辑上是由一个或多个表空间组成。初始化的时候,会主动创立 pg\_default 和 pg\_global 两个表空间。
\db
其中:pg_global:用于寄存零碎表。pg_default:该表空间的物理文件存储在数据目录中的 base 目录中。
创立本人的表空间,并在该表空间上创立表
create tablespace mydemotbs location '/home/postgres/training/pgsql/data/mydemotbs';
create table testtable1(tid int primary key,tname text) tablespace mydemotbs;
- 模式 -Schema
当创立一个数据库时,会为其创立一个名为 public 的默认 Schema。Schema 是数据库中的命名空间,在数据库中创立的所有对象都是在 Schema 中创立,一个用户能够从同一个客户端连贯中拜访不同的 Schema。而不同的 Schema 中能够有多个同名的 Table、Index、View、Sequence、Function 等等数据库对象。能够通过上面的形式来查看以后数据库的 Schema
\dn
- 段 -segment
一个段是调配给一个逻辑构造(一个表、一个索引或其余对象)的一组区,是数据库对象应用的空间的汇合;段能够有表段、索引段、回滚段、长期段和高速缓存段等。
- 区 -extent
区是数据库存储空间调配的一个逻辑单位,它由间断数据块所组成。第一个段是由一个或多个盘区组成。当一段两头所有空间已齐全应用,PostgreSQL 为该段调配一个新的范畴。
- 块 -block(Page)
数据块是 PostgreSQL 治理数据文件中存储空间的单位,为数据库应用的 I / O 的最小单位,是最小的逻辑部件。默认值 8K。
- 数据库对象 -Database object
如:表、视图、索引、序列、函数等等。在 PostgreSQL 中的所有数据库对象都由各自的对象标识符(OID)进行外部的治理。例如,数据库的 OID 存储在 pg_database 零碎表中,能够通过上面的语句进行查问。
select oid,datname from pg_database;
而数据库中的表、索引、序列等数据库对象的 OID 则存在了 pg_class 零碎表中,例如能够通过上面的语句查问后面创立的 testtable1 表的 OID。
select oid,relname,relkind,relfilenode from pg_class where relname ='testtable1';
2、物理存储构造
在执行 initdb 的时候会初始化一个目录,通常咱们都会在系统配置相干的环境变量 $PGDATA 来示意,初始化实现后,会再这个目录生成相干的子目录以及一些文件。在 postgresql 中,表空间的概念并不同于其余关系型数据库,这里一个 Tablespace 对应的都是一个目录。如下图就是 PG 的物理构造:
每个目录的性能与作用如下所示:
而 PostgreSQL 的物理存储构造次要是指硬盘上存储的文件,包含:数据文件、日志文件、参数文件、管制文件、redo 日志(WAL)。上面别离进行介绍。
- 数据文件(表文件)
顾名思义,数据文件用于存储数据。文件名以 OID 命名,对于超出 1G 的表数据文件,PostgreSQL 会主动将其拆分为多个文件来存储,而拆分的文件名将由 pg_class 中的 relfilenode 字段来决定。如下所示:
select oid,relname,relkind,relfilenode from pg_class where relname ='testtable1';
查看目录表空间 mydemotbs 的目录(其中:13578 是数据库 OID,16385 是表的 OID)
在 PostgreSQL 中,将保留在磁盘中的块(Block)称为 Page。数据的读写是以 Page 为最小单位,每个 Page 默认的大小是 8K。在编译 PostgreSQL 时指定 BLCKSZ 大小将决定 Page 的大小。每个表文件由逗哥 BLCKSZ 字节大小的 Page 组成。在剖析型数据库中,适当减少 BLCKSZ 大小能够小幅度晋升数据库的性能。
- 日志文件
PostgreSQL 日志文件的类型,分为以下几种:
① 运行日志(pg_log)
默认没有开启,开启后会主动生成。查看 postgresql.conf 文件的配置能够看到相干的参数设置。这个日志个别是记录服务器与 DB 的状态,比方各种 Error 信息,定位慢查问 SQL,数据库的启动敞开信息,产生 checkpoint 过于频繁等的告警信息,诸如此类。该日志有.csv 格局和.log。倡议应用.csv 格局,因为它个别会按大小和工夫主动切割。pg_log 是能够被清理删除,压缩打包或者转移,同时并不影响 DB 的失常运行。当咱们有遇到 DB 无奈启动或者更改参数没有失效时,第一个想到的就是查看这个日志。
② 重做日志(pg_xlog)
pg\_xlog 这个日志是记录的 Postgresql 的 WAL 信息,默认存储在目录 $PGDATA/pg\_wal/,是一些事务日志信息 (transaction log)。默认单个大小是 16M,源码装置的时候能够更改其大小(./configure --with-wal-segsize=target_value 参数,即可设置)这些日志会在定时回滚复原(PITR),流复制(Replication Stream) 以及归档时能被用到,这些日志是十分重要的,记录着数据库产生的各种事务信息,不得随便删除或者挪动这类日志文件,不然你的数据库会有无奈复原的危险。
③ 事务日志(pg_xact)
pg\_xact 是事务提交日志,记录了事务的元数据。默认开启。内容个别不能间接读。默认存储在目录 $PGDATA/pg\_xact/。
④ 服务器日志
如果用 pg_ctl 启动的时候没有指定 - l 参数来指定服务器日志,谬误可能会输入到 cmd 前台。服务器日志记录了数据库的重要信息。
- 参数文件
次要包含 postgresql.conf、pg\_hba.conf 和 pg\_ident.conf 这三个参数文件。上面别离进行介绍:
① postgresql.conf
PostgreSQL 的主要参数文件,有很具体的阐明和正文,和 Oracle 的 pfile,MySQL 的 my.cnf 相似。默认在 $PGDATA 下。很多参数批改后都须要重启。9.6 之后反对了 alter system 来批改,批改后的会存在 $PGDATA/postgresql.auto.conf 下,能够 reload 或者 restart 来使之失效。
② pg_hba.conf
这个是黑白名单的设置。文件里有具体的参数阐明,默认参数如下:
③ pg_ident.conf
pg\_ident.conf 是用户映射配置文件,用来配置哪些操作系统用户能够映射为数据库用户。联合 pg\_hba.conf 中,method 为 ident 能够用特定的操作系统用户和指定的数据库用户登录数据库。
- 管制文件
管制文件记录了数据库运行的一些信息,比方数据库 id,是否 open,wal 的地位,checkpoint 的地位等等。controlfile 是很重要的文件。
管制文件的地位:$PGDATA/global/pg\_control,能够应用命令 bin/pg\_controldata 查看管制文件的内容,如下:
-
redo 日志(WAL)
默认保留在 $PGDATA/pg_wal 目录下,如下所示:
文件名称为 16 进制的 24 个字符组成,每 8 个字符一组,每组的意义如下:00000001 00000000 00000001
工夫线 逻辑 ID 物理 ID
通过上面的语句进行 WAL 的手动切换:
select pg_switch_wal();
再次查看 pg_wal 目录,如下所示:
二、过程构造
执行上面的命令列出所有的 PostgreSQL 的过程。
ps -ef | grep postgres
① Postmaster 过程
主过程 Postmaster 是整个数据库实例的总管制过程,负责启动和敞开数据库实例。用户能够运行 postmaster,postgres 命令加上适合的参数启动数据库。实际上,postmaster 命令是一个指向 postgres 的链接,如下图所示。
更多时候咱们应用 pg\_ctl 启动数据库,pg\_ctl 也是通过运行 postgres 来启动数据库,它只是做了一些包装,让咱们更容易启动数据库,所以,主过程 Postmaster 理论是第一个 postgres 过程,此过程会 fork 一些与数据库实例相干的辅助子过程,并治理他们。
当用户与 PostgreSQL 数据库建设连贯时,实际上是先与 Postmaster 过程建设连贯。此时,客户端程序会收回身份证验证的音讯给 Postmaster 过程,Postmaster 主过程依据音讯中的信息进行客户端身份验证。如果验证通过,它会 fork 一个子过程 postgres 为这个连贯服务,fork 进去的过程被称为服务过程,查问 pg\_stat\_activity 表能够看到的 pid,就是这些服务过程的 pid。
select pid from pg_stat_activity;
② SysLogger 过程
在 postgresql.conf 里启用 运行日志(pg_log)后,会有 SysLogger 过程。SysLogger 会在日志文件达到指定的大小时敞开以后日志文件,产生新的日志文件。相干配置参数如下:
③ BgWriter 后盾写过程
BgWriter 是 PostgreSQL 中在后盾将脏页写出到磁盘的辅助过程,引入该过程次要为达到如下两个目标:首先,数据库在进行查询处理时若发现要读取的数据不在缓冲区中时要先从磁盘中读入要读取的数据所在的页面,此时如果缓冲区已满,则须要先抉择局部缓冲区中的页面替换进来。如果被替换的页面没有被批改过,那么能够间接抛弃;但如果要被替换的页已被批改,则必须先将这页写出到磁盘中后能力替换,这样数据库的查询处理就会被阻塞。通过应用 BgWriter 定期写出缓冲区中的局部脏页到磁盘中,为缓冲区腾出空间,就能够升高查询处理被阻塞的可能性。其次,PostgreSQL 在定期作检查点时须要把所有脏页写出到磁盘,通过 BgWriter 事后写出一些脏页,能够缩小设置检查点时要进行的 IO 操作,使零碎的 IO 负载趋势安稳。通过 BgWriter 对共享缓冲区写操作的对立治理,防止了其余服务过程在须要读入新的页面到共享缓冲区时,不得不将之前批改过的页面写出到磁盘的操作。
④ WalWriter 预写日志写过程
该过程用于保留 WAL 预写日志。预写式日志 WAL(Write Ahead Log,也称为 Xlog)的中心思想是对数据文件的批改必须是只能产生在这些批改曾经记录到日志之后,也就是先写日志后写数据。如果遵循这个过程,那么就不须要在每次事务提交的时候都把数据块刷回到磁盘,这一点与 Oracle 数据库是完全一致的。postgresql.conf 文件中与 WalWriter 过程相干的参数如下:
#------------------------------------------------------------------------------
# WRITE AHEAD LOG
#------------------------------------------------------------------------------
#wal_level = minimal # minimal, replica, or logical
# (change requires restart)
#fsync = on # flush data to disk for crash safety
# (turning this off can cause
# unrecoverable data corruption)
#synchronous_commit = on # synchronization level;
# off, local, remote_write, remote_apply, or on
#wal_sync_method = fsync # the default is the first option
# supported by the operating system:
# open_datasync
# fdatasync (default on Linux)
# fsync
# fsync_writethrough
# open_sync
#full_page_writes = on # recover from partial page writes
#wal_compression = off # enable compression of full-page writes
#wal_log_hints = off # also do full page writes of non-critical updates
# (change requires restart)
#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers
# (change requires restart)
#wal_writer_delay = 200ms # 1-10000 milliseconds
#wal_writer_flush_after = 1MB # measured in pages, 0 disables
#commit_delay = 0 # range 0-100000, in microseconds
#commit_siblings = 5 # range 1-1000
⑤ PgArch 归档过程
从 PostgreSQL 8.x 开始,有了 PITR(Point-In-Time-Recovery)技术,该技术支持将数据库复原到其运行历史中任意一个有记录的工夫点;PITR 的另一个重要的根底就是对 WAL 文件的归档性能。PgArch 辅助过程的指标就是对 WAL 日志在磁盘上的存储模式进行归档备份。但在默认状况下,PostgreSQL 是非归档模式,因而看不到 PgArch 过程。PgArch 过程通过 postgresql.conf 文件中的如下参数进行配置:
# - Archiving -
#archive_mode = off # enables archiving; off, on, or always
# (change requires restart)
#archive_command = '' # command to use to archive a logfile segment
# placeholders: %p = path of file to archive
# %f = file name only
# e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'
#archive_timeout = 0 # force a logfile segment switch after this
# number of seconds; 0 disables
⑥ AutoVacuum 主动清理过程
在 PG 数据库中,对数据进行 UPDATE 或者 DELETE 操作后,数据库不会立刻删除旧版本的数据,而是标记为删除状态。这是因为 PG 数据库具备多版本的机制,如果这些旧版本的数据正在被另外的事务关上,那么临时保留他们是很有必要的。当事务提交后,旧版本的数据曾经没有价值了,数据库须要清理垃圾数据腾出空间,而清理工作就是 AutoVacuum 过程进行的。postgresql.conf 文件中与 AutoVacuum 过程相干的参数有:
#------------------------------------------------------------------------------
# AUTOVACUUM
#------------------------------------------------------------------------------
#autovacuum = on # Enable autovacuum subprocess? 'on'
# requires track_counts to also be on.
#log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and
# their durations, > 0 logs only
# actions running at least this number
# of milliseconds.
#autovacuum_max_workers = 3 # max number of autovacuum subprocesses
# (change requires restart)
#autovacuum_naptime = 1min # time between autovacuum runs
#autovacuum_vacuum_threshold = 50 # min number of row updates before
# vacuum
#autovacuum_vacuum_insert_threshold = 1000 # min number of row inserts
# before vacuum; -1 disables insert
# vacuums
#autovacuum_analyze_threshold = 50 # min number of row updates before
# analyze
#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum
#autovacuum_vacuum_insert_scale_factor = 0.2 # fraction of inserts over table
# size before insert vacuum
#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze
#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum
# (change requires restart)
#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age
# before forced vacuum
# (change requires restart)
#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for
# autovacuum, in milliseconds;
# -1 means use vacuum_cost_delay
#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for
# autovacuum, -1 means use
# vacuum_cost_limit
⑦ PgStat 统计信息收集过程
PgStat 过程是 PostgreSQL 数据库的统计信息收集器,用来收集数据库运行期间的统计信息,如表的增删改次数,数据块的个数,索引的变动等等。收集统计信息次要是为了让优化器做出正确的判断,抉择最佳的执行打算。postgresql.conf 文件中与 PgStat 过程相干的参数,如下:
#------------------------------------------
# RUNTIME STATISTICS
#------------------------------------------
# - Query/Index Statistics Collector -
#track_activities = on
#track_counts = on
#track_io_timing = off
#track_functions = none # none, pl, all
#track_activity_query_size = 1024 # (change requires restart)
#stats_temp_directory = 'pg_stat_tmp'
⑧ CheckPoint 检查点过程
检查点是零碎设置的事务序列点,设置检查点保障检查点前的日志信息刷到磁盘中。postgresql.conf 文件中与之相干的参数有:
# - Checkpoints -
#checkpoint_timeout = 5min # range 30s-1d
#max_wal_size = 1GB
#min_wal_size = 80MB
#checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0
#checkpoint_flush_after = 256kB # measured in pages, 0 disables
#checkpoint_warning = 30s # 0 disables
三、内存构造
PostgreSQL 的内存构造,分为:本地内存和共享内存。它们的关系如下图所示:
① 本地内存:每个后端过程 (backend process) 本人应用的
② 共享内存:所有过程独特应用