PostgreSQL进程和内存浅析

AI 摘要 / TL;DR

PostgreSQL进程和内存浅析 点击上方“IT那活儿”公众号,关注后了解更多内容,不管IT什么活儿,干就完了!!! 本文主要是对 PostgreSQL 中的进程架构和内存架构做下简单介绍, 适用于初学者阅读。 PART1 PostgreSQL的进程结构 PostgreSQL是具有多进程体系结构的客户端/服务器类型的

来源: https://www.ucloud.cn/yun/129502.html 作者: IT那活儿 发布日期: 发布于2023-01-11 13:19

PostgreSQL进程和内存浅析

点击上方“IT那活儿”公众号,关注后了解更多内容,不管IT什么活儿,干就完了!!!

本文主要是对 PostgreSQL 中的进程架构和内存架构做下简单介绍,适用于初学者阅读。

PART1

PostgreSQL的进程结构

PostgreSQL是具有多进程体系结构的客户端/服务器类型的关系数据库管理系统。

协作管理一个数据库集群的多个进程的集合称为“PostgreSQL服务器”,它主要包含以下3种类型的进程:

  • postgres server process:Postgres服务器进程,即守护进程,是数据库集群管理的所有进程的父进程。
  • backend processes:后端进程,每个后端进程处理连接进来的客户端发出的所有查询和语句。
  • backgroud processes:后台进程,每个后台进程分别执行相应的功能(例如VACUUM和CHECKPOINT进程)以进行数据库管理。

下面将分别对这三种进程进行介绍:

图1.1.PostgreSQL进程结构示意图

1.1 postgres server process

postgres server process,即postgres服务器进程,也叫守护进程,它是所有进程的父进程,早期的版本叫postmaster。其执行文件位于安装目录的bin目录下:

当执行pg_ctl start,postgres服务器进程将会启动。

然后,它从内存中分配一个shared memory area,启动各种background processes后台进程,并等待来自客户端的连接请求,必要时还会启动与复制相关的进程和后台工作进程。每当接收到一个来自客户端的连接请求时,它就会启动(forks)一个backend process后端进程,启动的后端进程将处理连接进来的客户端发出的所有查询。

1.2 backend processes

backend process,即后端进程(也称为postgres),由postgres服务器进程启动,并处理由一个连接的客户端发出的所有查询。它通过TCP协议与客户端建立通信,并在客户端断开连接时终止。

PostgreSQL允许多个客户端同时连接,连接数由max_connections参数控制(默认为100)。

PostgreSQL不具备本地连接池功能,如果许多客户端(例如WEB应用程序)频繁重复与PostgreSQL服务端进行连接和断开连接,会增加数据库的开销,这会对数据库服务器的性能产生负面影响,为了避免这种情况,通常使用中间件(pgbouncer 或pgpool-II)。

1.3 backgroud processes

下面是对相关的服务端后台进程的介绍:

  • **background writer(后台写进程):**定期将shared buffer pool中的脏数据写到磁盘上的进程,checkpoint也会触发这个过程,类似Oracle的dbwn进程。当插入或更新数据时,并不会马上把数据持久化至数据文件中。

    这是基于提高插入、更新及删除数据的性能考虑的,毕竟写内存比写硬盘会快很多。BgWriter会周期性的将内存中的脏块刷新至磁盘,刷脏块既不能太快也不能太慢。

    如果一个数据库短时间内被修改多次,当刷新过快的情况下,它每次的修改都会保存至磁盘,这会导致I/O增加,从而影响性能。刷新过慢时,对于繁忙的数据库而言,内存中存放大量的脏块未刷新至磁盘,假设此时无可用内存,当有新的更新需要使用内存来保存从磁盘中读取的数据块时,需要等待脏块刷新至磁盘把内存腾挪出来。

    这样会导致更新需要等更长的时间。并且如果出现异常宕机的情况,重启时需要恢复的那部分没有刷新至磁盘的脏块,也影响其故障恢复的时间。其机制由如下参数来控制:

  • **Checkpointer进程:**执行checkpoint,类似Oracle的ckpt
    autovacuum launcher进程:为vacuum process周期性的调用autovacuum work processes,用于旧数据的清除。

  • **wal writer进程:**将wal buffer的数据刷新到磁盘,WAL log另称为预写式日志。即在事务提交之前,必须将这些修改操作记录到磁盘中。这样就不需要实时地将脏数据持久化到磁盘。

    即便服务器突然宕机或数据库异常宕掉,导致一部分内存中的脏块未刷新至文件,在数据库重启后,通过读取WAL日志,将这部分事务重放一遍就可以将数据库恢复至宕机的时刻。

  • **stats collector进程:**收集统计信息,例如pg_stat_activity 和pg_stat_database的统计信息。

  • **logging collector (logger)进程:**将错误信息写入到日志。

  • **Archiver进程:**将WAL log归档。

下面的示例展示了PostgreSQL服务器的进程信息,一个postgres server process守护进程,backend processes以及几个background processes后台进程正在运行。

一次PostgreSQL会话过程分解如下:

--客户端调用libpq(数据库应用连接接口库,如JDBC,ODBC),将连接请求发送给守护进程;

--守护进程启动(forks)一个新的后端进程postgres与客户端应用连接;

--后端进程postgres直接与用户通信,不再通过守护进程;

--后端进程postgres接收客户端的查询请求,完成并返回结果;

--客户端每创建一个数据库连接,守护进程就生成一个后端进程pstogres。

PART2

PostgreSQL的内存结构

PostgreSQL的内存结构分为两部分:

  • Local memory area,由每个backend process后端进程分配以供其自己使用。
  • Shared memory area,由PostgreSQL server的所有服务进程共享使用的内存。

图 2.1. PostgreSQL的内存结构

2.1 Local memory area

每一个backend process后端进程都会分配一个local memory area, 每个local memory area又分为三部分:

2.2 Shared memory area

shared memory area由PostgreSQL server的所有服务进程共享使用,这个区域在PostgreSQL server启动的时候分配,它包括三个主要的缓冲区:

除此之外,PostgreSQL还在Shared memory area分配一些其他的内存区域:

  • 为各种访问控制机制分配的子区域,例如轻量级锁,共享锁和排他锁等。
  • 各种后台进程的子区域,例如checkpointer和autovacuum。
  • 为事务处理提供的子区域,比如事务中的save-point,和二阶段事务提交。
  • 其他。

END

本文作者:魏 斌

本文来源:IT那活儿(上海新炬王翦团队)