文章目录

  • 一、vacuum的背景
    • 1.1 常见数据库MVCC实现对比
  • 二、vacuum工作机制
    • 2.1 vacuum
    • 2.2 autovacuum

我们常用的关系型数据库有MySQL、Oracle、SQL Server、PostgreSQL等…但是vacuum的概念只有PG数据库有,而且运维过PG数据库的工程师都应该对它很熟悉,vacuum是PG数据库非常关键的一个操作。那么PG数据库的vacuum是用来干什么的?为什么会有vacuum?

一、vacuum的背景

1.1 常见数据库MVCC实现对比

在了解vacuum之前,我们首先要了解数据库很关键的一个特性:多版本并发控制(MVCC),显而易见这个特性就是为了提高数据库并发而设计的,但是不同的数据库实现MVCC的使用了不同的方法:

  • 以Oracle、MySQL为例

    • 这两种数据库是通过undo日志来实现MVCC。
    • 当数据记录被DML修改,将修改前的数据记录在undo log中,客户端可以读取数据时,通过undo log指针进行回滚找到对应可见的版本。
    • 长事物、大事物会导致undo log暴涨,一定程度上会导致系统日志文件磁盘空间占用的暴涨。只有将事物提交/回滚,相关版本记录不再需要时,对应的版本数据才会被清理,undo系统文件空间才会把无效的版本空间进行释放,具体空间释放操作需要看数据库版本以及参数设置。
  • 以SQL Server为例
    • 它是通过tempdb数据库来实现的。
    • 当数据记录被DML修改,将旧版本数据写入tempdb进行存储,客户端读取数据时,可从通过指针找到tempdb数据库中对应可见的版本。
    • 长事物、大事物会导致tempdb空间暴涨,只有事物提交,相关版本记录不再需要时,才会将相关的版本记录进行释放,需要注意的是这部分磁盘空间消耗是没有释放给操作系统的,需要手动进行磁盘空间收缩。
  • 以PostgreSQL为例
    • 它是通过保留变更前的记录来实现MVCC的。
    • 当数据记录被DML修改,旧版本记录仍保留不变,仅仅需要修改相关记录的xmin、xmax属性,并新增写入变更后的版本记录数据。
    • 由于历史版本数据仍然保留在原表空间中,默认情况下autovacuum会按照一定的参数设置策略检测并进行一定的清理,但频繁的数据变极大可能导致旧版本数据空间来不及进行空间回收,从而导致表空间膨胀。

各MVCC实现方法的优缺点对比:

  • 通过undo log或者tempdb来进行旧版本存储的方式,有效的避免了表空间膨胀,相对于PG直接保留旧版本数据的方式,每次DML操作都需要额外的日志写入,存在一定的IO消耗(目前SSD盘存储下,感觉影响不会很大);
  • PG这种直接保留旧版本数据的方式,无需额外的日志写入的消耗,但是一定程度上会导致旧版本数据没有及时清理,导致表空间膨胀,影响该表数据的查询效率(扫描了不必要的数据页)

二、vacuum工作机制

2.1 vacuum

由于对表记录进行DML后,旧版本数据其实并没有真正的进行物理删除,而是继续保留且进行相应的记录打标,这些不在需要的旧版本记录称为dead tuple。
vacuum的作用就是回收表膨胀出现的dead tuple,将对应的表空间释放给数据库or操作系统。

1、命令格式

VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]where option can be one of:FULL [ boolean ]FREEZE [ boolean ]VERBOSE [ boolean ]ANALYZE [ boolean ]DISABLE_PAGE_SKIPPING [ boolean ]SKIP_LOCKED [ boolean ]INDEX_CLEANUP [ boolean ]TRUNCATE [ boolean ]PARALLEL integerand table_and_columns is:table_name [ ( column_name [, ...] ) ]

2、vacuum的几种关键变体

  • vacuum full : 执行期间需要获取对应表的独占锁,阻塞其他客户端的读写操作。该模式下会将对应表数据重新写入一个新的表空间文件,最后替换为新的表文件,这种方式下可以回收dead tuple空间并释放给操作系统。该操作执行消耗是比较大的,且耗时的。
  • vacuum freeze : 使用一种激进的方式冻结元祖,相当于把参数 vacuum_freeze_min_age 、 vacuum_freeze_table_age 设置为0。该模式下Full参数指定是多余的,该操作执行消耗同样是比较大的,且耗时的。
  • vacuum verbose : 执行期间不需要获取对应表的独占锁,允许其他客户端的并发读写操作。该模式下仅仅会将dead tuple空间进行回收并释放给数据库,并不会释放给操作系统,vacuum期间打印每张表详细的垃圾回收记录。
  • vacuum analyze : 执行期间不需要获取对应表的独占锁,允许其他客户端的并发读写操作,执行完毕vacuum后会再次执行analyza重新采集相关表的统计信息。该模式下仅仅会将dead tuple空间进行回收并释放给数据库,并不会释放给操作系统。

3、运维建议

  • vacuum_cost_delay :计算每个毫秒级别所允许消耗的最大IO,vacuum_cost_limit/vacuum_cost_dely。 默认vacuum_cost_delay为20毫秒。
  • vacuum_cost_page_hit :vacuum时,page在buffer中命中时,所花的代价。默认值为1。
  • vacuum_cost_page_miss:vacuum时,page不在buffer中,需要从磁盘中读入时的代价默认为10。
  • vacuum_cost_page_dirty:当vacuum时,修改了clean的page。这说明需要额外的IO去刷脏块到磁盘。默认值为20。
  • vacuum_cost_limit:当超过此值时,vacuum会sleep。默认值为200。

2.2 autovacuum

autovacuum为PG数据库中可以实现自动vacuum的一个守护进程,需要数据库将参数autovacuum参数打开。autovacuum会自动检测发生了大量DML操作的表对象,并对其进行垃圾回收和统计信息的重新采集,相当于手动执行 vacuum analyze 。

1、重点参数

  • autovacuum : 是否开启autovacuum守护进程,默认开启
  • log_autovacuum_min_duration : 指定autovacuum执行耗时超过该参数时,将对应操作记录到日志,-1表示禁用autovacuum的日志记录
  • autovacuum_max_workers : autovacuum可启动的最大worker数,默认为3
  • autovacuum_naptime : 指定两次autovacuum之间的时间延迟,默认为1min
  • autovacuum_vacuum_threshold 、autovacuum_vacuum_scale_factor : 指定一张表Delete、Update的tuple数超过 autovacuum_vacuum_scale_factor * table_size + autovacuum_vacuum_threshold 时,自动触发autovacuum。默认autovacuum_vacuum_threshold为50,autovacuum_vacuum_scale_factor为20
  • autovacuum_vacuum_insert_threshold 、 autovacuum_vacuum_insert_scale_factor : 指定一张表Insert的tuple数超过 autovacuum_vacuum_insert_scale_factor * table_size + autovacuum_vacuum_insert_threshold 时,自动触发autovacuum。默认autovacuum_vacuum_insert_threshold为50,autovacuum_vacuum_insert_scale_factor为20
  • autovacuum_analyze_threshold 、autovacuum_analyze_scale_factor : 指定一张表Insert、Delete、Update的tuple数超过 autovacuum_analyze_scale_factor * table_size + autovacuum_analyze_threshold 时,自动触发analyza操作。默认autovacuum_analyze_threshold为50,autovacuum_analyze_scale_factor为20
  • autovacuum_freeze_max_age : 为防止表中事物ID回卷,指定表的最大事物ID(pg_class.relfrozenxid),超过该参数值自动触发autovacuum,即使autovacuum参数设置为off
  • autovacuum_multixact_freeze_max_age : 为防止表中多个事物ID回卷,指定表的最大事物ID(pg_class.relminmxid),超过该参数值自动触发autovacuum,即使autovacuum参数设置为off
  • autovacuum_vacuum_cost_delay : 指定计算autovacuum的代价延迟值
  • autovacuum_vacuum_cost_limit : 指定autovacuum操作的代价限制值

2、工作原理

  • 当参数autovacuum设置为on时,数据库会启动一个autovacuum的守护进程,当满足触发条件时启动相关的autovacuum经常进行垃圾回收操作
  • 当表update,delete的tuples数量超过 autovacuum_vacuum_scale_factor * table_size + autovacuum_vacuum_threshold 时,自动触发autovacuum操作
  • 当表insert的tuples数量超过 autovacuum_vacuum_insert_scale_factor * table_size + autovacuum_vacuum_insert_threshold 时,自动触发autovacuum操作
  • 当表的insert,delete,update的tuple超过 autovacuum_analyze_scale_factor * table_size + autovacuum_analyze_threshold 时,自动触发analyza操作
  • 当表的最大事物ID超过autovacuum_freeze_max_age、autovacuum_multixact_freeze_max_age 时,自动触发autovacuum操作
  • 默认两次autovacuum之前的时间间隔为autovacuum_naptime,且每次进行autovacuum时可启动的最大并发数为autovacuum_max_workers

3、运维建议

  • 全局参数并不一定适用于所有表,特殊表可在表级别定义相关参数。例如变更频繁的表,可适当减少autovacuum_vacuum_scale_factor、autovacuum_vacuum_threshold参数值,使得其可以及时的垃圾回收,避免表膨胀影响其查询效率
  • autovacuum_max_workers可根据操作系统CPU资源进行适当调整

PostgreSQL之vacuum学习相关推荐

  1. 新特性:postgresql的vacuum漫谈

    关注我们,下载更多资源 刘伟 刘伟,云和恩墨软件开发部研究院研究员:前微博DBA,主要研究方向为开源数据库,分布式数据库,擅长自动化运维以及数据库内核研究. ◆◆前言◆◆ 即便是从数据库特性,SQL功 ...

  2. postgresql源码学习(49)—— MVCC⑤-cmin与cmax 同事务内的可见性判断

    一. 难以理解的场景 postgresql源码学习(十九)-- MVCC④-可见性判断 HeapTupleSatisfiesMVCC函数_Hehuyi_In的博客-CSDN博客 在前篇的可见性判断中有 ...

  3. 也谈PostgreSQL的Vacuum机制及其最佳实践

    点击▲关注 "数据和云"   给公众号标星置顶 更多精彩 第一时间直达 前几天,我们就如何对数据库,表进行合适的vacuum策略,对已有方法进行了总结,回顾 新特性:postgre ...

  4. PostgreSQL源码学习(1)--PG13代码结构

    PostgreSQL源码学习(1)–PG13代码结构 PostgreSQL代码结构 Bootstrap:用于支持Bootstrap运行模式,该模式主要用来创建初始的模板数据库. Main:主程序模块, ...

  5. Postgresql之Vacuum和Vacuum full的区别

    参考文章:Postgresql关于Vacuum的作用和操作方法,Vacuum full锁表并生成新的relfilenode_ITPUB博客 简单说明 在PostgreSQL中,一次行的UPDATE或D ...

  6. PostgreSQL源码学习(一)编译安装与GDB入门

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 PostgreSQL源码学习(一)编译安装与GDB入门 前言 一.安装PostgreSQL 1.获取源码 2.配置 3.编译 3.安装 ...

  7. postgresql源码学习(27)—— 事务日志⑦-日志落盘上层函数 XLogFlush

    一. 预备知识 1. XLOG什么时候需要落盘 事务commit之前 log buffer被覆盖之前 后台进程定期落盘 2. 两个核心结构体 这两个结构体定义代码在xlog.c,它们在日志落盘过程中非 ...

  8. postgresql源码学习(51)—— 提交日志CLOG 原理 用途 管理函数

    一. CLOG是什么 CLOG(commit log)记录事务的最终状态. 物理上,是$PGDATA/pg_xact目录下的一些文件 逻辑上,是一个数组,下标为事务id,值为事务最终状态 1. 事务最 ...

  9. postgresql源码学习(53)—— vacuum②-lazy vacuum之heap_vacuum_rel函数

    一. table_relation_vacuum函数 1. 函数定义 前篇最后(https://blog.csdn.net/Hehuyi_In/article/details/128749517),我 ...

最新文章

  1. C C++中关于全局变量静态变量,extern,static,const的区别与总结
  2. mongoDB3.0.2 升级操作
  3. 关于substring的理解
  4. vue computed使用_vue computed正确使用方式
  5. ef mysql modelfirst_MySQL –EF edmx(Model First)– Sql Server table
  6. jeecg自定义datagrid封装列表分页数据显示自定义字段
  7. 数据结构之查找算法:B+树
  8. Spring Cloud Sleuth 原理简介和使用
  9. (09)System Verilog 队列示例
  10. 如何清除vsphere主机提示“此主机当前没有管理网络冗余”
  11. 从“制造”到“智造”,南高齿携手锐捷打造“智能工厂”
  12. 用户可以通过软件对计算机,用户可以通过____软件对计算机软、硬件资源进行管理。...
  13. extremeComponents资料
  14. 不需要手机号,怎样注册邮箱账号
  15. GAMS系列分享20—GAMS电力系统—目标函数增量线性化
  16. MotionEvent和TouchSlop
  17. 恭喜!公积金将按月提取!12月31日前,全面执行!
  18. echarts旭日图
  19. 菜鸟的数学建模之路(六):层次分析法
  20. 鸿蒙系统无缘华为手机,华为手机无缘鸿蒙系统!任正非隐藏锋芒,谷歌“逃过一劫”...

热门文章

  1. prism 视图发现
  2. 基于java的水费管理系统
  3. linux下创建、删除文件夹
  4. 银河麒麟常见问题汇总
  5. 国外可以免费发布供求信息的网站(转)
  6. 什么蓝牙耳机好看?2022高颜值蓝牙耳机排行榜
  7. itext设置表格的单元格的默认高度
  8. 微信小程序实现录音格式为mp3,并上传到云开发环境
  9. IIS上解决ASP.Net第一次访问慢的处理
  10. unity重定向_Unity 骨骼动画的运行时重定向