postgresql vacuum流程分析

概述

VACUUM是postgresql MVCC机制不可分割的组成部分。

postgresql在管理同一个元组的多个版本时,采取在堆表页面上从老版本到新版本放置元组的方法,每个元组都记录了xmax和xmin用于判断其可见性。这样的好处是(1)在索引键没有更新时,btree始终指向最老的元组,更新非索引键的数据无需更新btree中的指针(2)回滚的事务时无需专门进行undo(对比MySQL有专门的回滚段,如果发生了事务回滚时需要从回滚段中把上个版本的数据还原出来的)。但是这也带来了垃圾元组(即对任何事务都不可见的元组)的回收开销,以释放堆表页面上的控件。这一回收动作正是由VACUUM执行的。

在postgresql中,当使用delete删除一行数据后,或者使用update更新一行数据后(未更新主键),老元组物理上并没有删除,只是被标记了xmax。需要通过VACUUM来完成物理上的删除。

VACUUM的几种不同形式

用户可见的vacuum命令有两个,一个是vacuum,另一个是vacuum full。其中vacuum full实质上是把表进行了重建,或者说重新聚簇,在vacuum full的过程中会占有表的8级锁,不允许在vacuum full的时候对表进行其它操作。与之不同的是,vacuum时只会持有表的4级锁,在vacuum的同时还可以继续对表进行查询、删除和更新。
本篇文章主要分析vacuum的流程,vacuum full的流程后面有机会再分析。

VACUUM的总体流程

用户下发VACUUM命令后,postgresql会调用table_relation_vacuum()函数来进行处理,table_relation_vacuum是个抽象方法,对于最常见的堆表来说,其对应的具体方法时heap_vacuum_rel。总的来说,heap_vacuum_rel包括三步:
(1)基于一个快照扫描堆表,确定哪些元组已经死亡,可以被删除
(2)基于上述死亡的元组扫描索引,并删除(或更新?)索引中的对应条目,如果发现某个索引页面中的内容全部被删除,则尝试(哪些场景下无法释放)释放该页面,在释放btree索引页面时,需要同步修改parent页面
(3)在删除完索引后,再删除堆表上已死亡的元组

之所以要先删除索引再删除堆表,是因为相反的顺序可能导致索引指向的元组无效(被删除了),会导致无法恢复的错误。

VACUUM流程图

在这里插入图片描述

备注

pg中btree页面的几种状态

// https://github.com/postgres/postgres/blob/c9c0589fda0edc46b8f5e7362b04636c0c4f0723/src/include/access/nbtree.h
/* Bits defined in btpo_flags */
#define BTP_LEAF		(1 << 0)	/* leaf page, i.e. not internal page */
#define BTP_ROOT		(1 << 1)	/* root page (has no parent) */
#define BTP_DELETED		(1 << 2)	/* page has been deleted from tree */
#define BTP_META		(1 << 3)	/* meta-page */
#define BTP_HALF_DEAD	(1 << 4)	/* empty, but still in tree (什么条件下是half dead?) */ 
#define BTP_SPLIT_END	(1 << 5)	/* rightmost page of split group */
#define BTP_HAS_GARBAGE (1 << 6)	/* page has LP_DEAD tuples (deprecated) */
#define BTP_INCOMPLETE_SPLIT (1 << 7)	/* right sibling's downlink is missing */
#define BTP_HAS_FULLXID	(1 << 8)	/* contains BTDeletedPageData */

pg中堆表元组的几种状态

// https://github.com/postgres/postgres/blob/c8e1ba736b2b9e8c98d37a5b77c4ed31baf94147/src/include/storage/itemid.h
/** lp_flags has these possible states.  An UNUSED line pointer is available* for immediate re-use, the other states are not.*/
#define LP_UNUSED		0		/* unused (should always have lp_len=0) */
#define LP_NORMAL		1		/* used (should always have lp_len>0) */
#define LP_REDIRECT		2		/* HOT redirect (should have lp_len=0) */
#define LP_DEAD			3		/* dead, may or may not have storage */

参考资料

openGauss源码解析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/296229.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nessus详细安装-windows (保姆级教程)

Nessus描述 Nessus 是一款广泛使用的网络漏洞扫描工具。它由 Tenable Network Security 公司开发&#xff0c;旨在帮助组织评估其计算机系统和网络的安全性。 Nessus 可以执行自动化的漏洞扫描&#xff0c;通过扫描目标系统、识别和评估可能存在的安全漏洞和弱点。它可以检测…

新版IDEA中Git的使用(一)

说明&#xff1a;本文介绍如何在新版IDEA中使用Git 创建项目 首先&#xff0c;在GitLab里面创建一个项目&#xff08;git_demo&#xff09;&#xff0c;克隆到桌面上。 然后在IDEA中创建一个项目&#xff0c;项目路径放在这个Git文件夹里面。 Git界面 当前分支&Commit …

计算机毕业设计 基于SpringBoot的房屋租赁管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

智能优化算法应用:基于跳蛛算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于跳蛛算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于跳蛛算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.跳蛛算法4.实验参数设定5.算法结果6.参考文献7.MA…

oracle即时客户端(Instant Client)安装与配置

之前的文章记录了oracle客户端和服务端的下载与安装&#xff0c;内容参见&#xff1a; 在Windows中安装Oracle_windows安装oracle 如果不想安装oracle客户端&#xff08;或者是电脑因为某些原因无法安装oracle客户端&#xff09;&#xff0c;还想能够连接oracle远程服务&#…

JavaWeb笔记之WEB项目

一. 版本控制 版本控制是指对软件开发过程中各种程序代码、配置文件及说明文档等文件变更的管理&#xff0c;是软件配置管理的核心思想之一。 版本控制最主要的功能就是追踪文件的变更。它将什么时候、什么人更改了文件的什么内容等信息忠实地了记录下来。每一次文件的改变&a…

LangChain 31 模块复用Prompt templates 提示词模板

LangChain系列文章 LangChain 实现给动物取名字&#xff0c;LangChain 2模块化prompt template并用streamlit生成网站 实现给动物取名字LangChain 3使用Agent访问Wikipedia和llm-math计算狗的平均年龄LangChain 4用向量数据库Faiss存储&#xff0c;读取YouTube的视频文本搜索I…

网络安全行业术语

病毒 是在计算机程序中插入的破坏计算机功能或者数据的代码&#xff0c;能影响计算机使用&#xff0c;能自我复制的一组计算机指令或者程序代码。 抓鸡 利用使用大量的程序的漏洞&#xff0c;使用自动化方式获取肉鸡的行为&#xff0c;即设法控制电脑&#xff0c;将其沦为肉…

冒泡排序之C++实现

描述 冒泡排序算法是一种简单的排序算法&#xff0c;它通过将相邻的元素进行比较并交换位置来实现排序。冒泡排序的基本思想是&#xff0c;每一轮将未排序部分的最大元素逐个向右移动到已排序部分的最右边&#xff0c;直到所有元素都按照从小到大的顺序排列。 冒泡排序的算法…

Windows平台开发需要掌握的基础知识

windows本身也是一个软件。在这个软件中进行开发时&#xff0c;我们需要对它有个基础的了解&#xff0c;这样能让我们的开发过程更顺畅一些。 下面我就来说一下我们需要关注的基础知识点。 环境变量 有时候我们的程序执行&#xff0c;需要基于一些基础的库。比如Java运行&am…

展望2023年CSDN博客之星评选

目录 1 前言2 博客的意义3 人工智能对博客的影响4 AI 技术下的成长与分享5 技术的探索6 博客之星评选对于技术人的激励作用7 结语 1 前言 当我们回顾过去&#xff0c;博客不仅仅是一种记录生活、分享经验的方式&#xff0c;更是一个见证自我成长与进步的平台。站在2023年度 CS…

Navicat里MySQL表的创建(详细)

我以Navicat连接MySQL为例&#xff0c;演示表的创建方法。 前提 创建表的语法&#xff1a; create table 表名 &#xff08; 字段名1&#xff0c;字段类型&#xff0c; 字段名2&#xff0c;字段类型&#xff0c; ...... 字段名n&#xff0c;字段类型 ); 我计划在test库存放一…