本文参考书籍《postgresql指南–内幕探索》的
Chapter 2:Process and Memory Architecture
该书的网络内容可参考:The Internals of PostgreSQL
进程架构
Postgresql 是一个C/S架构的关系型数据库,由多个后台进程管理数据库,下面分别介绍一些这些进程:
- postgres server process :是所有进程的父进程
- backend process:每一个客户端的连接都有一个后端进程存在
- backgroud processes:为管理数据库而产生的一些进程
- backgroud work processes:9.3以后版本开始有这个进程
进程架构图如下:
下面简短的介绍一些这几个进程的作用
postgres server process
正如上所说,是所有进程的父进程,早期的版本叫postmaster.
pg_ctl start执行后,这个进程就会启动。然后,从物理内存中分配内存给shared memory,然后产生很多其他的backgroup processes ,等待客户端来连接,每产生一个连接就会生成一个backend process,一个postgres server process只能监听一个端口,默认端口是5432。尽管一台机器可以运行多个server,但是端口必须不同。
backend processes
通过TCP协议和客户端建立通讯,当客户端断开时,连接消失。允许多个客户端同时连接,连接数由max_connections参数控制,默认是100,如果客户端频繁的和服务端建立连接然后断开,会增加数据库的开销,导致服务器负载不正常,因为数据库本身不提供连接池的功能,如果有需要,可以使用pgbouncer或者pgpool-II。
backgroud processes
下面列出了相关的服务端进程,这里只做简单的介绍:
process | description |
---|---|
background writer | 进程将shared buffer pool中的脏数据写到磁盘,检查点总能触发这个进程 |
checkpointer | 在9.2版本以后,检查点会触发产生这个进程 |
autovacuum launcher | 为vacuum process周期性的调用autovacuum work processes |
WAL writer | 周期性的从wal buffer刷新数据到磁盘 |
statistics collector | 收集统计信息进程,比如pg_stat_activity 和pg_stat_database的数据 |
logging collector (logger) | 将错误信息写入到日志 |
archiver | 将日志归档的进程 |
这里显示了PostgreSQL数据库的进程信息。在以下示例中,一个postgres服务器进程(pid为9687),两个后端进程(pids为9697和9717)以及上表中列出的几个后台进程正在运行。
postgres> pstree -p 9687
-+= 00001 root /sbin/launchd
\-+- 09687 postgres /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
|--= 09688 postgres postgres: logger process
|--= 09690 postgres postgres: checkpointer process
|--= 09691 postgres postgres: writer process
|--= 09692 postgres postgres: wal writer process
|--= 09693 postgres postgres: autovacuum launcher process
|--= 09694 postgres postgres: archiver process
|--= 09695 postgres postgres: stats collector process
|--= 09697 postgres postgres: postgres sampledb 192.168.1.100(54924) idle
\--= 09717 postgres postgres: postgres sampledb 192.168.1.100(54964) idle in transaction
内存架构
在Postgresql中,内存大概被分为两块:
- Local memory area – 为每一个backend process 分配的内存
- Shared memory area – PostgreSQL server 所有的backgroud process使用的内存
本地内存区域
每一个backend process 都会分配一块local memory area,每一块区域又分为三个子区域 ,见下表:
sub-area | description |
---|---|
work_mem | 用户在sort,distinct,merge join,hash join的时候会用到这块区域 |
maintenance_work_mem | vacuum,reindex会用到这块区域 |
temp_buffers | 存储临时表会用到这块区域 |
共享内存区域
这块区域在服务器启动的时候分配,这块区域也是分为好几个子区域,见下面介绍:
sub-area | description |
---|---|
shared buffer pool | 将表或者索引的page从磁盘加载到shared buffer,然后在shared buffer操作 |
WAL buffer | 为了确保服务器故障不会丢失任何数据,PostgreSQL支持WAL机制。WAL数据(也称为XLOG记录)是PostgreSQL中的事务日志;WAL缓冲区是在写入持久性存储之前WAL数据的缓冲区。 |
commit log | 提交日志(CLOG)为并发控制(CC)机制保留所有事务的状态(例如,进行中,已提交,已中止)。 |
除此之外,PostgreSQL还分配了几个区域,如下所示:
- 各种访问控制机制的子区域。(例如,信号灯,轻量级锁,共享锁和排他锁等)
- 各种后台进程的子区域,例如checkpointer和auto vacuum。
- 事务处理的子区域,例如保存点和两阶段提交。