Postgresql使用多进程架构实现(Mysql为多线程),PG启动时会拉起守护进程,然后由守护进程fork相关的后台辅助进程。守护进程的另一个作用是监听客户端的连接请求,当client发起连接时,守护进程会fork服务进程来处理client发送过来的命令,每有一个连接,后台就会存在一个服务进程。

在一个连接数高的PG服务端ps时能看到很多进程存在,大部分这些进程就是服务进程。例如服务端启动后,我们可以看到这样的进程结构:
/disk1/p01/pgsql8400/bin/postgres
\_ postgres: logger process
\_ postgres: checkpointer process
\_ postgres: writer process
\_ postgres: wal writer process
\_ postgres: archiver process
\_ postgres: stats collector process其中/disk1/p01/pgsql8400/bin/postgres是父进程也就是守护进程,下面的几个服务进程是守护进程拉起的。
当一个连接创建后,例如使用psql连接,进程变为:
/disk1/p01/pgsql8400/bin/postgres
\_ postgres: logger process
\_ postgres: checkpointer process
\_ postgres: writer process
\_ postgres: wal writer process
\_ postgres: archiver process
\_ postgres: stats collector process
\_ postgres: postgres postgres [local] idle
\_ -bash
| \_ psql可以看到psql进程启动后,PG守护进程fork了一个子进程来为连接服务。
其他服务进程的功能见下表
Process | Role |
|---|---|
logger | Write the error message to the log file. |
checkpointer | When a checkpoint occurs, the dirty buffer is written to the file. |
writer | Periodically writes the dirty buffer to a file. |
wal writer | Write the WAL buffer to the WAL file. |
Autovacuum launcher | Fork autovacuum worker when autovacuum is enabled.It is the responsibility of the autovacuum daemon to carry vacuum operations on bloated tables on demand |
archiver | When in Archive.log mode, copy the WAL file to the specified directory. |
stats collector | DBMS usage statistics such as session execution information ( pg_stat_activity ) and table usage statistical information ( pg_stat_all_tables ) are collected. |
一个正常启动的postgresql守护进程的调用栈:
#0 __select_nocancel
#1 ServerLoop
#2 PostmasterMain
#3 main 启动流程的源码可以从PostmasterMain函数开始调试。 Postmaster.c
void
PostmasterMain(int argc, char *argv[]) {
...
InitializeGUCOptions();
...
SysLoggerPID = SysLogger_Start();
...
pgstat_init();
...
status = ServerLoop();
...
}PG使用进程架构,所以进程间通信的方式是非常重要的。PG使用共享内存作为主要的数据共享、进程通信的方式。

PG服务进程的local memory包括三个部分
本地内存 | 说明 | 相关参数(默认值) |
|---|---|---|
work_mem | order by、distinct操作对元组进行排序,使用merge-join和hash-join连接表 | work_mem = 4MB |
maintenance_work_mem | vacuum、reindex | maintenance_work_mem = 64MB |
temp_buffers | 临时表排序 | temp_buffers = 8MB |
PG的所有进程共享使用shared memory,这里列举三个主要的缓冲区。
共享内存 | 说明 | 相关参数 |
|---|---|---|
Shared Buffer | 对于表和索引的所有操作都需要先加载到这里,然后进程来做相关操作 | shared_buffers = 128MB |
Wal Buffer | PG以redo log的方式保证数据不会丢失,PG的实现即WAL机制,WAL log可以理解为数据库的事务日志,这部分日志持久化使用wal buffer缓冲区 | wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers |
Clog Buffer | Commit Log(CLOG) keeps the states of all transactions (e.g., in_progress,committed,aborted) for Concurrency Control (CC) mechanism. |
除上述外,PG在共享缓冲区内 实现了锁、vacuum、两阶段事务管理等等功能。
TOP命令获取的PG进程内存通常是很高的,所有PG进程加起来可能比计算机实际内存还要高。原因是每个进程都会统计占用共享内存的大小,而PG是大量使用共享内存的,而且这类工具一般统计共享内存是进程整个生命周期中使用的所有共享内存页面数量,这样看起来很像内存泄漏,实际上是没有问题的。