2.5.5  AutoVacuum系统自动清理进程

在PostgreSQL数据库中,对表元组的UPDATE或DELETE操作并未立即删除旧版本的数据,表中的旧元组只是被标识为删除状态,并未立即释放空间。这种处理对于获取多版本并发控制是必要的,如果一个元组的版本仍有可能被其他事务看到,那么就不能删除元组的该版本。当事务提交后,过期元组版本将对事务不再有效,因而其占据的空间必须回收以供其他新元组使用,以避免对磁盘空间增长的无休止的需求,此时对数据库的清理工作通过运行VACUUM来实现。从PostgreSQL 8.1开始,PostgreSQL数据库引入一个额外的可选辅助进程AutoVacuum(系统自动清理进程),自动执行VACUUM和ANALYZE命令,回收被标识为删除状态记录的空间,更新表的统计信息。

在PostgreSQL数据库系统配置文件中,与系统自动清理相关的主要相关参数如下:

autovacuum:是否启动系统自动清理功能,默认值为on。

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系统自动清理进程中包含两种不同的处理进程:AutoVacuum Launcher和AutoVacuum Worker。AutoVacuum Launcher进程为监控进程,用于收集数据库运行信息,根据数据库选择规则选中一个数据库,并调度一个AutoVacuum Worker进程执行清理操作。在AutoVacuum Launcher进程中,选择数据库的规则如下:首先由于数据库事务XID是32位整数且递增分配,当超过最大值时会从头开始计数使用,而事务XID的大小表示事务开始的时间,事务XID重新计数使用会使数据库中部分事务数据丢失,因此当XID超过配置的autovacuum_freeze_max_age时,强制对该数据库进行清理并更新事务XID;其次,若无强制清理操作,则选择数据库列表中最早未执行过自动清理操作的数据库。Launcher进程会定时(或者被信号驱动)选择数据库并调度Worker进程去执行清理工作。

AutoVacuum中的AutoVacuum Worker进程执行实际的清理任务,Launcher进程中维护有Worker进程列表。Worker进程列表由三种不同状态的进程列表构成,即空闲的Worker进程列表、正在启动的Worker进程、运行中的Worker进程列表。Launcher进程在不同状态之间的切换实现了Worker进程的调度工作。首先,在初始化阶段创建的运行内存上下文中,创建长度为autovacuum_max_workers的空闲Worker进程描述信息列表,而正在启动Worker进程和运行中的Worker进程的列表被置为空。如果Launcher进程需要一个Worker进程,空闲Worker进程列表不为空且当前没有正在启动中的Worker进程,则开始一个启动Worker进程的操作,即向Postmaster进程发送启动消息,从空闲Worker进程列表中取出一个进程描述信息,设置为启动中状态。Launcher进程中只允许存在一个启动中状态的Worker进程,启动中的Worker进程如果超时(超时时间由autovacuum_naptime设置)将被取消并重新开始启动Worker进程的循环。如果Worker启动成功,将启动成功的Worker进程信息添加到运行中的Worker进程列表中。运行中的Worker进程即连接上根据规则选中的数据库。

在启动成功的Worker进程连接数据库成功后,将遍历该数据库中的表,根据对表的清理规则选择要执行的表和在该表上执行的操作。对表的操作分为VACUUM和ANALYZE两种,对选中的表如果上次VACUUM之后的过期元组的数量超过了“清理阈值”(vacuum threshold),那么就清理该表,清理阈值是定义为:

清理阈值=清理基本阈值+清理缩放系数 *元组数

这里的清理基本阈值是autovacuum_vacuum_threshold,清理的缩放系数是autovacuum_vacuum_scale_factor,元组的数目可以从统计收集器里面获取。这是一个部分精确的计数,由每次UPDATE和DELETE操作更新。

如果表上次被执行ANALYZE操作之后,其中过期元组的数量超过了“分析阈值”(analyze threshold),那么就分析该表更新表统计信息,分析阈值的定义与清理阈值相似,定义如下:

分析阈值=分析基本阈值+分析缩放系数 *元组数目

缺省的阈值和伸缩系数都是从postgresql.conf里面取得的。不过,我们可以以每个表独立设置的方式覆盖它,方法就是在系统表pg_autovacuum里输入信息。pg_autovacuum表中一个元组可以用来记录一个需要自动清理的表及其清理设置,AutoVacuum进程将使用其中的清理设置来清理该表。如果没有特别设置该表的清理设置,AutoVacuum将使用全局设置。

1.AutoVacuum Launcher进程

通常,在入口函数StartAutoVacLauncher中执行fork操作创建Postmaster的子进程AutoVacuum Launcher,在新创建的子进程执行体中关闭从Postmaster进程中复制出的网络连接端口,同时进入进程AutoVacuum Launcher的执行体函数AutoVacLauncherMain,其处理流程如图2-12所示。

图2-12  AutoVacuum Launcher处理流程

下面对其中几个重要的步骤进行说明:

1)构建数据库列表:调用函数rebuild_database_list完成,其步骤如下:

①建立一个Hash表,其中每一个元素代表一个数据库,记录了该数据库的OID(adl_datid)、启动worker的时间戳(adl_next_worker)以及一个评分值(adl_score)。初始时该Hash表中没有元素。

②将pg_database平面文件(在PGDATA/global目录下)中的数据库构成一个链表,链表中的每一个节点代表一个数据库,其中包括数据库的OID、名称、该数据库的统计信息等。

③调用pgstat_fetch_stat_dbentry来填充每个节点的统计信息。

④对每一个统计信息不为空的数据库,在Hash表中搜索该数据库,如果没有找到则将该数据库加入到Hash表中,并且将该数据库的adl_score设置为该数据库被加入到Hash表中时的顺序号。

⑤将Hash表中的数据库按照adl_score值升序的顺序依次加入到全局变量DatabaseList所指向的链表中,并设置每一个数据库的adl_next_worker值。其中第一个数据库的adl_next_worker值设为当前时间,之后的每一个数据库的adl_next_worker的值都比前一个增加millis_increment。millis_increment的值由autovacuum_naptime参数值除以Hash表中数据库的个数来设定。

为什么使用平面文件?

在PostgreSQL的数据集簇中,提供了两个平面文件:pg_database和pg_auth。这两个文件分别记录了pg_database系统表和pg_authid系统表中的部分信息。如果有些还没有启动完毕的后台进程需要访问这两个系统表的内容,它们将会使用两个平面文件来进行信息的获取,这是由于进程还未完全启动时是无法连接到数据库并读取相关系统表内容的。

在“构建数据库列表”这一步骤由于并未连接到数据库,因此只能用平面文件来替代系统表pg_database。

2)设置进程休眠时间:根据空闲Worker和数据库列表来计算休眠的时间,当所有Worker进程都在运行时要设置一个较长的休眠时间。而当Worker进程退出时可以唤醒休眠,同时休眠也可以被其他信号中断。

3)信号处理分支中got_SIGUSR1信号通知有Worker进程退出或者Postmaster通知有Worker启动失败。若是Postmaster通知Worker启动失败,则给Postmaster重新发送启动Worker进程的消息。

4)启动Worker进程:如果当前有一个Worker正在启动中,则再休眠一会儿等待该Worker启动完成。如果可以开始启动一个新的Worker,则进行以下判断:

①如果数据库列表不为空,则检查DatabaseList尾部数据库的adl_next_worker参数,如果早于当前时间(表示该数据库早就应该被处理)则启动Worker进程。

②数据库列表为空时,立即启动Worker进程。

2.AutoVacuum Worker进程

AutoVacuum Worker进程的入口为launch_worker函数,在该入口处调用do_start_worker创建worker进程,并且返回连接数据库的OID。如果返回的OID为有效的数据库OID,则遍历数据库列表找到该OID对应的数据库在数据库列表中对应的节点,更新该节点的adl_next_worker域值,并将该节点移动到数据库列表的头部。如果遍历数据库列表没有对应于该OID的节点,则调用rebuild_database_list重建数据库列表。创建worker进程的函数体do_start_worker处理流程如图2-13所示。

图2-13  AutoVacuum Worker进程处理流程

AutoVacuum Worker进程的处理流程和AutoVacuum Launcher进程的处理流程基本类似,选择要进行清理的数据库的规则如前所述:选中数据库后遍历数据库中的表,根据表的统计信息计算清理阈值和分析阈值,来确定是否要对表执行相应的操作。

在系统进行自动清理的同时,用户可以使用安装目录bin文件夹下的vacuumdb或者vacuumlo工具对数据进行手动清理工作。vacuumdb工具清理数据库并对数据库执行分析操作,vacuumlo工具清理数据库中无效的大对象。

pg 定时删除_postgresql AutoVacuum系统自动清理进程相关推荐

  1. pg 定时删除_PostgreSQL的时间函数使用整理

    PG的时间函数使用整理如下 1.获取系统时间函数 ~~~ select now(); --2012-05-12 18:51:59.562+08 select current_timestamp; -- ...

  2. linux系统自动清理日志实现脚本

    1.删除文件命令:find  对应目录  命令选项 实例命令 find /export/Logs/ -type f -name "*log*" -mtime +3 -exec rm ...

  3. wps临时文件不自动删除_电脑:让 Windows 10 系统自动清理临时文件

    不少朋友在系统用久了以后,都会用一些软件来帮忙清理系统中没用的文件,其中包括一些临时文件.无用文件等. 但其实在 Windows 10 中,系统已经内置了自动定期清理临时文件的功能了.你还不知道?跟着 ...

  4. pg 定时删除_定时删除网站文件

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  5. php定时删除文件夹下文件(清理缓存文件)

    <?php ignore_user_abort(); //客户端断开时,可以让脚本继续在后台执行 set_time_limit(0); //忽略php.ini设置的脚本运行时间限制 $inter ...

  6. 所有的service报红但不报错_从一个应用报错来看centos系统的/tmp目录自动清理规则...

    概述 分享最近应用碰到的一个奇怪bug,一开始以为是代码上的问题,找了一段时间发现居然是因为系统的一个自动清理规则导致,下面一起来看看吧~ 一.应用报错: logwire.core.exception ...

  7. tmp ubuntu 自动删除吗_ubuntu 自动清理/tmp目录

    在Ubuntu系统中,在/tmp文件夹里面的内容,每次开机都会被清空,如果不想让他自动清理的话,只需要更改rcS文件中的TMPTIME的值. 我们看如何来修改 sudo vi /etc/default ...

  8. postgresql autovaccum自动清理

    为什么要开启autovaccum 在Postgresql做delete操作时,数据集(也叫做元组 (tuples))是没有立即从数据文件中移除的,仅仅是通过在行头部设置xmax做一个删除标记. upd ...

  9. centos7 tmp目录 自动清理规则

    CentOS6以下系统(含)使用watchtmp + cron来实现定时清理临时文件的效果,这点在CentOS7发生了变化,在CentOS7下,系统使用systemd管理易变与临时文件,与之相关的系统 ...

最新文章

  1. 《数学之美》第7章 贾里尼克和现代语言处理
  2. 计算机表格计算总积分,Excel函数教程: 根据条件计算成绩表-excel技巧-电脑技巧收藏家...
  3. Yii框架控制台报错: The id configuration for the Application is required
  4. AppVerifier的功能和原理
  5. 开启 JM 的 trace 功能
  6. oracle rac实例切换,RAC+单实例DG的切换
  7. php 打印 trace,php xdebug trace 调试的问题
  8. python在线编辑器可视化_python软件——wxpython可视化编辑器 v4.1附使用教程
  9. 怎么python安装mysql库_python在windows上怎么安装mysql数据库
  10. axure如何导出原件_Axure 教程:轻松导出图标字体所有图标
  11. 基于Golang 的后台管理系统框架
  12. 软件测试员工作经验分享
  13. vi毕业设计参考文献优秀范例
  14. win10鼠标右键一直转圈怎么解决 鼠标右键一直转圈
  15. 如何计算文件MD5 sha1 -- 微软MD5/SHA1 校验工具 Microsoft File Checksum Integrity Verifier
  16. 计算机打音乐歌谱成都,赵雷成都的曲谱
  17. postgresql获取基于当前时间计算的当月第一天,最后一天,下个月的第n天等功能
  18. 软件设计师知识点100条(21~40)
  19. 鸿蒙智联生态产品《接入智慧生活App开发指导》(官方更新版)
  20. 激发波长近红外二区发光量子点,近红外二区(NIR-II)发射波长(1000-1700 nm)

热门文章

  1. 利用Gitee搭建个人图床(下)
  2. 漏洞learning[安全大事记]
  3. elixir开发的项目_我对Elixir的介绍:学习另一种编程语言如何使您成为更好的开发人员...
  4. 云南省高中计算机学业水平考试,云南省高中计算机学业水平考试技巧
  5. 基于图神经网络的节点表征学习
  6. Hive UDF 中使用hdfs中的文件
  7. sublimText3在ubuntu下的中文支持
  8. AlexNet层级分析(涉及:卷积核操作下下层网络特征图size计算;对通道和卷积核尺寸及通道前层feature map和卷积核的运算关系的解释)
  9. ASP.NET获取真正的客户端IP地址的6种方法
  10. 虚拟网关与正规网关的区别