二、进程体系与内存布局
进程体系
PostgreSQL是一个多进程体系的DBMS。PostgreSQL服务器由一组服务器进程管理的
- PostgreSQL server进程是所有pg相关进程的父进程。
- 每一个后端进程(Backend process)管理连接端的所有执行语句和状态。
- 后台进程(Background processes)执行数据库管理的进程,如VACUUM、Checkpoint。
- 在流复制进程中,主要负责流复制相关操作
- 在工作者进程(worker process),可以执行用户的相关处理。
主服务进程

从服务进程

大致布局

Postgres服务进程
执行pg_ctl命令行工具,pg服务就会启动。紧接着,会在内存中分配共享内存,并启动若干个后台进程、流复制进程,若有客户端连接,就会启动pg的工作者进程(worker process)。无论何时,只要从客户端接收到新的请求,就会启动一个新的后端进程。
后端进程
有一个客户端连接,就会新fork一个postgres进程;一个TCP连接对应一个进程。 一个进程只允许操作一个数据库,连接Pg服务器时,就得在连接配置项指定。 Pg允许同时连接多个客户端,最大客户端连接数在配置文件里设置(max_connections)。 Pg自带没有连接池,但有pgbouncer、pgpool2这类中间件。
后台进程
| 进程名 | 描述 |
|---|---|
| background writer | 在此进程里,在shared buffer里的脏页数据会被定期写入到硬盘 |
| checkpointer | 检查点 |
| autovacuum launcher | 定期执行vacuum命令 |
| WAL writer | 定期执行写入、刷新wal数据从wal buffer => 硬盘 |
| statistics collector | 收集统计信息,像pg_stat_activity或pg_stat_database里存放的数据 |
| logging collector | 写错误日志到日志文件 |
| archiver | 执行归档操作 |
内存布局
PostgreSQL的内存布局可分为两个板块
- 进程内存域,每个后台进程独自分配使用
- 共享内存域,pg服务进程通用。
后端进程里的内存块
| 名字 |
|---|
| temp_buffers |
| work_mem |
| maintenance_work_mem |
共享内存里的内存块
| 名字 |
|---|
| shared buffer pool |
| wal buffer |
| CommitLog(CLOG) |
进程内的内存块
每个后端进程分配了一块内存用于查询处理;每块区域由若干个子域隔离,每个域的大小可能是固定的,也可能是变化的。
| 子域名称 | 描述 |
|---|---|
| work_mem | 用于 Order by、Distinct、表连接等操作 |
| maintenance_work_mem | 执行一些管理操作,如VACUUM、REINDEX |
| temp_buffers | 用于存放临时表 |
共享内存的内存块
共享内存由Pg服务启动时分配。共享内存里分布多个内存块。
| 子域名称 | 描述 |
|---|---|
| shared buffer pool | pg直接从硬盘加载“页”到内存里 |
| wal buffer | 为确保数据不会在服务崩溃时丢失,pg采用了wal技术。wal数据(又称为xlog记录)在pg里是事物日志;wal buffer是在wal数据准备写入到硬盘前的缓冲区 |
| commit log | CLOG保持所有事务状态,如in_progress,committed,aborted,用于并发控制 |
除此之外,PG还分配了若干块用于展示:
- 访问控制,如信号量、轻量级锁、shared lock、exclusive lock
- Checkpointer、autovacuum
- 保存点(save point)、两阶段提交