在之前的博客,我们了解的PG的相关信息,如下:
PostgreSQL 学习笔记(1) — PG 概述
https://www.cndba.cn/dave/article/116370
PostgreSQL 学习笔记(2) — PG 版本发布策略 和 生命周期说明
https://www.cndba.cn/dave/article/116372
PostgreSQL 学习笔记(3) — PG 单实例安装手册
https://www.cndba.cn/dave/article/116374
PostgreSQL 学习笔记(4) — PG 启动 与 关闭
https://www.cndba.cn/dave/article/116375
PostgreSQL 学习笔记(5) — psql 工具使用说明
https://www.cndba.cn/dave/article/116376
PostgreSQL 学习笔记(6) — PG 参数管理
https://www.cndba.cn/dave/article/116377
PostgreSQL 学习笔记(7) — PG 数据库 基本操作
https://www.cndba.cn/dave/article/116379
PostgreSQL 学习笔记(8) — PG 模式 与 用户 管理
https://www.cndba.cn/dave/article/116380
本篇我们看下PG的进程和内存结构。
1 进程结构
PostgreSQL数据库启动时,会先启动一个叫Postmaster的主进程,还会fork 出一些辅助子进程,这些辅助子进程各自负责一部分功能。
[dave@www.cndba.cn ~]# pstree -ap |grep post |grep -v grep
|-postgres,3559 -D /var/lib/pgsql/14/data
| |-postgres,3564
| |-postgres,3566
| |-postgres,3567
| |-postgres,3568
| |-postgres,3569
| |-postgres,3570
| |-postgres,3571
| |-postgres,3688
| `-postgres,4031
| | `-su,3619 - postgres
| | `-su,3965 - postgres
[dave@www.cndba.cn ~]# ps -ef |grep postgres |grep -v grep
postgres 3559 1 0 05:02 ? 00:00:03 /usr/pgsql-14/bin/postgres -D /var/lib/pgsql/14/data
postgres 3564 3559 0 05:02 ? 00:00:00 postgres: logger
postgres 3566 3559 0 05:02 ? 00:00:00 postgres: checkpointer
postgres 3567 3559 0 05:02 ? 00:00:00 postgres: background writer
postgres 3568 3559 0 05:02 ? 00:00:00 postgres: walwriter
postgres 3569 3559 0 05:02 ? 00:00:02 postgres: autovacuum launcher
postgres 3570 3559 0 05:02 ? 00:00:05 postgres: stats collector
postgres 3571 3559 0 05:02 ? 00:00:00 postgres: logical replication launcher
root 3619 3537 0 21:54 pts/3 00:00:00 su - postgres
postgres 3621 3619 0 21:54 pts/3 00:00:00 -bash
postgres 3687 3621 0 21:54 pts/3 00:00:00 psql
postgres 3688 3559 0 21:54 ? 00:00:00 postgres: postgres postgres [local] idle
root 3965 3896 0 21:57 pts/4 00:00:00 su - postgres
postgres 3966 3965 0 21:57 pts/4 00:00:00 -bash
postgres 4030 3966 0 21:57 pts/4 00:00:00 psql
postgres 4031 3559 0 21:57 ? 00:00:00 postgres: postgres postgres [local] idle
[dave@www.cndba.cn ~]#
1.1 Postmaster 主进程
当PG数据库启动时,首先会启动Postmaster主进程。这个进程是PG数据库的总控制进程,负责启动和关闭数据库实例,默认就是5432。
实际上Postmaster进程是一个指向postgres命令的链接,如下:
[dave@www.cndba.cn ~]# ll /usr/pgsql-14/bin/postmaster
lrwxrwxrwx. 1 root root 8 Aug 8 09:41 /usr/pgsql-14/bin/postmaster -> postgres
[dave@www.cndba.cn ~]#
当用户和PG数据库建立连接时,要先与Postmaster进程建立连接,此时客户端进程会发送身份验证消息给Postmaster主进程,Postmaster主进程根据消息进行身份验证,验证通过后,Postmaster主进程会fork出一个会话服务进程为这个用户连接服务。可以通过pg_stat_activity表来查看服务进程的pid,如下:
postgres=# select pid,usename,client_addr,client_port from pg_stat_activity;
pid | usename | client_addr | client_port
------+----------+-------------+-------------
3571 | postgres | |
3569 | | |
3688 | postgres | | -1
4031 | postgres | | -1
3567 | | |
3566 | | |
3568 | | |
(7 rows)
postgres=#
客户端每创建一个数据库连接,postmaster就生成一个pstogres进程,是一种1:1的进程结构(一个客户端对应一个服务进程)。多进程比多线程的结构开销要大,进程的创建和回收比线程更加消耗资源,当用户发来的请求过多时,会造成负载过大,执行速度变慢。
1.2 BgWriter(后台写)进程
BgWriter进程是把共享内存中的脏页写到磁盘上的进程。它的作用有两个:
- 定期把脏数据从内存缓冲区刷出到磁盘中,减少查询时的阻塞;
- PG在定期作检查点时需要把所有脏页写出到磁盘,通过BgWriter预先写出一些脏页,可以减少设置检查点(CheckPoint)时要进行的IO操作,使系统的IO负载趋向平稳。
BgWriter是PostgreSQL 8.0以后新加的特性,它的机制可以通过postgresql.conf文件中以”bgwriter_”开头配置参数来控制:
[dave@www.cndba.cn data]# cat 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
[dave@www.cndba.cn data]#
参数说明如下:
1. bgwriter_delay:backgroud writer进程连续两次flush数据之间的时间的间隔。默认值是200,单位是毫秒。
2. bgwriter_lru_maxpages:backgroud writer进程每次写的最多数据量,默认值是100,单位buffers。如果脏数据量小于该数值时,写操作全部由backgroud writer进程完成;反之,大于该值时,大于的部分将有server process进程完成。设置该值为0时表示禁用backgroud writer写进程,完全有server process来完成;配置为-1时表示所有脏数据都由backgroud writer来完成。
3. bgwriter_lru_multiplier:这个参数表示每次往磁盘写数据块的数量,当然该值必须小于bgwriter_lru_maxpages。设置太小时需要写入的脏数据量大于每次写入的数据量,这样剩余需要写入磁盘的工作需要server process进程来完成,将会降低性能;值配置太大说明写入的脏数据量多于当时所需buffer的数量,方便了后面再次申请buffer工作,同时可能出现IO的浪费。该参数的默认值是2.0。bgwriter的最大数据量计算方式:1000/bgwriter_delaybgwriter_lru_maxpages8K=最大数据量
4. bgwriter_flush_after:数据页大小达到bgwriter_flush_after时触发BgWriter,默认是512KB。
1.3 PgArch(归档)进程
PgArch是把WAL日志进行归档,WAL日志会被循环使用,也就是说,过去的WAL日志会被新产生的日志覆盖,PgArch进程就是为了在覆盖前把WAL日志备份出来。归档日志的作用是为了数据库能够使用全量备份和备份后产生的归档日志,从而让数据库回到过去的任一时间点。
PgArch进程通过postgresql.conf文件中的如下参数进行配置:
[dave@www.cndba.cn data]# cat postgresql.conf|grep archive
#archive_mode = off # enables archiving; off, on, or always
#archive_command = '' # command to use to archive a logfile segment
# placeholders: %p = path of file to archive
# e.g. 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'
#archive_timeout = 0 # force a logfile segment switch after this
#restore_command = '' # command to use to restore an archived logfile segment
# e.g. 'cp /mnt/server/archivedir/%f %p'
#archive_cleanup_command = '' # command to execute at every restartpoint
#max_standby_archive_delay = 30s # max delay before canceling queries
# when reading WAL from archive;
You have new mail in /var/spool/mail/root
[dave@www.cndba.cn data]#
参数说明如下:
- archive_mode:表示是否进行归档操作,可选择为off(关闭)、on(启动)和always(总是开启),默认值为off(关闭)。
- archive_command:由管理员设置的用于归档WAL日志的命令。在用于归档的命令中,预定义变量“%p”用来指代需要归档的WAL全路径文件名,“%f”表示不带路径的文件名(这里的路径都是相对于当前工作目录的路径)。每个WAL段文件归档时将调用archive_command所指定的命令。当归档命令返回0时,PostgreSQL就会认为文件被成功归档,然后就会删除或循环使用该WAL段文件。否则,如果返回一个非零值,PostgreSQL会认为文件没有被成功归档,便会周期性地重试直到成功。
- archive_timeout:表示归档周期,在超过该参数设定的时间时强制切换WAL段,默认值为0(表示禁用该功能)。
1.4 PgStat(统计数据收集)进程
PgStat进程是PostgreSQL数据库的统计信息收集器,用来收集数据库运行期间的统计信息,如表的增删改次数,数据块的个数,索引的变化等等。收集统计信息主要是为了让优化器做出正确的判断,选择最佳的执行计划。
postgresql.conf文件中与PgStat进程相关的参数,如下:
# - Query and Index Statistics Collector -
#track_activities = on
#track_activity_query_size = 1024 # (change requires restart)
#track_counts = on
#track_io_timing = off
#track_wal_io_timing = off
#track_functions = none # none, pl, all
#stats_temp_directory = 'pg_stat_tmp'
相关参数:
- track_activities:表示是否对会话中当前执行的命令开启统计信息收集功能,该参数只对超级用户和会话所有者可见,默认值为on(开启)。
- track_activity_query_size:设置用于跟踪每一个活动会话的当前执行命令的字节数,默认值为1024,只能在数据库启动后设置。
- track_counts:表示是否对数据库活动开启统计信息收集功能,由于在AutoVacuum自动清理进程中选择清理的数据库时,需要数据库的统计信息,因此该参数默认值为on。
- track_io_timing:定时调用数据块I/O,默认是off,因为设置为开启状态会反复的调用数据库时间,这给数据库增加了很多开销。只有超级用户可以设置。
- track_functions:表示是否开启函数的调用次数和调用耗时统计。
- stats_temp_directory:统计信息的临时存储路径。路径可以是相对路径或者绝对路径,参数默认为pg_stat_tmp,设置此参数可以减少数据库的物理I/O,提高性能。此参数只能在postgresql.conf文件或者服务器命令行中修改。
1.5 AutoVacuum(自动清理)进程
在PG数据库中,对数据进行UPDATE或者DELETE操作后,数据库不会立即删除旧版本的数据,而是标记为删除状态。当事务提交后,旧版本的数据已经没有价值了,数据库需要清理垃圾数据腾出空间,而清理工作就是AutoVacuum进程进行的。
postgresql.conf文件中与AutoVacuum进程相关的参数有:
#------------------------------------------------------------------------------
# AUTOVACUUM
#------------------------------------------------------------------------------
#autovacuum = on # Enable autovacuum subprocess? 'on'
# requires track_counts to also be on.
#autovacuum_max_workers = 3 # max number of autovacuum subprocesses
# (change requires restart)
#autovacuum_naptime = 1min # time between autovacuum runs
#autovacuum_vacuum_threshold = 50 # min number of row updates before
# vacuum
#autovacuum_vacuum_insert_threshold = 1000 # min number of row inserts
# before vacuum; -1 disables insert
# vacuums
#autovacuum_analyze_threshold = 50 # min number of row updates before
# analyze
#autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum
#autovacuum_vacuum_insert_scale_factor = 0.2 # fraction of inserts over table
# size before insert vacuum
#autovacuum_analyze_scale_factor = 0.1 # fraction of table size before analyze
#autovacuum_freeze_max_age = 200000000 # maximum XID age before forced vacuum
# (change requires restart)
#autovacuum_multixact_freeze_max_age = 400000000 # maximum multixact age
# before forced vacuum
# (change requires restart)
#autovacuum_vacuum_cost_delay = 2ms # default vacuum cost delay for
# autovacuum, in milliseconds;
# -1 means use vacuum_cost_delay
#autovacuum_vacuum_cost_limit = -1 # default vacuum cost limit for
# autovacuum, -1 means use
# vacuum_cost_limit
相关参数说明:
- autovacuum:是否启动系统自动清理功能,默认值为on。
- log_autovacuum_min_duration:这个参数用来记录 autovacuum 的执行时间,当 autovaccum 的执行时间超过 log_autovacuum_min_duration参数设置时,则autovacuum信息记录到日志里,默认为 “-1”, 表示不记录。
- autovacuum_max_workers:设置系统自动清理工作进程的最大数量。
- autovacuum_naptime:设置两次系统自动清理操作之间的间隔时间。
- autovacuum_vacuum_threshold和autovacuum_analyze_threshold:设置当表上被更新的元组数的阈值超过这些阈值时分别需要执行vacuum和analyze。
- autovacuum_vacuum_scale_factor和autovacuum_analyze_scale_factor:设置表大小的缩放系数。
- autovacuum_freeze_max_age:设置需要强制对数据库进行清理的XID上限值。
- autovacuum_vacuum_cost_delay:当autovacuum进程即将执行时,对 vacuum 执行 cost 进行评估,如果超过 autovacuum_vacuum_cost_limit设置值时,则延迟,这个延迟的时间即为 autovacuum_vacuum_cost_delay。如果值为 -1, 表示使用 vacuum_cost_delay 值,默认值为 20 ms。
- autovacuum_vacuum_cost_limit:这个值为 autovacuum 进程的评估阀值, 默认为 -1, 表示使用 “vacuum_cost_limit “ 值,如果在执行 autovacuum 进程期间评估的cost 超过 autovacuum_vacuum_cost_limit, 则 autovacuum 进程则会休眠。
1.6 WalWriter(预写式日志写)进程
预写式日志WAL(Write Ahead Log,也称为Xlog),对数据文件的修改必须等这些修改已经记录到日志之后,也就是先写日志后写数据(日志先行)才能返回成功。使用这种机制可以避免数据频繁的写入磁盘,可以减少磁盘I/O。数据库在宕机重启后可以运用这些WAL日志来恢复数据库。
postgresql.conf文件中与WalWriter进程相关的参数如下:
#------------------------------------------------------------------------------
# WRITE-AHEAD LOG
#------------------------------------------------------------------------------
# - Settings -
#wal_level = replica # minimal, replica, or logical
# (change requires restart)
#fsync = on # flush data to disk for crash safety
# (turning this off can cause
# unrecoverable data corruption)
#synchronous_commit = on # synchronization level;
# off, local, remote_write, remote_apply, or on
#wal_sync_method = fsync # the default is the first option
# supported by the operating system:
# open_datasync
# fdatasync (default on Linux and FreeBSD)
# fsync
# fsync_writethrough
# open_sync
#full_page_writes = on # recover from partial page writes
#wal_log_hints = off # also do full page writes of non-critical updates
# (change requires restart)
#wal_compression = off # enable compression of full-page writes
#wal_init_zero = on # zero-fill new WAL files
#wal_recycle = on # recycle WAL files
#wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers
# (change requires restart)
#wal_writer_delay = 200ms # 1-10000 milliseconds
#wal_writer_flush_after = 1MB # measured in pages, 0 disables
#wal_skip_threshold = 2MB
#commit_delay = 0 # range 0-100000, in microseconds
#commit_siblings = 5 # range 1-1000
参数说明:
- wal_level:控制wal存储的级别。wal_level决定有多少信息被写入到WAL中。 默认值是最小的(minimal),其中只写入从崩溃或立即关机中恢复的所需信息。replica 增加 wal 归档信息 同时包括 只读服务器需要的信息。(9.6 中新增,将之前版本的 archive 和 hot_standby 合并),logical 主要用于logical decoding 场景
- fsync:该参数直接控制日志是否先写入磁盘。默认值是ON(先写入),表示更新数据写入磁盘时系统必须等待WAL的写入完成。可以配置该参数为OFF,表示更新数据写入磁盘完全不用等待WAL的写入完成。
- synchronous_commit:参数配置是否等待WAL完成后才返回给用户事务的状态信息。默认值是ON,表明必须等待WAL完成后才返回事务状态信息;配置成OFF能够更快地反馈回事务状态。
- wal_sync_method:WAL写入磁盘的控制方式,默认值是fsync,可选用值包括open_datasync、fdatasync、fsync_writethrough、fsync、open_sync。open_datasync和open_sync分别表示在打开WAL文件时使用O_DSYNC和O_SYNC标志;fdatasync和fsync分别表示在每次提交时调用fdatasync和fsync函数进行数据写入,两个函数都是把操作系统的磁盘缓存写回磁盘,但前者只写入文件的数据部分,而后者还会同步更新文件的属性;fsync_writethrough表示在每次提交并写回磁盘会保证操作系统磁盘缓存和内存中的内容一致。
- full_page_writes:表明是否将整个page写入WAL。
- wal_buffers:用于存放WAL数据的内存空间大小,系统默认值是64K,该参数还受wal_writer_delay、commit_delay两个参数的影响。
- wal_writer_delay:WalWriter进程的写间隔时间,默认值是200毫秒,如果时间过长可能造成WAL缓冲区的内存不足;时间过短将会引起WAL的不断写入,增加磁盘I/O负担。
- wal_writer_flush_after:
- commit_delay:表示一个已经提交的数据在WAL缓冲区中存放的时间,默认值是0毫秒,表示不用延迟;设置为非0值时事务执行commit后不会立即写入WAL中,而仍存放在WAL缓冲区中,等待WalWriter进程周期性地写入磁盘。
- commit_siblings:表示当一个事务发出提交请求时,如果数据库中正在执行的事务数量大于commit_siblings值,则该事务将等待一段时间(commit_delay的值);否则该事务则直接写入WAL。系统默认值是5,该参数还决定了commit_delay的有效性。
- wal_writer_flush_after:当脏数据超过阈值时,会被刷出到磁盘。
1.7 CheckPoint(检查点)进程
检查点是系统设置的事务序列点,设置检查点保证检查点前的日志信息刷到磁盘中。
postgresql.conf文件中与之相关的参数有:
# - Checkpoints -
#checkpoint_timeout = 5min # range 30s-1d
#checkpoint_completion_target = 0.9 # checkpoint target duration, 0.0 - 1.0
#checkpoint_flush_after = 256kB # measured in pages, 0 disables
#checkpoint_warning = 30s # 0 disables
max_wal_size = 1GB
min_wal_size = 80MB
1.8 SysLogger进程
日志信息是数据库管理员获取数据库系统运行状态的有效手段。在数据库出现故障时,日志信息是非常有用的。把数据库日志信息集中输出到一个位置将极大方便管理员维护数据库系统。然而,日志输出将产生大量数据(特别是在比较高的调试级别上),单文件保存时不利于日志文件的操作。因此,在SysLogger的配置选项中可以设置日志文件的大小,SysLogger会在日志文件达到指定的大小时关闭当前日志文件,产生新的日志文件。
在postgresql.conf里可以配置日志操作的相关参数:
# - Where to Log -
log_destination = 'stderr' # Valid values are combinations of
# stderr, csvlog, syslog, and eventlog,
# depending on platform. csvlog
# requires logging_collector to be on.
# This is used when logging to stderr:
logging_collector = on # Enable capturing of stderr and csvlog
# into log files. Required to be on for
# csvlogs.
# (change requires restart)
# These are only used if logging_collector is on:
log_directory = 'log' # directory where log files are written,
# can be absolute or relative to PGDATA
log_filename = 'postgresql-%a.log' # log file name pattern,
# can include strftime() escapes
#log_file_mode = 0600 # creation mode for log files,
# begin with 0 to use octal notation
主要参数说明:
- log_destination:配置日志输出目标,根据不同的运行平台会设置不同的值,Linux下默认为stderr。
- logging_collector:是否开启日志收集器,当设置为on时启动日志功能;否则,系统将不产生系统日志辅助进程。
- log_directory:配置日志输出文件夹。
- log_filename:配置日志文件名称命名规则。
- log_rotation_size:配置日志文件大小,当前日志文件达到这个大小时会被关闭,然后创建一个新的文件来作为当前日志文件。
2 内存结构
PostgreSQL的内存体系结构可以分为两大类:
- 本地内存(Local memory area):每个backend process分配使用
- 共享内存(Shared memory area):由PostgreSQL服务器的所有进程使用
2.1 本地内存: Local memory area
每个backend process分配一个本地内存区域用于查询处理;每个区域又分为几个子区域,子区域的大小可以是固定的,也可以是可变的。
由3部分组成:
- work_mem:内部排序操作和hash表在使用临时磁盘文件之前使用的内存缓冲区,对于并发,每个并发子进程都会分配;order by,distinct,merge join都要用到排序操作,hash表在以hash join,hash 为基础的聚集,以hash为基础的in子查询处理都会用到
- maintenance_work_mem:在维护性操作(如VACUUM,CREATE INDEX,ALTER TABLE ADD FOREIGN KEY 等),会使用到。
- temp_buffers:执行器使用此区域存储临时表
2.2 共享内存: Shared memory area
共享内存区域由PostgreSQL服务在启动时分配。这个区域也被划分为几个固定大小的子区域。
由3部分组成:
- shared buffer pool:PostgreSQL将表和索引中的页面从持久存储加载到这里,并直接操作它们。
- WAL buffer:为了保证数据不因服务器故障而丢失,PostgreSQL支持WAL机制。WAL data(也称XLOG records)是PostgreSQL中的事务日志;WAL buffer是WAL数据写入持久存储之前的缓冲区域。
- commit log:commit log(CLOG)保存所有事务(如in_progress,committed,aborted)的状态,用于并发控制(CC)机制。
除此之外,PostgreSQL还分配了如下几个区域:
- 用于各种访问控制机制的Sub-area。(例如,信号量、轻量级锁、共享锁和排他锁等)
- 用于各种后台进程的Sub-area,如checkpointer和autovacuum。
- 事务处理的Sub-area,比如保存点和两阶段提交。
- others
2.3 相关参数
在postgresql.conf里可以配置日志操作的相关参数:
# - Memory -
shared_buffers = 128MB # min 128kB
# (change requires restart)
#huge_pages = try # on, off, or try
# (change requires restart)
#huge_page_size = 0 # zero for system default
# (change requires restart)
#temp_buffers = 8MB # min 800kB
#max_prepared_transactions = 0 # zero disables the feature
# (change requires restart)
# Caution: it is not advisable to set max_prepared_transactions nonzero unless
# you actively intend to use prepared transactions.
#work_mem = 4MB # min 64kB
#hash_mem_multiplier = 1.0 # 1-1000.0 multiplier on hash table work_mem
#maintenance_work_mem = 64MB # min 1MB
#autovacuum_work_mem = -1 # min 1MB, or -1 to use maintenance_work_mem
#logical_decoding_work_mem = 64MB # min 64kB
#max_stack_depth = 2MB # min 100kB
#shared_memory_type = mmap # the default is the first option
# supported by the operating system:
# mmap
# sysv
# windows
# (change requires restart)
dynamic_shared_memory_type = posix # the default is the first option
# supported by the operating system:
# posix
# sysv
# windows
# mmap
# (change requires restart)
#min_dynamic_shared_memory = 0MB # (change requires restart)
版权声明:本文为博主原创文章,未经博主允许不得转载。