Postgresql 15 进程结构和内存结构
操作系统进线与线程
在计算机系统中,进程和线程是两个重要的概念,用于管理和执行程序的执行。
进程(Process)是指正在运行的程序的实例。它是计算机系统中的一个独立单位,具有自己的内存空间、程序代码、数据和执行环境。每个进程都是由操作系统分配的资源的独立拥有者,它可以包含一个或多个线程。进程之间是相互独立的,它们在内存中有各自的地址空间,可以独立执行和调度。
线程(Thread)是进程中的一个执行单元。一个进程可以包含多个线程,它们共享进程的资源,如内存空间、文件描述符和打开的文件等。线程是在进程内部创建和管理的,它们共享相同的代码段和数据段,但拥有自己的栈空间和寄存器状态。线程之间可以并发执行,共享进程的资源,从而提高程序的并发性和执行效率。
与进程相比,线程的创建、销毁和切换开销较小,因为它们共享相同的执行环境。线程之间的通信和同步也比进程更方便和高效。然而,线程的共享资源也带来了线程安全性的问题,需要通过同步机制来保证数据的一致性和正确性。总结起来,进程是一个独立的执行单位,拥有自己的资源和执行环境,而线程是进程内部的执行单元,共享进程的资源,用于提高程序的并发性和执行效率。进程和线程是计算机系统中重要的并发执行概念,对于理解和设计多任务和并发程序非常重要。
Postgres 进程结构
[root@pcm tmp]# ps -auxf |grep postgres postgres 20000 0.0 0.1 284548 13804 ? Ss Mar06 0:03 /pgccc/bin/postgres -D /pgccc/pgdata postgres 20001 0.0 0.3 284804 25668 ? Ss Mar06 0:00 \_ postgres: checkpointer postgres 20002 0.0 0.0 284680 3488 ? Ss Mar06 0:01 \_ postgres: background writer postgres 20004 0.0 0.0 284680 5884 ? Ss Mar06 0:02 \_ postgres: walwriter postgres 20005 0.0 0.0 286160 2664 ? Ss Mar06 0:01 \_ postgres: autovacuum launcher postgres 20006 0.0 0.0 286144 2488 ? Ss Mar06 0:00 \_ postgres: logical replication launcher postgres 26954 0.0 0.0 286976 7252 ? Ss Mar07 0:00 \_ postgres: admin postgres [local] idle postgres 30426 0.0 0.0 286692 4964 ? Ss 16:06 0:00 \_ postgres: postgres postgres [local] idle [root@pcm tmp]#
Postgresql 是一个C/S架构的关系型数据库,由多个后台进程管理数据库。postgres server process 一个服务器端进程,是所有进程的父进程。该进程管理数据库文件,接受客户端与数据库的连接,且代表客户端对数据库进行操作。该进程的程序名叫做 postgres。
checkpointer 进程:检查点进程,辅助 background write 进行内存中脏数据块的写入,并且记录已经写入的脏块,从而保证下次只会写入新的脏块。
background writer 进程:数据写入进程,将共享内存中的脏数据块写入到磁盘上。
walwriter 进程:wal 日志写进程,修改的数据记录到 wal 日志中。
autovacuum launcher 进程:自动清理进程,自动清理被标记为删除状态的数据(自动清理 MVCC 多版本产生的死元组)。
logical replication launcher 进程:逻辑复制进程,订阅者通过 logical replication launcher 进程向发布者订阅表的更新并获取更新。
postgres 进程:postmaster 创建出的客户端连接子进程。
stats collector 进程:统计数据收集进程,主要作用就是数据的统计收集,比如在一个表上进行了多少次的插入、更新和删除操作,磁盘块的读写次数、行的读写次数等等。
PG15 对统计进行了重大改进。将stats collector进程优化掉了,不再将统计数据放入临时文件中,而是放到共享内存中,在shutdown前由checkpoint进程将其持久化,启动时由startup进程将其加载。减少了IO和进程间通信,从而改进性能。
内存结构
PostgreSQL中的内存架构可以分为两大类:
本地内存区 -由每个后端进程分配给自己使用。
共享内存区 -由PostgreSQL服务器的所有进程使用。
共享内存
共享内存区域由PostgreSQL服务器在启动时分配。这个区域也被划分为几个固定大小的子区域。PostgreSQL 启动后会生成一块共享内存,共享内存主要用作数据块的缓冲区,以便提高读写性能。WAL 日志缓冲区 和 CLOG(CommitLog)缓冲区也存在于共享内存中。除此以外,一些全局信息也保存在共享内存中,如进程信息、锁的信息、全局统计信息等,相关数据库参数如下:
shared_buffers:一个合理开始值是系统内存的 25%,设置的太大效果可能并不总是理想的,因为 PostgreSQL 同样依赖操作系统的高速缓冲区,默认值为 128MB。
WAL buffer:为了保证数据不因服务器故障而丢失,PostgreSQL支持WAL机制。WAL数据(也称为XLOG记录)是PostgreSQL中的事务日志。WAL缓冲区是WAL数据写入持久存储之前的缓冲区域。WAL缓冲区是WAL数据写入持久存储之前的缓冲区域。
commit log:提交日志(Commit Log, CLOG)保存所有事务的状态(例如in_progress、committed、aborted),用于并发控制(CC)机制。
本地内存
每个后端进程分配一个本地内存区用于查询处理。每个区域被划分为若干个子区域,子区域的大小是固定的或可变的。后台服务进程除访问共享内存以外,还会申请分配一些本地内存,以便暂存一些不需要全局存储的数据,相关数据库参数如下:
temp_buffers:为每个数据库会话设置用于临时缓冲区的最大内存,用于访问临时表的本地缓冲区,默认值为 8MB。
work_mem:设置在写入临时磁盘文件之前每个查询操作(排序或哈希表)可使用的基础最大内存容量,默认值是 4MB。
maintenance_work_mem:指定在维护性操作(例如VACUUM、CREATE INDEX和ALTER TABLE ADD FOREIGN KEY)中使用的最大的内存量,默认值是 64MB。
