PostgreSQL之vacuum学习
文章目录
- 一、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学习相关推荐
- 新特性:postgresql的vacuum漫谈
关注我们,下载更多资源 刘伟 刘伟,云和恩墨软件开发部研究院研究员:前微博DBA,主要研究方向为开源数据库,分布式数据库,擅长自动化运维以及数据库内核研究. ◆◆前言◆◆ 即便是从数据库特性,SQL功 ...
- postgresql源码学习(49)—— MVCC⑤-cmin与cmax 同事务内的可见性判断
一. 难以理解的场景 postgresql源码学习(十九)-- MVCC④-可见性判断 HeapTupleSatisfiesMVCC函数_Hehuyi_In的博客-CSDN博客 在前篇的可见性判断中有 ...
- 也谈PostgreSQL的Vacuum机制及其最佳实践
点击▲关注 "数据和云" 给公众号标星置顶 更多精彩 第一时间直达 前几天,我们就如何对数据库,表进行合适的vacuum策略,对已有方法进行了总结,回顾 新特性:postgre ...
- PostgreSQL源码学习(1)--PG13代码结构
PostgreSQL源码学习(1)–PG13代码结构 PostgreSQL代码结构 Bootstrap:用于支持Bootstrap运行模式,该模式主要用来创建初始的模板数据库. Main:主程序模块, ...
- Postgresql之Vacuum和Vacuum full的区别
参考文章:Postgresql关于Vacuum的作用和操作方法,Vacuum full锁表并生成新的relfilenode_ITPUB博客 简单说明 在PostgreSQL中,一次行的UPDATE或D ...
- PostgreSQL源码学习(一)编译安装与GDB入门
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 PostgreSQL源码学习(一)编译安装与GDB入门 前言 一.安装PostgreSQL 1.获取源码 2.配置 3.编译 3.安装 ...
- postgresql源码学习(27)—— 事务日志⑦-日志落盘上层函数 XLogFlush
一. 预备知识 1. XLOG什么时候需要落盘 事务commit之前 log buffer被覆盖之前 后台进程定期落盘 2. 两个核心结构体 这两个结构体定义代码在xlog.c,它们在日志落盘过程中非 ...
- postgresql源码学习(51)—— 提交日志CLOG 原理 用途 管理函数
一. CLOG是什么 CLOG(commit log)记录事务的最终状态. 物理上,是$PGDATA/pg_xact目录下的一些文件 逻辑上,是一个数组,下标为事务id,值为事务最终状态 1. 事务最 ...
- postgresql源码学习(53)—— vacuum②-lazy vacuum之heap_vacuum_rel函数
一. table_relation_vacuum函数 1. 函数定义 前篇最后(https://blog.csdn.net/Hehuyi_In/article/details/128749517),我 ...
最新文章
- C C++中关于全局变量静态变量,extern,static,const的区别与总结
- mongoDB3.0.2 升级操作
- 关于substring的理解
- vue computed使用_vue computed正确使用方式
- ef mysql modelfirst_MySQL –EF edmx(Model First)– Sql Server table
- jeecg自定义datagrid封装列表分页数据显示自定义字段
- 数据结构之查找算法:B+树
- Spring Cloud Sleuth 原理简介和使用
- (09)System Verilog 队列示例
- 如何清除vsphere主机提示“此主机当前没有管理网络冗余”
- 从“制造”到“智造”,南高齿携手锐捷打造“智能工厂”
- 用户可以通过软件对计算机,用户可以通过____软件对计算机软、硬件资源进行管理。...
- extremeComponents资料
- 不需要手机号,怎样注册邮箱账号
- GAMS系列分享20—GAMS电力系统—目标函数增量线性化
- MotionEvent和TouchSlop
- 恭喜!公积金将按月提取!12月31日前,全面执行!
- echarts旭日图
- 菜鸟的数学建模之路(六):层次分析法
- 鸿蒙系统无缘华为手机,华为手机无缘鸿蒙系统!任正非隐藏锋芒,谷歌“逃过一劫”...