PostgreSQL内幕探索—进程与内存结构
本篇介绍PostgreSQL(以下简称PG)的主要进程和内存结构。PG是一个典型C/S架构的关系数据库管理系统,采用多进程架构,运行在单台服务器上。
主要进程
我们一般所说的PG服务器,实际上是一系列协同工作的进程集合,主要包含了下面的进程
- Postmaster服务器进程,所有数据集簇(database cluster)工作进程的父进程
- backend progress后端进程,负责处理客户端发出的查询和语句
- background progress后台进程,负责执行各种管理数据库的任务,例如清理进程
- replication assoiated progress复制相关进程,负责流复制
- background work progress 后台工作进程,9.3版本被引入,能执行任意由用户实现的处理逻辑。
我们详细介绍前三种进程,其他内容暂不做详细描述,可以参考官方文档。可以通过下面的图来了解主要进程,包含了1个服务器进程,2个client进程,2个后端进程,7个后台进程。也话除了shared buffer和database cluster
Postmaster服务器进程
Postmaster是PG服务器中所有进程的父进程,在使用pg_ctl start
命令时会启动Postmaster进程,它会在内存中分配共享内存,并且启动各种后台进程,如果涉及流复制还会启动复制进程。然后等待客户端发起连接请求,每次收到客户端的连接请求时,Postmaster进程会启动一个后端进程来负责处理该客户端发送的查询和语句。
一个Postmaster只能监听一个网络端口,默认端口为5432。如果要在单台服务器上部署多个PG服务器,那么需要为每个PG服务器分配不同的网络端口。
后端进程
每个后端进程backend process由父进程Postmaster启动,并处理对应客户端发出的所有查询和语句。通过TCP建立连接,在client断开连接后就会终止。
因为一个连接只能操作一个数据库,所以必须在建立连接时显式指定数据库,否则会报错。
PG允许多个客户端同时进行连接,最大连接限制由参数max_connecitons
参数控制。PG没有原生的连接池功能,所以频繁创建销毁连接是一个开销很大的操作,这时可以借助池化中间件来合理控制连接或者客户端例如web程序中的druid连接池来做控制。
后台进程
比起后端进程,后台进程的种类繁多,要在本文全部详细解释出来是不太现实的,所以当前只做简单介绍,后续做详细介绍。每个后台进程和对应的描述可以参照下表
进程名 | 描述 |
---|---|
background writer | 此进程用于将共享缓存中的脏页逐渐刷入持久化存储(磁盘等)中 |
checkpointer | 此进程负责处理检查点 |
autovacuum launcher | 此进程负责周期性地启动自动清理进程 |
WAL writer | 此进程用于将WAL buffer中的数据刷入持久化存储(磁盘等)中 |
statistics collector | 此进程负责收集统计信息,用于pg_stat_activity、pg_stat_database等系统视图 |
log writer | 此进程负责将错误消息写入日志 |
archiver | 此进程负责日志归档 |
内存架构
PG的内存结构主要分为两个部分,本地内存区和共享内存区
- 本地内存区,由每个后端进程backend process分配,只供自己使用
- 共享内存区,由postmaster启动时分配,供所有进程使用
大体的内存架构图如下
每个后端进程都会分配一块本地内存区用于查询处理。该区域分为几个子区域,有的大小不变,有的大小可变,本地内存区的各子区域和描述如下表
子区域 | 描述 |
---|---|
work_mem | 该子区域用于处理查询的order by语句和distinct语句排序,存储归并连接和hash连接的连接表,如果不够用的话会使用磁盘临时文件 |
maintenance_work_mem | 该子区域用于维护类操作,例如vacuum或者reindex等 |
temp_buffer | 执行器使用此区域存储临时表 |
PG启动时就会分配共享内存区域,主要的子区域和描述如下表
子区域 | 描述 |
---|---|
shared buffer pool | PG将表中的数据和索引所在的页面从持久化存储加载到共享缓冲池,并在这里直接操作它们 |
commit log(clog) | 提交日志用于保存事务的状态,实现MVCC的关键 |
WAL buffer | 确保crash-safe,PG实现了WAL机制。WAL数据(xlog记录)是PG中的事务日志,WAL buffer是写入wal日志文件前的缓冲区 |
除了上面介绍的主要区域,PG中还分配了以下几个区域
- 访问控制的子区域(信号量,锁相关)
- 各种后台进程使用的子区域,例如checkpointer和autovacuum
- 事务处理使用的子区域,例如savepoint和两阶段提交2PC