二、进程体系与内存布局
进程体系
PostgreSQL是一个多进程体系的DBMS。PostgreSQL服务器由一组服务器进程管理的
- PostgreSQL server进程是所有pg相关进程的父进程。
- 每一个后端进程(Backend process)管理连接端的所有执行语句和状态。
- 后台进程(Background processes)执行数据库管理的进程,如VACUUM、Checkpoint。
- 在流复制进程中,主要负责流复制相关操作
- 在工作者进程(worker process),可以执行用户的相关处理。
主服务进程
从服务进程
大致布局
Pg服务进程之间使用共享内存来通信。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)、两阶段提交