进程和内存结构图
一、进程结构
(一) Postmaster主进程和服务进程
首先从postmaster(守护进程)说起。
postmaster进程的主要职责有:
❑ 数据库的启停。
❑ 监听客户端连接。
❑ 为每个客户端连接fork单独的postgres服务进程。
❑ 当服务进程出错时进行修复。
❑ 管理数据文件。
❑ 管理与数据库运行相关的辅助进程。
Postgres server process
执行启动数据库的时候启动该父进程
pg ctl start -D SPGDATA-I/tmp/logfile
启动其他进程分配内存
通常, Postgres服务器进程仅有一个监听端口,默认就是5432(MySQL3306)(Oracle 1521)
如果在一台服务器上运行多个 PostgreSQL数据库那么需要配置不同的监听端口(在一台服务器上安装多个 PostgreSQL实例,只能通过编译安装的方式)
当用户和PG数据库建立连接时,要先与Postmaster进程建立连接,此时客户端进程会发送身份验证消息给Postmaster主进程,Postmaster主进程根据消息进行身份验证,验证通过后,Postmaster主进程会fork出一个会话服务进程为这个用户连接服务。可以通过pg_stat_activity表来查看服务进程的pid,如下:
test=# select pid,usename,client_addr,client_port from pg_stat_activity;
pid | usename | client_addr | client_port
-------±---------±------------±------------
26402 | postgres | | -1
(1 row)
postgre=# select pid,usename,client_addr,client_port from pg_stat_activity;
pid | usename | client_addr | client_port
------+---------+-------------+-------------
2721 | postgre | |
2719 | | |
7718 | postgre | | -1
8905 | postgre | | -1
2717 | | |
2716 | | |
2718 | | |
(7 rows)
postgre=#
[postgre@yanwei ~]$ pstree -ap |grep post |grep -v grep
|-postgres,2713 -D /mydata/pgdata
| |-postgres,2714
| |-postgres,2716
| |-postgres,2717
| |-postgres,2718
| |-postgres,2719
| |-postgres,2720
| |-postgres,2721
| `-postgres,7718
| | `-su,7679 - postgre
| `-su,8847 - postgre
[postgre@yanwei ~]$
[postgre@yanwei ~]$ ps -ef |grep postgres |grep -v grep
postgre 2713 1 0 02:27 ? 00:00:00 /usr/local/pgsql10.2/bin/postgres -D /mydata/pgdata
postgre 2714 2713 0 02:27 ? 00:00:00 postgres: logger process
postgre 2716 2713 0 02:27 ? 00:00:00 postgres: checkpointer process
postgre 2717 2713 0 02:27 ? 00:00:00 postgres: writer process
postgre 2718 2713 0 02:27 ? 00:00:00 postgres: wal writer process
postgre 2719 2713 0 02:27 ? 00:00:00 postgres: autovacuum launcher process
postgre 2720 2713 0 02:27 ? 00:00:00 postgres: stats collector process
postgre 2721 2713 0 02:27 ? 00:00:00 postgres: bgworker: logical replication launcher
postgre 7718 2713 0 09:56 ? 00:00:00 postgres: postgre postgre [local] idle
[postgre@yanwei ~]$
(二) SysLogger 进程
SysLogger 辅助进程会通过 Postmaster 进程,所有的服务进程及其其他辅助进程收集所有的 stderr 输出,并将这些输出写入到日志文件中。
在SysLogger的配置选项中可以设置日志文件的大小,SysLogger会在日志文件达到指定的大小时关闭当前日志文件,产生新的日志文件。如果收到了装载配置文件的信号 (SIGHUP),就会检查配置文件中的配置参数log_directory和 log_fileanme与当前配置是否相同,如果不相同则会切换日志文件并使用新的置。
在postgresql.conf里可以配置日志操作的相关参数:
log_destination:配置日志输出目标,根据不同的运行平台会设置不同的值,Linux下默认为stderr。
logging_collector:是否开启日志收集器,当设置为on时启动日志功能;否则,系统将不产生系统日志辅助进程。
log_directory:配置日志输出文件夹。
log_filename:配置日志文件名称命名规则。
log_rotation_size:配置日志文件大小,当前日志文件达到这个大小时会被关闭,然后创建一个新的文件来作为当前日志文件。
log_statement: none | ddl | all,控制记录哪些 SQL 语句。默认是 none,ddl 是记录所有数据定义语句。
除了上面讲到的这几个配置外,还有其他就不一一描述了,有兴趣的话可以去看官方文档说明
(三) BgWriter 后台写进程介绍
在PostgreSQL中,BgWriter辅助进程是把共享内存中的脏页写到磁盘上的进程。当向数据库中插入或更新数据时,并不会马上把数据持久 化到数据文件中。这主要是为了提高插入、更新、删除数据的性能。
BgWriter辅助进程可周期性地把内存中的脏数据刷新到磁盘中,刷新频 率既不能太快,也不能太慢。如果一个数据块被改变了多次,而此时刷 新频率又太快,那么这些改变每次都会被保存到磁盘中,这会导致I/O 次数增多。在刷新频率太慢的情况下,若有新的查询或更新需要使用内 存来保存从磁盘中读取的数据块时,由于没有空闲空间来存储这些数据 块,就需要把内存腾出来,即先把一些内存中的脏页写到磁盘中,这样 就会导致查询或更新需要等更长的时间,自然就会降低性能。
上面提到的这些机制由以“bgwriter_”开头的配置参数来控制,后面的章节会详细介绍这些参数的作用。
(四) PgArch(归档)进程
类似于Oracle数据库的ARCH归档进程,不同的是ARCH是吧redo log进行归档,PgArch是把WAL日志进行归档。再深入点,WAL日志会被循环使用,也就是说,过去的WAL日志会被新产生的日志覆盖,PgArch进程就是为了在覆盖前把WAL日志备份出来。归档日志的作用是为了数据库能够使用全量备份和备份后产生的归档日志,从而让数据库回到过去的任一时间点。PG从8.X版本开始提供的PITR(Point-In-Time-Recovery)技术,就是运用的归档日志。
PgArch进程通过postgresql.conf文件中的如下参数进行配置:
archive_mode:OFF | ON | ALWAYS 表示是否进行归档操作
archive_command:由管理员设置的用于归档WAL日志的命令。
在用于归档的命令中,预定义变量“%p”用来指代需要归档的WAL全路径文件名,“%f”表示不带路径的文件名(这里的路径都是相对于当前工作目录的路径)。每个WAL段文件归档时将调用archive_command所指定的命令。当归档命令返回0时,PostgreSQL就会认为文件被成功归档,然后就会删除或循环使用该WAL段文件。否则,如果返回一个非零值,PostgreSQL会认为文件没有被成功归档,便会周期性地重试直到成功。
archive_timeout:
表示归档周期,在超过该参数设定的时间时强制切换WAL段,默认值为0(表示禁用该功能)。
(五) PgStat(统计数据收集)进程
PgStat进程是PostgreSQL数据库的统计信息收集器,用来收集数据库运行期间的统计信息,如表的增删改次数,数据块的个数,索引的变化等等。收集统计信息主要是为了让优化器做出正确的判断,选择最佳的执行计划。postgresql.conf文件中与PgStat进程相关的参数如下:
track_activities:表示是否对会话中当前执行的命令开启统计信息收集功能,该参数只对超级用户和会话所有者可见,默认值为on(开启)。
track_counts:表示是否对数据库活动开启统计信息收集功能,由于在AutoVacuum自动清理进程中选择清理的数据库时,需要数据库的统计信息,因此该参数默认值为on。
track_io_timing:定时调用数据块I/O,默认是off,因为设置为开启状态会反复的调用数据库时间,这给数据库增加了很多开销。只有超级用户可以设置
track_functions:none | pl | all 表示是否开启函数的调用次数和调用耗时统计。
track_activity_query_size:设置用于跟踪每一个活动会话的当前执行命令的字节数,默认值为1024,只能在数据库启动后设置。
stats_temp_directory:统计信息的临时存储路径。路径可以是相对路径或者绝对路径,参数默认为pg_stat_tmp,设置此参数可以减少数据库的物理I/O,提高性能。此参数只能在postgresql.conf文件或者服务器命令行中修改。
(六) AutoVacuum(自动清理)进程
在PG数据库中,对数据进行UPDATE或者DELETE操作后,数据库不会立即删除旧版本的数据,而是标记为删除状态。这是因为PG数据库具有多版本的机制,如果这些旧版本的数据正在被另外的事务打开,那么暂时保留他们是很有必要的。当事务提交后,旧版本的数据已经没有价值了,数据库需要清理垃圾数据腾出空间,而清理工作就是AutoVacuum进程进行的。postgresql.conf文件中与AutoVacuum进程相关的参数有:
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 进程则会休眠。
(七) WalWriter(预写式日志写)进程
预写式日志WAL(Write Ahead Log,也称为Xlog)的中心思想是对数据文件的修改必须是只能发生在这些修改已经记录到日志之后,也就是先写日志后写数据(日志先行)。使用这种机制可以避免数据频繁的写入磁盘,可以减少磁盘I/O。数据库在宕机重启后可以运用这些WAL日志来恢复数据库。postgresql.conf文件中与WalWriter进程相关的参数如下:
wal_level:控制wal存储的级别。
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:指定 WAL 编写器刷新 WAL 的频率(以卷为单位)
commit_delay:表示一个已经提交的数据在WAL缓冲区中存放的时间,默认值是0毫秒,表示不用延迟;设置为非0值时事务执行commit后不会立即写入WAL中,而仍存放在WAL缓冲区中,等待WalWriter进程周期性地写入磁盘。
commit_siblings:表示当一个事务发出提交请求时,如果数据库中正在执行的事务数量大于commit_siblings值,则该事务将等待一段时间(commit_delay的值);否则该事务则直接写入WAL。系统默认值是5,该参数还决定了commit_delay的有效性。
wal_writer_flush_after:当脏数据超过阈值时,会被刷出到磁盘。
(八) CheckPoint(检查点)进程
检查点是系统设置的事务序列点,设置检查点保证检查点前的日志信息刷到磁盘中。postgresql.conf文件中与之相关的参数有:
#checkpoint_timeout = 5min # range 30s-1d
#max_wal_size = 1GB
#min_wal_size = 80MB
#checkpoint_completion_target = 0.5 # checkpoint target duration, 0.0 - 1.0
#checkpoint_flush_after = 256kB # measured in pages, 0 disables
#checkpoint_warning = 30s # 0 disables
二、内存结构
在Postgresql中,内存大概被分为两块
Local memory area – 为每一个backend process 分配的内存
Shared memory area – PostgreSQL server 所有的backgroud process使用的内存
(一) Local memory area(进程内存/私有内存)
每一个后端进程都会分配一块local memory area, 每一块区域又分为三个子区域 ,见下表
(二) Shared memory area
这块区域在服务器启动的时候分配,这块区域也是分为好几个子区域,见下面介绍
另外,Postgresql还分配一些其他的内存区域:
为访问控制分配的子区域,比如轻量级锁,共享或者专有锁.
为其他backgroud process提供的子区域,比如检查点,vacuum.
为事物处理提供的子区域,比如事物中的保存点,和二阶段事物提交.
评论