💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] # <span style="font-size:15px">**进程结构** </span> 从下面的体系结构图可以看出来,PG使用经典的C/S架构,进程架构。在服务器端有主进程、服务进程、子进程、共享内存以及文件存储几大部分。 ![](https://img.kancloud.cn/c5/62/c562e0e827a4220e61cdb6bfda0d1598_1292x590.png) ``` SIS3.0.60.0 ~ # ps aux | grep postgres daemon 8384 0.0 0.1 384180 21920 ? Ss Nov10 0:10 /home/fantom/party/pgsql/bin/postmaster -D /data/pgsql/ --config-file=/etc/postgresql-13/postgresql.base.conf daemon 8489 0.0 0.0 226608 1716 ? Ss Nov10 0:00 postgres: logger daemon 8607 0.0 0.3 384348 36544 ? Ss Nov10 0:00 postgres: checkpointer daemon 8608 0.0 0.0 384316 3972 ? Ss Nov10 0:01 postgres: background writer daemon 8609 0.0 0.0 384180 5920 ? Ss Nov10 0:02 postgres: walwriter daemon 8610 0.0 0.0 384912 2828 ? Ss Nov10 0:02 postgres: autovacuum launcher daemon 8611 0.0 0.0 229788 2488 ? Ss Nov10 0:07 postgres: stats collector daemon 8612 0.0 0.0 384724 2392 ? Ss Nov10 0:00 postgres: logical replication launcher ``` **postmaster** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当PG数据库启动时,首先会启动Postmaster主进程。这个进程是PG数据库的总控制进程,负责启动和关闭数据库实例。实际上Postmaster进程是一个指向postgres命令的链接。 ``` SIS3.0.60.0 ~ # ll /home/fantom/party/pgsql/bin/postmaster lrwxrwxrwx 1 daemon daemon 8 May 25 14:21 /home/fantom/party/pgsql/bin/postmaster -> postgres* ``` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当用户和PG数据库建立连接时,要先与Postmaster进程建立连接,此时客户端进程会发送身份验证消息给Postmaster主进程,Postmaster主进程根据消息进行身份验证,验证通过后,Postmaster主进程会fork出一个会话服务进程为这个用户连接服务。可以通过`pg_stat_activity`表来查看服务进程的pid ``` sip=# select pid,usename,client_addr,client_port from pg_stat_activity; pid | usename | client_addr | client_port --------+----------+-------------+------------- 43796 | sipadmin | 127.0.0.1 | 45431 25859 | sipadmin | 127.0.0.1 | 32942 23895 | sipadmin | 127.0.0.1 | 56456 ... (26 rows) ``` **background writer** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BgWriter进程是把共享内存中的脏页写到磁盘上的进程。它的作用有两个:一是定期把脏数据从内存缓冲区刷出到磁盘中,减少查询时的阻塞;二是PG在定期作检查点时需要把所有脏页写出到磁盘,通过BgWriter预先写出一些脏页,可以减少设置检查点(CheckPoint,数据库恢复技术的一种)时要进行的IO操作,使系统的IO负载趋向平稳。可以通过postgresql.conf文件中以"bgwriter\_"开头配置参数来控制 ``` [root@izwz91quxhnlkan8kjak5hz ~]# cat /www/server/data/postgres/postgresql.conf | grep bgwriter_ #bgwriter_delay = 200ms # 10-10000ms between rounds #bgwriter_lru_maxpages = 100 # max buffers written/round, 0 disables #bgwriter_lru_multiplier = 2.0 # 0-10.0 multiplier on buffers scanned/round #bgwriter_flush_after = 512kB # measured in pages, 0 disables ``` **logger** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logger系统日志进程通过postmaster进程、服务进程和其余辅助进程收集所有的stderr输出,并记录到日志文件中 ``` #logging_collector = off # 是否开启日志收集器,当设置为on时启动日志功能;否则,系统将不产生系统日志辅助进程。 # These are only used if logging_collector is on: #log_directory = 'log' # 输出日志目录 #log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' # 文件命名规则 #log_file_mode = 0600 # 日志文件的创建模式, #log_rotation_age = 1d # 自动轮转日志文件 #log_rotation_size = 10MB # 配置日志文件大小,当前日志文件达到这个大小时会被关闭,然后创建一个新的文件来作为当前日志文件 ``` **checkpointer** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;检查点是系统设置的事务序列点,设置检查点保证检查点前的日志信息刷到磁盘中。相关参数如下: ``` [root@izwz91quxhnlkan8kjak5hz ~]# cat /www/server/data/postgres/postgresql.conf | grep checkpoint #checkpoint_timeout = 5min # 生成检查点的最大的间隔时间 #checkpoint_completion_target = 0.5 # 参数表示checkpoint的完成目标,系统默认值是0.5,也就是说每个checkpoint需要在checkpoints间隔时间的50%内完成 #checkpoint_flush_after = 256kB # measured in pages, 0 disables #checkpoint_warning = 30s # 0 disables #log_checkpoints = off ``` **WalWriter** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;预写式日志WAL进程(Write Ahead Log,也称为Xlog),预写日志可以保证数据的完整性;在修改数据之前,数据库会将修改操作记录到磁盘中。这样就不必担心数据未持久化到磁盘导致数据丢失。如果数据库宕机,重启后数据库会读取WAL日志最后一部分重新执行,将数据库恢复为宕机时的状态。WAL日志保存在`$PGDATA/pg_wal`目录下(在postgresql10之前,是存储在pg_xlog目录下) **autovacuum launcher** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;自动垃圾回收进程。在PostgreSQL中,对数据进行UPDATE或者DELETE操作后,数据库不会立即删除旧版本的数据,而是标记为删除状态。当事务提交后,旧版本的数据已经没有价值了,数据库需要清理垃圾数据腾出空间,而清理工作就是AutoVacuum进程进行的。相关参数如下: ``` [root@izwz91quxhnlkan8kjak5hz postgres]# cat /www/server/data/postgres/postgresql.conf | grep autovacuum #autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem #autovacuum = on # 是否启动系统自动清理功能,默认值为on #log_autovacuum_min_duration = -1 # 在规定时长内未完成的vacuum予以记录日志,-1表示禁用,0表示所有的,大于0仅记录超过时间的 #autovacuum_max_workers = 3 # autovacuum最大线程数 #autovacuum_naptime = 1min # vacuum的间隔时间 #autovacuum_vacuum_threshold = 50 # 达到DML操作(增删改)的最小行数则vacuum #autovacuum_vacuum_insert_threshold = 1000 # 达到最小新增行数则vacuum #autovacuum_analyze_threshold = 50 # 激活自动analyze操作的最小行数,analyze有利于对SQL语句进行更精准的plan(这是由于explain用到的pg_class列reltuples and relpages are not updated on-the-fly) #autovacuum_vacuum_scale_factor = 0.2 # 表示autovacuum的vacuum操作所需的变更量阈值,当这个表的update/delete的tuple总数大于(pg_class.reltuples*autovacuum_vacuum_scale_factor+autovacuum_vacuum_threshold)时, 触发vacuum操作 #autovacuum_vacuum_insert_scale_factor = 0.2 # fraction of inserts over table #autovacuum_analyze_scale_factor = 0.1 # 表示autovacuum的analyze操作所需的变更量阈值,当这个表的INSERT/update/delete的tuple总数大于(pg_class.reltuples*autovacuum_analyze_scale_factor+autovacuum_analyze_threshold)时, 触发analyze操作 #autovacuum_freeze_max_age = 200000000 # 指定表上事务的最大年龄,默认为2亿,达到这个阀值将触发 autovacuum进程,从而避免 wraparound。 表上的事务年龄可以通过 pg\_class.relfrozenxid 查询 #autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age #autovacuum_vacuum_cost_delay = 2ms # 运行一次vacuum的时长,如果超过此值则休眠然后起来接着vacuum,当autovacuum进程即将执行时,对vacuum执行cost进行评估,如果超过autovacuum_vacuum_cost_limit的值时,则延迟,这个延迟的时间值即为改成的值. #autovacuum_vacuum_cost_limit = -1 # autovacuum进程的评估阀值,-1表示使用vacuum_cost_limit值,如果在执行 autovacuum进程期间评估的cost超过autovacuum_vacuum_cost_limit,则autovacuum进程则会休眠 ``` **stats collector** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;统计信息收集进程。 **logical replication launcher** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Logical Replication属于逻辑复制,适用于数据库实例的部分(单个数据库或者某些表)的复制,目前只支持表复制. # <span style="font-size:15px">**内存结构** </span> ![](https://img.kancloud.cn/da/e1/dae1dc15eb42f9e0e5ea906fac6910c4_875x513.png)