深入理解Postgresql -2

张彤 2021年12月15日 305次浏览

版权声明:
本文作者是日本的Hironobu SUZUKI
原文地址
中文版图书 PostgreSQL指南:内幕探索
本文旨在学习目的,禁止用于商业目的。

  • 本章节讲述了postgresql 的进程管理,如果你对进程这个概念有些生疏,可以参考我之前的文章 进程,线程,协程

进程和内存结构

在本章中,总结了 PostgreSQL 中的进程体系结构和内存体系结构,以帮助阅读后面的章节。

1. 进程架构

PostgreSQL 是一个客户端/服务端 c\s类型的关系型数据库管理系统,具有多进程架构,并在单个主机上运行。

多个进程共同管理一个数据库集群通常被称为PostgreSQL 服务器,它包含以下类型的进程:

  • postgres server process
    这个进程是所有进程的父进程,用于管理postgresql数据库进程
  • backend process
    后端进程用于处理连接的客户端发出的所有查询和语句
  • background processes
    后台进程执行每个具有特性的数据库管理进程,比如 VACUUMCHECKPOINT
  • replication associated processes
    replicate 相关进程 ,执行流式复制
  • background worker process
    后台worker进程
    PostgreSQL 可以扩展为在单独的进程中运行任何用户提供的代码。
    worker数量由配置文件中的max_worker_processes项进行配置
    详见 官方文档

下面将介绍前三种进程。
图1 进程结构

  • 该图展示了一个 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 serverbackend process不同,不可能简单的介绍每种进程的功能,因为这些功能依赖于个别的特定特性和 PostgreSQL内部组件。

processdescriptionreference
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_activitypg_stat_database 等统计信息
logging collector (logger)此进程将错误消息写入日志文件
archiver执行归档日志记录

2. 内存架构

内存架构可以分为两大类:

  1. Local memory area 本地内存区域——由每个后端进程backend process开辟
  2. Shared memory area 共享内存区域——用于 PostgreSQL 服务器的所有进程

图2 内存架构

2.1 Local Memory Area

每个后端进程分配一个用于处理查询的本地内存区域;
每个区域被划分为几个子区域,它们的大小要么是固定的,要么是可变的。
表2.2显示了主要子区域的列表。细节将在下面的章节中描述。

  • Local memory area sub-area
sub-areadescriptionreference
work_mem使用这个区域按 ORDER BYDISTINCT 操作对元组进行排序,joining table,hash-join,merge-join 也在此区域进行操作。
maintenance_work_mem某些类型的维护操作(如 VACUUM、 REINDEX)使用这个区域
temp_buffers存储临时表

2.2 Shared Memory Area

  • Share Memory Area
sub-areadescriptionreference
shared buffer poolPostgreSQL 将表中的页page和索引index从持久存储装载到这里,并直接操作它们
WAL buffer为了确保服务器故障不会造成数据丢失,PostgreSQL 支持 WAL日志预写机制。WAL数据(也称为XLOG记录)是 PostgreSQL 中的事务日志; WAL buffer是WAL数据写入持久存储之前的缓冲区
commit log保存着所有事务的状态(例如,in_progress,committed,abort) ,用于并发控制/服务

除此之外,postgresql 还有以下内存区域

  • 各种访问控制机制的子区域(例如,信号量、轻量级锁、共享锁和排他锁等)
  • 各种后台进程的子区域,如checkpointerautovacuum
  • 用于事务处理的子区域,例如save-point , two-phase-commit