本章总结了PostgreSQL的进程架构和内存架构。
2.1. Process Architecture(进程架构)
PostgreSQL是一个客户端/服务器类型的关系数据库管理系统,具有多进程架构,运行在单个主机上。
多个进程协同管理一个数据库集群通常被称为“PostgreSQL server”,它包含以下类型的进程:
postgres 服务器进程:postgres服务器进程是所有与数据库集群管理相关进程的父进程。
backend 进程: 每个backend进程处理由连接的客户机发出的所有查询和语句。
background 进程: 不同的background 进程执行不同特性的进程(例如,VACUUM进程和CHECKPOINT进程),用于数据库管理。
replication associated 进程: 与复制相关的进程负责执行流复制。
background worker 进程:background worker process进程可以执行用户实现的任何处理。
图 2.1.PostgreSQL进程架构示例

图片来源:https://www.interdb.jp/pg/pgsql02.html
这张图显示了一个PostgreSQL服务器的进程:一个postgres服务器进程,两个backend进程,七个background进程和两个客户端进程。还演示了数据库集群、共享内存和两个客户机进程。
2.1.1 Postgres服务器进程
如上所述,postgres服务器进程是PostgreSQL服务器中所有进程的父进程。在早期的版本中,它被称为postmaster。
通过执行带有start选项的pg_ctl程序,postgres服务器进程将启动。然后,它在内存中分配一个共享内存区域,启动各种background进程,必要时启动与复制相关的进程和background workers进程,并等待客户机的连接请求。每当收到来自客户机的连接请求时,它就启动backend进程。(然后,启动的backend进程处理连接的客户端发出的所有查询。)
2.1.2. Backend 进程
backend进程也称为postgres,由postgres服务器进程启动,并处理由一个连接的客户机发出的所有查询。它通过一个TCP连接与客户机通信,并在客户机断开连接时终止。
因为它只允许操作一个数据库,所以在连接到PostgreSQL服务器时,必须明确指定想要使用的数据库。
允许多个客户端同时连接;配置参数max_connections控制客户机的最大数量(默认为100)。
如果许多客户端(如WEB应用程序)频繁地重复连接和断开与PostgreSQL服务器的连接,这会增加建立连接和创建后端进程的成本,因为PostgreSQL没有实现本机连接池特性。这种情况会对数据库服务器的性能产生负面影响。为了处理这种情况,通常使用池中间件(pgbouncer或pgpool-II)。
2.1.3. Background 进程
表2.1: background 进程
| 进程 | 描述 |
| background writer | 在这个过程中,共享缓冲池中的脏页会被逐步地定期写入持久存储(例如,HDD、SSD)。 |
| checkpointer | 负责执行checkpoint。 |
| autovacuum launcher | 负责执行autovacuum。 |
| WAL writer | 该进程定期将WAL缓冲区中的WAL数据写入并刷新到持久存储中。 |
| statistics collector | 在这个过程中,会收集诸如pg_stat_activity和pg_stat_database等统计信息。 |
| logging collector (logger) | 此进程将错误消息写入日志文件。 |
| archiver | 在此过程中,将执行归档日志记录。 |
2.2. Memory Architecture(内存架构)
PostgreSQL的内存体系结构可以分为两大类:
Local memory area 本地内存区域——由每个后端进程分配供自己使用。
Shared memory area 共享内存区域——由PostgreSQL服务器的所有进程使用。
图. 2.2. Memory architecture in PostgreSQL

图片来源:https://www.interdb.jp/pg/pgsql02.html
2.2.1. Local Memory Area(本地内存区域)
每个backend进程分配一个本地内存区域用于查询处理;每个区域又分为几个子区域,子区域的大小可以是固定的,也可以是可变的。表2.2列出了主要的子区域。
表 2.2: Local memory area
| 子区域 | 描述 |
| work_mem | Executor使用此区域按顺序和不同的操作对元组进行排序,并使用merge-join和hash-join操作来连接表。 |
| maintenance_work_mem | 某些维护操作(如VACUUM, REINDEX)使用这个区域。 |
| temp_buffers | Executor使用此区域存储临时表。 |
2.2.2. Shared Memory Area(共享内存区域)
共享内存区域由PostgreSQL服务器在启动时分配。这个区域也被划分为几个固定大小的子区域。表2.3列出了主要的子区域。
表 2.3: Shared memory area
| 子区域 | 描述 |
| shared buffer pool | PostgreSQL将表和索引中的页面从持久存储加载到这里,并直接操作它们。 |
| WAL buffer | 为了保证数据不因服务器故障而丢失,PostgreSQL支持WAL机制。WAL data(也称XLOG records)是PostgreSQL中的事务日志;WAL buffer是WAL数据写入持久存储之前的缓冲区域。 |
| commit log | 提交日志(CLOG)保存所有事务(如in_progress,committed,aborted)的状态,用于并发控制(CC)机制。 |
除了上面提到的本地内存区域和共享内存区域,PostgreSQL还分配了如下几个区域:
子区域用于各种访问控制机制。(例如,信号量、轻量级锁、共享锁和排他锁等)
用于各种后台进程的子区域,如checkpointer和autovacuum。
事务处理的子区域,比如保存点和两阶段提交。
等等。




