胸怀万里世界, 放眼无限未来。这篇文章主要讲述赵强老师史上最详细的PostgreSQL体系架构介绍相关的知识,希望能为你提供帮助。
文章图片
PostgreSQL是最像Oracle的开源数据库,我们可以拿Oracle来比较学习它的体系结构,比较容易理解。PostgreSQL的主要结构如下:
文章图片
一、存储结构PG数据存储结构分为:逻辑存储结构和物理存储存储。其中:逻辑存储结构是内部的组织和管理数据的方式;物理存储结构是操作系统中组织和管理数据的方式。
1、逻辑存储结构
文章图片
所有数据库对象都有各自的oid(object identifiers),oid是一个无符号的四字节整数,相关对象的oid都存放在相关的system catalog表中,比如数据库的oid和表的oid分别存放在pg_database,pg_class表中。
在逻辑存储结构中有几个术语需要解释:
- 数据库集群-Database cluster
- 数据库-Database
- 表空间-tablespace
\\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
\\dn
文章图片
- 段-segment
- 区-extent
- 块-block(Page)
- 数据库对象-Database object
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)。下面分别进行介绍。
- 数据文件(表文件)
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大小可以小幅度提升数据库的性能。
- 日志文件
_① 运行日志(pglog)
默认没有开启,开启后会自动生成。查看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
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可以用特定的操作系统用户和指定的数据库用户登录数据库。
- 控制文件
控制文件的位置:$PGDATA/global/pg_control,可以使用命令bin/pg_controldata查看控制文件的内容,如下:
文章图片
- redo日志(WAL)
文章图片
文件名称为16进制的24个字符组成,每8个字符一组,每组的意义如下:
000000010000000000000001
时间线逻辑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会在日志文件达到指定的大小时关闭当前日志文件,产生新的日志文件。相关配置参数如下:
【赵强老师史上最详细的PostgreSQL体系架构介绍】
文章图片
③ 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)自己使用的
文章图片
② 共享内存:所有进程共同使用
文章图片
文章图片
推荐阅读
- 浅析 DDD 领域驱动设计
- 精品RestTemplate工具类及使用
- 百度短视频推荐系统的目标设计
- 你知道怎么修改pycharm编辑器嘛(简单的四步教你搞定界面风格修改)
- 职责链的应用
- 红帽Linux入门指南第五期(Linux文件权限管理)
- 性能环境之docker操作指南2(全网最全)
- pulsar bookies清理磁盘方法
- Java技术指南「难点-核心-遗漏」Java线程状态流转及生命周期的技术指南(知识点串烧)!