PostgreSQL指南:内幕探索
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

第2章 进程和内存架构

本章会总结PostgreSQL中进程与内存的架构,有助于读者理解后续章节。如果读者已经熟悉这些内容,可以直接跳过本章。

2.1 进程架构

PostgreSQL是一个客户端/服务器风格的关系型数据库管理系统,采用多进程架构,运行在单台主机上。

我们通常所说的“PostgreSQL 服务器(PostgreSQL Server)”,实际上是一系列协同工作的进程集合,其中包含下列进程:

· Postgres服务器进程(postgres server process)是所有数据库集簇管理进程的父进程。

· 每个后端进程(backend process)负责处理客户端发出的查询和语句。

· 各种后台进程(background process)负责执行各种数据库管理任务(例如清理过程与存档过程)。

· 各种复制相关进程(replication associated process)负责流复制,流复制的细节会在第11章中介绍。

· 后台工作进程(background worker process)在9.3版本中被引入,它能执行任意由用户实现的处理逻辑。这里不做详述,更多内容请参阅官方文档。

以下几小节将详细描述前三种进程。

图2.1展示了PostgreSQL服务器包含的postgres服务器进程、2个后端进程、7个后台进程及2个客户端进程。也画出了数据库集簇、共享内存及2个客户端。

图2.1 PostgreSQL的进程架构示例

2.1.1 Postgres服务器进程

如上所述,postgres服务器进程是 PostgreSQL服务器中所有进程的父进程,在早期版本中被称为“postmaster”。

带start参数执行pg_ctl实用程序会启动一个postgres服务器进程。它会在内存中分配共享内存区域,启动各种后台进程,如有必要还会启动复制相关进程与后台工作进程,并等待来自客户端的连接请求。每当接收到来自客户端的连接请求时,它都会启动一个后端进程,然后由启动的后端进程处理该客户端发出的所有查询。

一个postgres服务器进程只会监听一个网络端口,默认端口为5432。如果要在同一台主机上运行多个PostgreSQL服务器,则应为每个服务器配置不同的监听端口,如5432、5433等。

2.1.2 后端进程

每个后端进程(也称为“postgres”)由 postgres 服务器进程启动,并处理连接另一侧的客户端发出的所有查询。它通过单条TCP连接与客户端通信,并在客户端断开连接时终止。

因为一条连接只允许操作一个数据库,所以必须在连接到PostgreSQL服务器时显式地指定要连接的数据库。

PostgreSQL允许多个客户端同时连接,配置参数max_connections用于控制最大客户端连接数(默认为100)。

因为 PostgreSQL 没有原生的连接池功能,所以如果许多客户端频繁地重复与 PostgreSQL服务器建立断开连接(譬如 Web 应用),则会导致建立连接与创建后端进程的开销变大。这种情况对数据库服务器的性能有负面影响,通常可以使用池化中间件(pgbouncer或pgpool-II)来避免该问题。

2.1.3 后台进程

表2.1是后台进程的列表。比起postgres服务器和后端进程,后台进程的种类要多很多。想要简单地解释每种后台进程的具体功能是不现实的,因为这些功能具有依赖PostgreSQL的内部机制与特定的独立特性,依赖于各个特定的特性以及PostgreSQL的内部机制。因此在本章中仅做简要介绍,更多细节将在后续章节中描述。

表2.1 后台进程

这里展示了PostgreSQL服务器包含的实际进程。在以下示例中有1个postgres服务器进程(pid为9687)、2个后端进程(pid为9697和9717)及表2.1中列出的几个后台进程正在运行,详见图2.1。

    postgres> pstree -p 9687
    -+= 00001 root /sbin/launchd
     \-+- 09687 postgres /usr/local/pgsql/bin/postgres -D /usr/local/pgsql/data
      |--= 09688 postgres postgres: logger process

      |--= 09690 postgres postgres: checkpointer process
      |--= 09691 postgres postgres: writer process
      |--= 09692 postgres postgres: wal writer process
      |--= 09693 postgres postgres: autovacuum launcher process
      |--= 09694 postgres postgres: archiver process
      |--= 09695 postgres postgres: stats collector process
      |--= 09697 postgres postgres: postgres sampledb 192.168.1.100(54924) idle
      \--= 09717 postgres postgres: postgres sampledb 192.168.1.100(54964) idle in transaction