Postgresql体系架构
Posted 呆呆的私房菜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Postgresql体系架构相关的知识,希望对你有一定的参考价值。
Postgresql体系架构
简单理解:
PG实例:内存 + 进程
存储结构:物理存储 + 逻辑存储
内存结构
共享内存
PG启动后,会生成一块共享内存,共享内存主要用作数据块的缓冲区,以便提高读写性能。WAL日志缓冲区和CLOG(Commit log)缓冲区也存在于共享内存中。除此之外,一些全局信息也保存在共享内存中,如进程信息、锁信息、全局统计信息等。
本地内存
后台进程除了访问共享内存外,还会申请分配一些本地内存,以便暂存一些不需要全局存储的数据,这些内存缓冲区主要有:
临时缓冲区:用于访问临时表的本地缓冲区;
Work_mem:内部排序操作和hash表在使用临时磁盘文件之前使用的内存缓冲区;
Maintenance_work_mem:在维护性操作(如VACUUM、CREATE INDEX和ALTER TABLE ADD FOREIGN KEY等)中使用的内存缓冲区。
进程结构
Postmaster
客户端发起连接,PG会启动一个服务进程为这个连接服务。当某个服务进程出现异常,Postmaster主进程会自动完成系统的恢复,恢复过程中会停掉所有的服务进程,然后进行数据一致性恢复,恢复完成之后才开始接收新的连接。
SysLogger
SysLogger进程通过从postmaster进程、所有的服务进程及其他辅助进程收集所有的stderr输出,并将这些输出写入到日志文件中。
BgWriter
BgWriter辅助进程是把共享内存中的脏页写入磁盘上的进程。
WalWriter
WAL就是Write Ahead Log的缩写,中文称为预写式日志,是负责写入Wal日志的进程。概念就是在修改数据之前,必须将这些修改操作记录到磁盘中,后面更新实际数据时,就不需要实时的将数据持久化到文件中了。
WAL日志保存在pg_wal下,每个文件默认是16MB。
PgArch
由于Wal日志会被循环使用,PgArch归档进程会把覆盖前的WAL日志备份出来。
AutoVacuum
在PG中,对表进行delete操作后,旧的数据并不会立即被删除。并且,在更新数据时,也不会在旧的数据上做更新,而是生成一行新的数据。旧的数据只是被表示为删除状态,只有在没有并发的其他事务读到这些旧数据时,它们就会被AutoVacuum进程清除。
PgStat
PgStat辅助进程用来做数据的统计收集工作。收集的信息主要用于查询优化时的代价估算,这些信息包括在一个表和索引上进行了多少次的插入、更新、删除操作,磁盘块读写的次数以及行的读次数。系统表pg_statistic中存储了PgStat收集的各类统计信息。
物理存储
数据文件
物理存储结构是操作系统中组织和管理数据库的方式。主要包括数据文件、日志文件、参数文件、控制文件、WAL文件。
执行initdb的时候会初始化一个目录,在这个目录会生成相关的子目录和一些文件。PG的表空间概念不同于其他关系型数据库,这里的tablespace对应的都是一个目录。下图是对每个目录的功能和作用的介绍。
数据文件用于存储数据。文件名以OID命名,对于超出1G的表数据文件,PostgreSQL会自动将其拆分为多个文件来存储,而拆分的文件名将由pg_class中的relfilenode字段来决定。
下面展示一些内联代码片
。
select oid,relname,relkind,relfilenode from pg_class where relname ='testtable1';
在PostgreSQL中,将保存在磁盘中的块(Block)称为Page。数据的读写是以Page为最小单位,每个Page默认的大小是8K。在编译PostgreSQL时指定BLCKSZ大小将决定Page的大小。每个表文件由逗哥BLCKSZ字节大小的Page组成。在分析型数据库中,适当增加BLCKSZ大小可以小幅度提升数据库的性能。
日志文件
运行日志文件
默认没有开启,开启后会自动生成。这个日志一般是记录服务器与DB的状态,比如各种Error信息,定位慢查询SQL,数据库的启动关闭信息,发生checkpoint过于频繁等的告警信息,诸如此类。该日志有.csv格式和.log。建议使用.csv格式,因为它一般会按大小和时间自动切割。pg_log是可以被清理删除,压缩打包或者转移,同时并不影响DB的正常运行。当我们有遇到DB无法启动或者更改参数没有生效时,第一个想到的就是查看这个日志。
重做日志文件
pg_xlog 这个日志是记录的Postgresql的WAL信息,默认存储在目录$PGDATA/pg_wal/,是一些事务日志信息(transaction log)。默认单个大小是16M,源码安装的时候可以更改其大小(./configure --with-wal-segsize=target_value 参数,即可设置)这些日志会在定时回滚恢复(PITR), 流复制(Replication Stream)以及归档时能被用到,这些日志是非常重要的,记录着数据库发生的各种事务信息,不得随意删除或者移动这类日志文件,不然你的数据库会有无法恢复的风险。
事务日志文件
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可以用特定的操作系统用户和指定的数据库用户登录数据库。
控制文件
控制文件记录了数据库运行的一些信息,比如数据库id,是否open,wal的位置,checkpoint的位置等等。controlfile是很重要的文件。
ls $PG_DATA/global/pg_control
bin/pg_controldata $PG_DATA/
WAL文件
默认保存在$PGDATA/pg_wal目录下。文件名称为16进制的24个字符组成,每8个字符一组,每组的意义如下:
00000001 00000000 00000001
时间线 逻辑ID 物理ID
-- 手动切换WAL
select pg_switch_wal();
逻辑存储
逻辑存储结构是内部的组织和管理数据的方式。
所有的数据库对象都有各自的object identifiers,oid是一个无符号的四字节整数,相关对象的oid都存放在相关的system catalog表中,比如数据库的oid和表的oid分别存放在pg_database和pg_class表中。
Databases cluster
数据库集群簇,它是指向单个PG服务器实例管理的数据库集合,组合数据库集群的这些数据库使用相同的全局配置文件和监听端口,共用进程和内存结构。
一个Database cluster可以包含多个database、多个user以及databases中的所有对象。
Database
在PG中,数据库本身也是数据库对象,并且在逻辑上彼此分离,出数据库之外的其他数据库对象(例如表、索引等)都属于它们各自的数据库。
Database object
如:表、视图、索引、序列、函数等等。在PostgreSQL中的所有数据库对象都由各自的对象标识符(OID)进行内部的管理。数据库的OID存储在pg_database系统表中,数据库对象的OID存储在pg_class系统表中。
select oid,datname from pg_database;
select oid,relname,relkind,relfilenode from pg_class where relname ='testtable1';
Tablespace
数据库在逻辑上分为多个存储单元,称为表空间。表空间的作用把逻辑上相关的结构放在一起。数据库逻辑上是一个或多个表空间组成。初始化的时候,会自动创建pg_default和pg_global两个表空间。
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、Funcation等数据库对象。
Segment
一个段是分配给一个逻辑结构(一个表、一个索引或其他对象)的一组区,是数据库对象使用的空间的集合;段可以有表段、索引段、回滚段、临时段和高速缓存段等。
Extent
区是数据库存储空间分配的一个逻辑单位,它由连续数据块所组成。第一个段是由一个或多个盘区组成。当一段中间所有空间已完全使用,PostgreSQL为该段分配一个新的范围。
Block
数据块是PostgreSQL 管理数据文件中存储空间的单位,为数据库使用的I/O的最小单位,是最小的逻辑部件。默认值8K。
PostgreSQL学习总结(10)—— PostgreSQL 数据库体系架构
PG 架构图
进程说明
进程 | 说明 |
Postmaster 主进程 | 是整个数据库实例的总控进程,负责启动和关闭该数据库实例 |
Potgres (常驻进程) | 管理后端的常驻进程,也称为“postmaster”。其默认监测UNIXDomain Socket和TCP/IP(Windows等,一部分的平台只监测TCP/IP)的5432端口,等待来自前端的的连接处理。监测的端口号可以在PostgreSql的设置文件postgresql.conf中修改。 |
Postgres(子进程) | 子进程根据pg_hba.conf定义的安全策略来判断是否允许进行连接,根据策略,会拒绝某些特定的IP及网络,或者也可以只允许某些特定的用户或者对某些数据库进行连接。 Postgres会接受前端过来的查询,然后对数据库进行检索,最后把结果返回,有时也会对数据库进行更新。更新的数据同时还会记录在事务日志里面(PostgreSQL称为WAL日志),这个主要是当停电的时候,服务器宕机,重新启动的时候进行恢复处理的时候使用的。另外,把日志归档保存起来,可在需要进行恢复的时候使用。在PostgreSQL 9.0以后,通过把WAL日志传送其他的PostgreSQL,可以实时地进行数据库复制,这就是所谓的“数据库复制”功能。 |
PgArch进程 (归档) | WAL日志会被循环使用,PgArch在归档前会把WAL日志备份出来。通过PITR(Point in Time Recovery)技术,可以对数据库进行一次全量备份后,该技术将备份时间点之后的WAL日志通过归档进行备份,使用数据库的全量备份再加上后面产生的WAL日志,即可把数据库向前推到全量备份后的任意一个时间点。 |
PgStat进程 (统计数据收集) | 做数据的统计收集工作。主要用于查询优化时的代价估算,包括一个表和索引进行了多少次的插入、更新、删除操作,磁盘块读写的次数、行的读次数。pg_statistic中存储了PgStat收集的各类信息。 |
AutoVacuum进程 (自动清理) | 在PostgreSQL数据库中,对表进行DELETE操作后,旧的数据并不会立即被删除,并且,在更新数据时,也并不会在旧的数据上做更新,而是新生成一行数据。旧的数据只是被标识为删除状态,只有在没有并发的其他事务读到这些旧数据时,它们才会被清除。这个清除工作就由AutoVacuum进程完成。 |
BgWriter进程 (后台) | 页写到磁盘上的进程。主要是为了提高插入、更新和删除数据的性能。 |
Wal Writer进程 (预写式日志) | WAL(Write Ahead Log,预写式日志),在修改数据之前把修改操作记录到磁盘中,以便后面更新实时数据时就不需要数据持久化到文件中。 |
CheckPoint进程 (检查点) | 检查点是系统设置的事务序列点,设置检查点保证检查点前的日志信息刷到磁盘中。 |
Syslogger进程 (系统日志) | 将错误信息写到log日志中,需要在Postgres.conf中logging_collection设置为on,此时主进程才会启动Syslogger辅助进程。 |
postgresql 的物理架构非常简单,它由共享内存、一系列后台进程和数据文件组成。
Shared Memory
共享内存是服务器服务器为数据库缓存和事务日志缓存预留的内存缓存空间。其中最重要的组成部分是Shared Buffer和WAL Buffer。
- Shared Buffer:是数据页缓冲区。Shared Buffer的目的是减少磁盘IO,大部分oltp工作负载都是随机IO,因此从磁盘获取非常慢。为了解决这个问题,postgre将数据缓存在RAM中,来提高性能。对于shared_buffers,没有一个特定的推荐值。但是一般来说,对于专用DB服务器,shared_buffers的值应该大约是系统总RAM的25%。
- WAL Buffer:是预写日志(wal)缓冲区。在备份和恢复的场景下,WAL Buffer和WAL文件是极其重要的。如果要调优的系统有大量并发连接,那么wal_buffers的值越高,性能越好。
PostgreSQL 进程类型
PostgreSQL有四种进程类型
- Postmaster (Daemon) Process(主后台驻留进程)
- Background Process(后台进程)
- Backend Process(后端进程)
- Client Process(客户端进程)
- Postmaster Process:PostgreSQL启动时第一个启动的进程。启动时,他会执行恢复、初始化共享内存的运行后台进程操作。运行期间,当有客户端发起链接请求时,它还负责创建后端进程。
如果通过 pstree 命令查看进程之间的关系,你会发现 Postmaster 进程是其他所有进程的父进程。
Background Process
PgArch进程 (归档) | WAL日志会被循环使用,PgArch在归档前会把WAL日志备份出来。通过PITR(Point in Time Recovery)技术,可以对数据库进行一次全量备份后,该技术将备份时间点之后的WAL日志通过归档进行备份,使用数据库的全量备份再加上后面产生的WAL日志,即可把数据库向前推到全量备份后的任意一个时间点。 |
PgStat进程 (统计数据收集) | 做数据的统计收集工作。主要用于查询优化时的代价估算,包括一个表和索引进行了多少次的插入、更新、删除操作,磁盘块读写的次数、行的读次数。pg_statistic中存储了PgStat收集的各类信息。 |
AutoVacuum进程 (自动清理) | 在PostgreSQL数据库中,对表进行DELETE操作后,旧的数据并不会立即被删除,并且,在更新数据时,也并不会在旧的数据上做更新,而是新生成一行数据。旧的数据只是被标识为删除状态,只有在没有并发的其他事务读到这些旧数据时,它们才会被清除。这个清除工作就由AutoVacuum进程完成。 |
BgWriter进程 (后台) | 页写到磁盘上的进程。主要是为了提高插入、更新和删除数据的性能。 |
Wal Writer进程 (预写式日志) | WAL(Write Ahead Log,预写式日志),在修改数据之前把修改操作记录到磁盘中,以便后面更新实时数据时就不需要数据持久化到文件中。 |
CheckPoint进程 (检查点) | 检查点是系统设置的事务序列点,设置检查点保证检查点前的日志信息刷到磁盘中。 |
Syslogger进程 (系统日志) | 需要在Postgres.conf中logging_collection设置为on,此时主进程才会启动Syslogger辅助进程。 |
最大后台链接数通过 max_connections参数设定,默认值为 100。后端进程用于处理前端用户请求并返回结果。查询运行时需要一些内存结构,就是所谓的本地内存(local memory)。本地内存涉及的主要参数有:
work_mem:用于排序、位图索引、哈希链接和合并链接操作。默认值为 4MB。
maintenance_work_mem:用于 vacuum 和创建索引操作。默认值为 64MB。
temp_buffers:用于临时表。默认值为 8MB。
Client Process
客户端进程需要和后端进程配合使用,处理每一个客户链接。通常情况下,Postmaster进程会派生一个子进程用来处理用户连接。
数据库结构
数据库相关概念:
- PostgreSQL由一系列数据库组成。一套PostgreSQL程序称之为一个数据库群集。
- 当initdb()命令执行后,template0 , template1 , 和postgres数据库被创建。
- template0和template1数据库是创建用户数据库时使用的模版数据库,他们包含系统元数据表。
- initdb()刚完成后,template0和template1数据库中的表是一样的。但是template1数据库可以根据用户需要创建对象。
- 用户数据库是通过克隆template1数据库来创建的;
表空间相关概念:
- initdb()后马上创建pg_default和pg_global表空间。
- 建表时如果没有指定特定的表空间,表默认被存在pg_default表空间中。
- 用于管理整个数据库集群的表默认被存储在pg_global表空间中。
- pg_default表空间的物理位置为$PGDATA\\base目录。
- pg_global表空间的物理位置为$PGDATA\\global目录。
- 一个表空间可以被多个数据库同时使用。此时,每一个数据库都会在表空间路径下创建为一个新的子路径。
- 创建一个用户表空间会在$PGDATA\\pg_tblspc目录下面创建一个软连接,连接到表空间制定的目录位置。
表相关概念:
- 每个表有三个数据文件。
- 一个文件用于存储数据,文件名是表的OID。
- 一个文件用于管理表的空闲空间,文件名是OID_fsm。
- 一个文件用于管理表的块是否可见,文件名是OID_vm。
- 索引没有_vm文件,只有OID和OID_fsm两个文件
以上是关于Postgresql体系架构的主要内容,如果未能解决你的问题,请参考以下文章
PostgreSQL学习总结(10)—— PostgreSQL 数据库体系架构
PostgreSQL学习总结(10)—— PostgreSQL 数据库体系架构