PostgreSQL在开源关系型数据库市场是最早进的数据库。他的第一个版本在1989年发布,从那时开始,他获得了不少扩展。根据db-enginers上的排名状况,PostgreSQL目前在数据库领域排名第四。前端
本篇博客,咱们来讨论一下PostgreSQL的内部架构,以及各个组件之间如何交互。这将是本期PostgreSQL DBA系列博客的基石。node
PostgreSQL的物理架构很是简单,它由共享内存、一系列后台进程和数据文件组成。 (以下图)数据库
共享内存是服务器服务器为数据库缓存和事务日志缓存预留的内存缓存空间。其中最重要的组成部分是Shared Buffer和WAL Buffer。后端
Shared Buffer的目的是减小磁盘IO。为了达到这个目的,必须知足如下规则:缓存
WAL Buffer是用来临时存储数据库变化的缓存区域。存储在WAL Buffer中的内容会根据提早定义好的时间点参数要求写入到磁盘的WAL文件中。在备份和恢复的场景下,WAL Buffer和WAL文件是极其重要的。服务器
PostgreSQL有四种进程类型架构
主后台驻留进程是PostgreSQL启动时第一个启动的进程。启动时,他会执行恢复、初始化共享内存爱你的运行后台进程操做。正常服役期间,当有客户端发起连接请求时,它还负责建立后端进程。并发
若是经过pstree命令查看进程之间的关系,你会发现Postmaster进程是其余全部进程的父进程。post
PostgreSQL操做须要的后台进程列表以下:测试
进程 | 做用 |
---|---|
logger | 将错误信息写到log日志中 |
checkpointer | 当检查点出现时,将脏内存块写到数据文件 |
writer | 周期性的将脏内存块写入文件 |
wal writer | 将WAL缓存写入WAL文件 |
Autovacuum launcher | 当自动vacuum被启用时,用来派生autovacuum工做进程。autovacuum进程的做用是在须要时自动对膨胀表执行vacuum操做。 |
archiver | 在归档模式下时,复制WAL文件到特定的路径下。 |
stats collector | 用来收集数据库统计信息,例如会话执行信息统计(使用pg_stat_activity视图)和表使用信息统计(pg_stat_all_tables视图) |
最大后台连接数经过max_connections参数设定,默认值为100。后端进程用于处理前端用户请求并返回结果。查询运行时须要一些内存结构,就是所谓的本地内存(local memory)。本地内存涉及的主要参数有:
客户端进程须要和后端进程配合使用,处理每个客户连接。一般状况下,Postmaster进程会派生一个紫禁城用来处理用户连接。
想要理解PostgreSQL的数据库结构,须要先了解一些重要的概念。
数据库相关概念:
表空间相关概念:
表相关概念:
表和索引建立时文件名是OID,此时的OID和pg_class.relfilenode的值是同样的。无论怎样,当咱们执行重写操做时(truncate,cluster,vacuum full,reindex等),被修改对象的relfilenode值也会被修改,文件名也会随着reffilenode值一块儿改变。咱们能够经过pg_relation_filepath('<object_name>')视图很容易的检查文件位置和名称。
initdb()完成后,若是登陆数据库查询视图pg_database,咱们能够看到template0 , template1和 postgres数据库已经被建立好了。
上文提过,用户数据库建立是经过克隆template1数据库。为了验证这个规则,咱们如今template1中建立一个表t1,紧接着建立一个mydb01数据库,检查t1表是否在mydb01中存在。
initdb()后,若是登陆数据库查询pg_tablespace视图,会发现pg_global和pg_default表空间已经建立好。
pg_default表空间的位置为$PGDATA\base。每个数据库都拥有一个以本身OID命令的子路径。
pg_global表空间用于存储集群级别的数据。
pg_tablespace视图显示myts01表空间已经被建立好。
$PGDATA/pg_tblspc路径下有一个符号连接指到目标目录。
下面分别链接到postgres和mydb01数据库,建立表。
若是查看/data01路径下的内容,会发现上面建立的两个数据库中的t1表,分别在下面有一个对应OID的文件夹存在。
PostgreSQL在建立表空间时指定一个特定的路径。所以,若是该特定路径已经满了,数据就不能在向里面存储了。为了解决该问题,咱们可使用磁盘管理程序扩展空间。可是若是不想使用磁盘管理程序,咱们能够经过该表表空间的位置来解决该问题。命令以下:
vacuum执行以下操做:
#1 和 #2 是数据库管理须要的。#3 和 #4 PostgreSQL MVCC 特性的要求。
两者之间最大的不一样是MVCC模型和共享池(shared pool)。
指标 | ORACLE | PostgreSQL |
---|---|---|
MVCC模型 | UNDO | Store previous |
实现方法 | Segment | record within block |
共享池 | exists | it does not exist |
为了增长并发,必须遵循“读操做不阻塞写操做,写操做不阻塞读操做”的原则。为了实现这个原则,多版本并发控制(MVCC)理论被引入。Oracle使用UNDO段实现MVCC。而PostgreSQL存储以前的记录在数据块中,它经过事务XID和事务的xmin、xmax来控制事务版本。
PostgreSQL不提供共享池。这对于熟悉Oracle的用户来讲有点尴尬。共享池是Oracle中最基本和最重要的组件。PostgreSQL在进程级别提供SQL信息的共享能力,而不是共享池。换句话说,若是咱们在同一个进程中屡次执行相同的SQL,它只会硬解析一次。
很是感谢拜读本篇博客,下次再见~