版权声明:
本文作者是日本的Hironobu SUZUKI
原文地址
中文版图书 PostgreSQL指南:内幕探索
本文旨在学习目的,禁止用于商业目的。
- 本章节讲述了postgresql 的进程管理,如果你对进程这个概念有些生疏,可以参考我之前的文章 进程,线程,协程
进程和内存结构
在本章中,总结了 PostgreSQL 中的进程体系结构和内存体系结构,以帮助阅读后面的章节。
1. 进程架构
PostgreSQL 是一个客户端/服务端 c\s
类型的关系型数据库管理系统,具有多进程架构,并在单个主机上运行。
多个进程共同管理一个数据库集群通常被称为PostgreSQL 服务器
,它包含以下类型的进程:
- postgres server process
这个进程是所有进程的父进程,用于管理postgresql数据库进程 - backend process
后端进程用于处理连接的客户端发出的所有查询和语句 - background processes
后台进程执行每个具有特性的数据库管理进程,比如VACUUM
和CHECKPOINT
- replication associated processes
replicate 相关进程 ,执行流式复制 - background worker process
后台worker进程
PostgreSQL 可以扩展为在单独的进程中运行任何用户提供的代码。
worker数量由配置文件中的max_worker_processes
项进行配置
详见 官方文档
下面将介绍前三种进程。
- 该图展示了一个 PostgreSQL 服务器的进程:
一个 postgres 服务器进程
两个后端进程
七个后台进程
两个客户端进程
还说明了数据库集群、共享内存和两个客户机进程
1.1 Postgres Server Process
如上所述,postgres 服务器进程是 PostgreSQL 服务器中所有进程的父进程。在早期的版本中,它被称为postmaster
通过执行带有 start 选项的 pg_ctl 实用程序,postgres 服务器进程将启动。
然后,它在内存中开辟一个共享内存区域,启动各种后台进程,必要时启动replication associated进程和background worker进程,并等待来自客户机的连接请求。无论何时从客户机接收连接请求,它都会启动一个后端进程。(然后,已启动的后端进程处理由连接的客户机发出的所有查询。)
一个 postgres 服务器进程监听一个网络端口,默认端口是5432。尽管可以在同一台主机上运行多台 PostgreSQL 服务器,但是每台服务器应该设置为相互监听不同的端口号,例如5432、5433等。
1.2 Backend Processes
后端进程(也称为 postgres)由 postgres 服务器进程启动,并处理由一个连接的客户端发出的所有查询。它通过单个 TCP 连接与客户端通信,并在客户端断开连接时终止。
由于只允许操作一个数据库,因此必须指定在连接到 PostgreSQL服务器时,要使用显式的连接数据库。
PostgreSQL 允许多个客户机同时连接; 配置参数 max_connections 控制客户机的最大数量(默认值为100)。
如果许多客户机,比如 WEB 应用程序,频繁地重复与 PostgreSQL 服务器的连接和断开,那么建立连接和创建后端进程的成本都会增加,因为 PostgreSQL 没有实现本地连接池特性。
这种情况对数据库服务器的性能有负面影响。为了处理这种情况,通常使用池中间件(pgbouncer 或 pgpool-II)。
1.3 Background Processes
下面的表格显示了background processes 的种类。
与postgres server
和backend process
不同,不可能简单的介绍每种进程的功能,因为这些功能依赖于个别的特定特性和 PostgreSQL内部组件。
process | description | reference |
---|---|---|
background writer | 在这个进程中,共享缓冲池share buffer pool 上的脏页dirty page 将逐步写入持久存储(例如 HDD、 SSD)。(在版本9.1或更早的版本中,它还负责检查点进程。) | |
checkpointer | 执行检查点进程 | |
autovacuum launcher | 周期调用脏页回收进程vacuum process ,更确切的说,是请求postgres server 新增autovacuum workers | |
WAL writer | 这个进程将WAL缓冲区的数据写入持久存储 | |
statistics collector | 收集了 pg_stat_activity 和 pg_stat_database 等统计信息 | |
logging collector (logger) | 此进程将错误消息写入日志文件 | |
archiver | 执行归档日志记录 |
2. 内存架构
内存架构可以分为两大类:
- Local memory area 本地内存区域——由每个后端进程
backend process
开辟 - Shared memory area 共享内存区域——用于 PostgreSQL 服务器的所有进程
2.1 Local Memory Area
每个后端进程分配一个用于处理查询的本地内存区域;
每个区域被划分为几个子区域,它们的大小要么是固定的,要么是可变的。
表2.2显示了主要子区域的列表。细节将在下面的章节中描述。
- Local memory area sub-area
sub-area | description | reference |
---|---|---|
work_mem | 使用这个区域按 ORDER BY 和 DISTINCT 操作对元组进行排序,joining table ,hash-join ,merge-join 也在此区域进行操作。 | |
maintenance_work_mem | 某些类型的维护操作(如 VACUUM、 REINDEX)使用这个区域 | |
temp_buffers | 存储临时表 |
2.2 Shared Memory Area
- Share Memory Area
sub-area | description | reference |
---|---|---|
shared buffer pool | PostgreSQL 将表中的页page 和索引index 从持久存储装载到这里,并直接操作它们 | |
WAL buffer | 为了确保服务器故障不会造成数据丢失,PostgreSQL 支持 WAL日志预写 机制。WAL数据(也称为XLOG记录)是 PostgreSQL 中的事务日志; WAL buffer是WAL数据写入持久存储之前的缓冲区 | |
commit log | 保存着所有事务的状态(例如,in_progress,committed,abort) ,用于并发控制/服务 |
除此之外,postgresql 还有以下内存区域
- 各种访问控制机制的子区域(例如,信号量、轻量级锁、共享锁和排他锁等)
- 各种后台进程的子区域,如
checkpointer
,autovacuum
- 用于事务处理的子区域,例如
save-point
,two-phase-commit