PG进程结构和内存结构
本文主要介绍PostgreSQL数据库(后文简称PG)进程结构和内存结构,物理结构将在后续继续整理分享。
上图描述了PG进程结构、内存结构和部分物理结构的内容。图中的内容包含了两个部分:
- PG启动时分配
- 应用访问时分配
PG启动时进程结构和内存结构
PG是一用户一进程的Client/Server的应用程序。在PG启动时会启动若干个进程,其中包括主进程和辅助进程。在详细介绍之前,我们先来做一个测试,以下是操作记录:
[postgres@CHENZX-DB01 ~]$ ps -ef|grep postgres
root 15592 15571 0 14:23 pts/1 00:00:00 su - postgres
postgres 15593 15592 0 14:23 pts/1 00:00:00 -bash
postgres 15684 15593 0 14:24 pts/1 00:00:00 ps -ef
postgres 15685 15593 0 14:24 pts/1 00:00:00 grep --color=auto postgres
[postgres@CHENZX-DB01 ~]$ pgtl start
server starting
[postgres@CHENZX-DB01 ~]$
[postgres@CHENZX-DB01 ~]$
[postgres@CHENZX-DB01 ~]$ ps -ef|grep postgres
root 15592 15571 0 14:23 pts/1 00:00:00 su - postgres
postgres 15593 15592 0 14:23 pts/1 00:00:00 -bash
postgres 15712 1 0 14:25 pts/1 00:00:00 /postgres/postgresql-9.6.11/bin/postgres -D /postgres/pgdata
postgres 15713 15712 0 14:25 ? 00:00:00 postgres: logger process
postgres 15715 15712 0 14:25 ? 00:00:00 postgres: checkpointer process
postgres 15716 15712 0 14:25 ? 00:00:00 postgres: writer process
postgres 15717 15712 0 14:25 ? 00:00:00 postgres: wal writer process
postgres 15718 15712 0 14:25 ? 00:00:00 postgres: autovacuum launcher process
postgres 15719 15712 0 14:25 ? 00:00:00 postgres: stats collector process
postgres 15736 15593 0 14:25 pts/1 00:00:00 ps -ef
postgres 15737 15593 0 14:25 pts/1 00:00:00 grep --color=auto postgres
[postgres@CHENZX-DB01 ~]$ kill -9 15712
[postgres@CHENZX-DB01 ~]$ ps -ef|grep postgres
root 15592 15571 0 14:23 pts/1 00:00:00 su - postgres
postgres 15593 15592 0 14:23 pts/1 00:00:00 -bash
postgres 16164 15593 0 14:32 pts/1 00:00:00 ps -ef
postgres 16165 15593 0 14:32 pts/1 00:00:00 grep --color=auto postgres
PG启动前后OS层面上一共多了7个进程,而进程15713、15715、15716、15717、15718和15719均是被进程15712拉起的。当进程15712被杀掉后,剩余6个进程均会停止。所以,进程15712是PG的主进程,它在这里的作用是数据库的启动和停止、管理与数据库运行相关的辅助进程。
这里有6个进程,究竟这6个进程是干啥用的呢?以下是具体介绍:
进程名 | 作用 |
---|---|
系统日志进程SysLogger | 通过从Postmaster进程、所有的服务进程及其他辅助进程收集所有的stderr输出,并将这些输出写入到日志文件中 |
后台写进程BgWriter | 将共享内存中的内容基于算法周期性的写入磁盘 如果太快:一个数据块可能会被修改很多次,太快的情况下,每修改一次都要写入磁盘中,是一个相当浪费资源和性能的过程 如果太慢:如果有新的查询或者更新等操作需要用内存保存从磁盘中读取数据,而此时内存却没有足够的空间,就需要把“脏数据”刷入磁盘来释放一部分内存。那么此时的查询或者更新操作就会发生“等待”,性能体验降低 |
归档进程PgArch | postgreSQL从8.x版本开始提出了PITR(Point-In-Time-Recovery)技术,支持将数据库恢复到其运行历史中任意一个有记录的时间点。除2.5.3节中所述的WalWriter外,PITR的另一个重要的基础就是对WAL文件的归档功能。PgArch辅助进程的目标就是对WAL日志在磁盘上的存储形式(Xlog文件)进行归档备份。 |
预写式日志写进程WalWriter | 写WAL日志的进程。预写式日志的概念就是在修改数据之前,必须要把这些修改操作记录到磁盘中,这样后面更新实际数据时,就不需要实时地把数据持久化到文件中了。即使机器突然宕机或数据库异常退出,导致一部分内存中的脏数据没有及时地刷新到文件中,在数据库重启后,通过读取WAL日志,并把最后一部分的WAL日志重新执行一遍,就可以恢复到宕机时的状态。 |
自动清理进程AutoVacuum | 在PostgreSQL数据库中,对表元组的UPDATE或DELETE操作并未立即删除旧版本的数据,表中的旧元组只是被标识为删除状态,并未立即释放空间。这种处理对于获取多版本并发控制是必要的,如果一个元组的版本仍有可能被其他事务看到,那么就不能删除元组的该版本。当事务提交后,过期元组版本将对事务不再有效,因而其占据的空间必须回收以供其他新元组使用,以避免对磁盘空间增长的无休止的需求,此时对数据库的清理工作通过运行VACUUM来实现。从PostgreSQL 8.1开始,PostgreSQL数据库引入一个额外的可选辅助进程AutoVacuum(系统自动清理进程),自动执行VACUUM和ANALYZE命令,回收被标识为删除状态记录的空间,更新表的统计信息。 |
统计数据收集进程PgStat | 做数据的统计收集工作 |
我们再启动PG,看看内存方面的内容:
[postgres@CHENZX-DB01 ~]$ pgtl start
server starting
[postgres@CHENZX-DB01 ~]$ ps -ef|grep postgres
root 15592 15571 0 14:23 pts/1 00:00:00 su - postgres
postgres 15593 15592 0 14:23 pts/1 00:00:00 -bash
postgres 16403 1 0 14:36 pts/1 00:00:00 /postgres/postgresql-9.6.11/bin/postgres -D /postgres/pgdata
postgres 16404 16403 0 14:36 ? 00:00:00 postgres: logger process
postgres 16406 16403 0 14:36 ? 00:00:00 postgres: checkpointer process
postgres 16407 16403 0 14:36 ? 00:00:00 postgres: writer process
postgres 16408 16403 0 14:36 ? 00:00:00 postgres: wal writer process
postgres 16409 16403 0 14:36 ? 00:00:00 postgres: autovacuum launcher process
postgres 16410 16403 0 14:36 ? 00:00:00 postgres: stats collector process
postgres 19276 15593 0 15:24 pts/1 00:00:00 ps -ef
postgres 19277 15593 0 15:24 pts/1 00:00:00 grep --color=auto postgres
[postgres@CHENZX-DB01 ~]$ ps aux --sort -rss|grep 16403
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
postgres 16403 0.0 2.1 319992 41268 pts/1 S 14:36 0:00 /postgres/postgresql-9.6.11/bin/postgres -D /postgres/pgdata
postgres 19299 0.0 0.0 112704 968 pts/1 S+ 15:24 0:00 grep --color=auto 16403
PG启动后,主进程会占用一部分的内存,这部分内存会共享给所有后端进程共同使用。这部分称之为共享内存,共享内存由三部分组成,分别是:
- Shared Buffer Pool:PG将表和索引中的页面从持久存储装载到这里,并直接操作它们
- WAL Buffer:WAL文件持久化之前的缓冲区
- CommitLog Buffer:PostgresSQL在CommitLog中保存事务的状态,并将这些状态保留在Shared Buffer Pool中,在整个事务过程中使用
应用访问时的进程结构和内存结构
我们在找一台安装了PG客户端的机器,进行远程登录的操作:
[postgres@CHENZX-DB02 bin]$ psql -h 192.168.1.61 -p 5432
psql (9.6.11)
Type "help" for help.
postgres=#
我们在PG服务器端查看一下进程:
[postgres@CHENZX-DB01 ~]$ ps -ef|grep postgres
root 15592 15571 0 14:23 pts/1 00:00:00 su - postgres
postgres 15593 15592 0 14:23 pts/1 00:00:00 -bash
postgres 16403 1 0 14:36 pts/1 00:00:00 /postgres/postgresql-9.6.11/bin/postgres -D /postgres/pgdata
postgres 16404 16403 0 14:36 ? 00:00:00 postgres: logger process
postgres 16406 16403 0 14:36 ? 00:00:00 postgres: checkpointer process
postgres 16407 16403 0 14:36 ? 00:00:00 postgres: writer process
postgres 16408 16403 0 14:36 ? 00:00:00 postgres: wal writer process
postgres 16409 16403 0 14:36 ? 00:00:00 postgres: autovacuum launcher process
postgres 16410 16403 0 14:36 ? 00:00:00 postgres: stats collector process
postgres 23120 16403 0 16:23 ? 00:00:00 postgres: postgres postgres 192.168.1.62(36106) idle ------>多了此进程
postgres 23136 15593 0 16:24 pts/1 00:00:00 ps -ef
postgres 23137 15593 0 16:24 pts/1 00:00:00 grep --color=auto postgres
除了数据库启动时那7个进程之外,多了一个由主进程fork出来的进程23120。我们再做一个测试,远程登录一个数据库中没有的用户。
[postgres@CHENZX-DB02 bin]$ psql -U chenzx -h 192.168.1.61 -p 5432
psql: FATAL: role "chenzx" does not exist
那服务器端的进程有无多呢?正常无连上数据库应该是无多的。
[postgres@CHENZX-DB01 ~]$ ps -ef|grep postgres
root 15592 15571 0 14:23 pts/1 00:00:00 su - postgres
postgres 15593 15592 0 14:23 pts/1 00:00:00 -bash
postgres 16403 1 0 14:36 pts/1 00:00:00 /postgres/postgresql-9.6.11/bin/postgres -D /postgres/pgdata
postgres 16404 16403 0 14:36 ? 00:00:00 postgres: logger process
postgres 16406 16403 0 14:36 ? 00:00:00 postgres: checkpointer process
postgres 16407 16403 0 14:36 ? 00:00:00 postgres: writer process
postgres 16408 16403 0 14:36 ? 00:00:00 postgres: wal writer process
postgres 16409 16403 0 14:36 ? 00:00:00 postgres: autovacuum launcher process
postgres 16410 16403 0 14:36 ? 00:00:00 postgres: stats collector process
postgres 28197 15593 0 17:45 pts/1 00:00:00 ps -ef
postgres 28198 15593 0 17:45 pts/1 00:00:00 grep --color=auto postgres
可以看到,服务器进程并没有比之前多,仍然是7个进程。可以看到,主进程在这里的作用是监听客户端连接、为每个客户端连接fork单独的postgres服务进程。
创建一个会话连接到PG,再查看这个进程使用内存的状况:
[postgres@CHENZX-DB01 ~]$ ps aux --sort -rss|grep 28572
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
postgres 28572 0.0 0.1 321604 2948 ? Ss 17:51 0:00 postgres: postgres postgres 192.168.1.62(36134) idle
可以看到在会话连接到数据库时,postgres进程会为每个进程查询等操作划分一部分内存,这部分内存我们称之为本地内存。本地内存由三部分组成:
- Temp_buffers:临时表相关操作会使用这部分内存
- work_mem:内部排序(order by,distinct)操作和Hash表在使用临时磁盘文件之前使用的内存缓冲区
- maintenance_work_mem:维护性操作中使用的内存缓冲区,如vacuum、create index和alter table add foreign key等
讨论了两个情景,基本把PG的进程结构和内存结构梳理了一遍。最后,结合上述的情景,对PG主进程的作用进行整理:
- 数据库启停
- 监听客户端连接
- 为每个客户端连接fork单独的postgres进程
- 当服务进程出错时进行修复
- 管理数据文件
- 管理与数据库运行相关的辅助进程
PG进程结构和内存结构的更多相关文章
- windows进程中的内存结构[转载]
在阅读本文之前,如果你连堆栈是什么多不知道的话,请先阅读文章后面的基础知识. 接触过编程的人都知道,高级语言都能通过变量名来访问内存中的数据.那么这些变量在内存中是如何存放的呢?程序又是如何使用这些变 ...
- windows进程中的内存结构(好多API,而且VC最聪明)
在阅读本文之前,如果你连堆栈是什么多不知道的话,请先阅读文章后面的基础知识. 接触过编程的人都知道,高级语言都能通过变量名来访问内存中的数据.那么这些变量在内存中是如何存放的呢?程序又是如何使用这 ...
- windows进程中的内存结构(缓冲溢出原理)
接触过编程的人都知道,高级语言都能通过变量名来访问内存中的数据.那么这些变量在内存中是如何存放的呢?程序又是如何使用这些变量的呢?下面就会对此进行深入的讨论.下文中的C语言代码如没有特别声明,默认都使 ...
- 从一道面试题深入了解java虚拟机内存结构
记得刚大学毕业时,为了应付面试,疯狂的在网上刷JAVA的面试题,很多都靠死记硬背.其中有道面试题,给我的印象非常之深刻,有个大厂的面试官,顺着这道题目,一直往下问,问到java虚拟机的知识,最后把我给 ...
- 浮点型 float和double类型的内存结构和精度问题
首先引用一个例子在java中可能你会遇到这样的问题: 例:0.99999999f==1f //true 0.9999999f==1f //false 这是超出精度造成的,为了知道为什么会造成这样的问题 ...
- JVM宏观认知&&内存结构
JVM宏观认知 1.什么是虚拟机? 虚拟机是一种软件. 可分为系统虚拟机(仿真物理机)和程序虚拟机(执行单个计算机程序,比如JVM). 2.什么是Java虚拟机(JVM)? JVM是一种将字节码转化为 ...
- 面试~jvm(JVM内存结构、类加载、双亲委派机制、对象分配,了解垃圾回收)
一.JVM内存结构 ▷ 谈及内存结构各个部分的数据交互过程:还可以再谈及生命周期.数据共享:是否GC.是否OOM 答:jvm 内存结构包括程序计数器.虚拟机栈.本地方法栈.堆.方法区:它是字节码运行时 ...
- [转]oracle学习入门系列之五内存结构、数据库结构、进程
原文地址:http://www.2cto.com/database/201505/399285.html 1 Oracle数据库结构 关于这个话题,网上一搜绝对一大把,更别提书籍上出现的了,还有很多大 ...
- Windows中进程的内存结构
基础知识: 栈是一种简单的数据结构,是一种只允许在其一端进行插入或删除的线性表.允许插入或删除操作的一端称为栈顶,另一端称为栈底,对栈的插入和删除操作被称为入栈和出栈. 有一组CPU指令可以实现对进程 ...
随机推荐
- 【Linux】安装Nginx
注:转自https://www.cnblogs.com/hdnav/p/7941165.html 安装所需环境 Nginx 是 C语言 开发,建议在 Linux 上运行,当然,也可以安装 Window ...
- c#解析json字符串处理(最清晰易懂的方法)
注:博客迁移到csdn,本文最新地址:https://blog.csdn.net/sajiazaici/article/details/77647625 以下为原文 本文是全网第二简单的方法,因为我女 ...
- CRM——起步
一.CRM简介 crm 客户关系管理软件 ( Customer Relationship Management ). 二.CRM起步 1.设计表结构和数据库迁移 from django.db impo ...
- Nginx管理(一)
一.Nginx介绍 Nginx (engine x) 是一个高性能的HTTP和反向代理服务,也是一个IMAP/POP3/SMTP服务. 1.Nginx历史和特性 Nginx是由伊戈尔·赛索耶夫为俄罗斯 ...
- JS的封装(JS插件的封装)
JS中类的概念类,实际上就是一个function,同时也是这个类的构造方法,new创建该类的实例,new出的对象有属性有方法.方法也是一种特殊的对象. 类的方法在构造方法中初始化实例的方法(就是在构造 ...
- Windows资源管理器对物理内存的描述
对每个进程的虚拟/物理内存使用描述: 1.硬错误/秒:在最后一分钟内每秒出现的平均硬页错误数 2.提交(KB):操作系统为内存保留的虚拟内存量,任务管理器中显示为:提交大小 3.工作集(KB):进程当 ...
- C/S与B/S架构的区别和优缺点
C/S 架构的概念 C/S是Client/Server,即客户端/服务器端架构,一种典型的两层架构. 客户端包含一个或多个在用户的电脑上运行的程序 服务器端有两种,一种是数据库服务器端,客户端通过数据 ...
- visual studio code配置项
// 通过将设置放入设置文件中来覆盖设置. { //-------- 编辑器配置 -------- // 控制字体系列. "editor.fontFamily": "Co ...
- OpenSUSE 内核编译教程 (kernel 2.6.x)
http://cn.opensuse.org/OpenSUSE_%E5%86%85%E6%A0%B8%E7%BC%96%E8%AF%91%E6%95%99%E7%A8%8B_(kernel_2.6.x ...
- C# 取整问题
关于C#里的取整问题,有向上和向下两种取整方式[1]向上取整a=1.2345string res = Math.Ceiling(Convert.ToDecimal(a)).ToString();str ...