vacuum 处理 | 学习笔记

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介: 快速学习 vacuum 处理

开发者学堂课程【PolarDB for PostgreSQL 开源人才初级认证培训课程vacuum 处理学习笔记,与课程紧密连接,让用户快速学习知识。

课程地址https://developer.aliyun.com/learning/course/1077/detail/15554


vacuum 处理

 

内容介绍:

一、并发 vacuum 概述

二、可见性地图概述

三、冻结概述

四、Autovacuum 介绍

五、Full VACUUM

这节课讲 Polar DB vacuum的操作,vacuum 是 Polar DB 里头所特有的一种维护工作,为什么要有这个进程,它怎么操作。


一、并发 vacuum 概述

1.vacuum 工作内容

Vacuum如果中文翻译过来叫做真空。可以根据他的工作内容,可以把它理解为是一个空间清理,空间整理这么一个工作,他最主要的工作内容就是把数据块当中被删除的行的空间,把它释放出来,首先要了解polarDB,它对数据库当中被删除的行是怎么处理的,假如当前这个数据块,已经有两行数据,一个用户做了一个update操作,比如说他修改了这一行,那么polarDB它的操作方式不是在当前这一行进行修改,他会把原来的这一行标识为删除,然后会在这个数据块insert一行新行,这个被标识为删除的行,他的空间不会立刻去释放,在什么时候释放,谁去释放,就是由vacuum来操作。所以vacuum的操作就是做空间整理,他除了这个工作以外,他还做把老的PXID修改的给冻结,为什么要冻结,冻结只有polarDB或者PG所具备的一个特征。除了这个之外,他还做表统计信息的收集,这个非常重要,这个收集的信息是为了给优化器提供可用的答案进行做参考,除了这个以外,还会更新一些表的文件。

image.png

2.vacuum 处理流程

首先vacuum的操作过程,实际上的过程可以分为三部分,首先是怎么处理前的部分,处理前的部分他要到各个数据库里头去搜一下,哪一些表达到了需要整理的一个条件,vacuum的操作条件,他在他polarDB里是有规定的,它有一个专门的一些参数来制定。如果你这个表达到了这个条件,它就会从各个数据库里头把需要整理的这个表组成一个例子,准备完之后,接下来就到了清理阶段,清理阶段就是把包含着被删除的行,测完后同时更新一下这两个文件,做完以后就是善后工作,善后是如果说这个表有三个块,空间整理完以后,发现最后没有数据,就没有办法那么减少这个表的尺寸,那么polarDB会把这个数据块,从这个表中给删掉,这样子就让表包含有两个块,可以减少数据文件的尺寸。弄完以后,他会做统计信息。如果需要会把不必要的log、clog打给上面,所以看一下vacuum的进程,它平时所做的操作的内容比较多,同时也比较重要。

image.png

3.vacuum 操作前后对比

这个vacuum操作的一个前后对比,举个例子,比如这个表,当前三个数据块,三个数据块其中第0个数据块,当前的情况是有一行和这一行是被删除的行,在polarDB它被标注的tuple的就是死行,死元组,那么polarDB它的称呼不像olger,olger函数就叫做log,但是它叫tuple翻译过来叫做元组。那么假如这个块当中的一个被删掉,那做完back后来看polarDB,它就会把被删除的行的空间释放,然后再把原来这两个数据做一个整理,这样子数据就存放的就更加紧凑,然后将来在存放新数据的时候就放得更多。同时注意被删除的这个函的这个指针,他没有删掉,因为将来这个指针,比如说我现在又插入一个新行,他就根据指针把这个指针给新行,维护的操作就少一点,可以提高效率。

image.png


二、可见地图概述

1.可见性地图作用

在做vacuum的时候,正常情况,它是要把表的所有的数据块给找一点,然后进行清除,那么我为了提高他的效率,比例,就用了VM数据文件,叫做可见性地图,可见地图是为了提高这个vacuum的效率,举个例子,比如当前有三种数据块,这个数据块里假如第二个块,这个块他那里没有包含被删除的行,那么他就在vacuum地图上面用1来表示,那么将来他在做vacuum的时候,如果他去扫描这个页的这一块的时候,他一看这个页的状态是1,将来在处理的时候,这块它就跳过去,因为里面没有包含我需要进行空间整理的数据我就跳过去,那这样子就会提高vacuum的效率,所以这是可见性地图的一个作用。

image.png

2.增强的可见地图

那么可见地图除了提高效率,同时它还包含了将来去做冻结的时候它的一个效率。

VM在9.6版中得到了增强,以提高冻结处理的效率。

新的VM显示页面可见性和关于在每个页面中元组是否冻结的信息。

3.事务 IDS 结构(polarDB 中的 IDS)

接下来polarDB为什么要去冻结PXID,

这就是数据库为了去描述这个事物操作的一个先后顺序,要给事务分配一个ID号,那么aorocal生成的ID号,叫做SCN号,这个应该都明白,叫事务处理号,事务改变号。那么polarDB他不叫SCN号,它叫做txid号。就是事务ID号,那么aorocal的这个SCN号,它是以整数的形式来增长,而且他还告诉我ID号可以用100年,所以这个ID号我们可想而知,可能将来他的数量是比较大的,但是polarDB他用的这种方式,不是这种无限大的整数,他用到了一个循环的使用,就是他最大的可用的这个事务ID,总共有42亿,这个42亿是一半一半的用的,比如前面用前面20亿的时候,代表当前正在用的这些事务ID所修改的行,把它当作是过去的修改的这些行,我们把它描述为是可见,那么后21亿,这个是未来的,未来就是未来不可见,根据他的规则,这些事务ID所修改的行是不可见的,

举个例子,原来有个数据块,这个数据块这一行的数据,它修改他的事务ID,比如说很大是由这个事务ID去改的,那么这个事务ID假如说是属于这个部分,就是后21亿的,那么根据他的规则,那么这个块的这一行,将来去扫描的时候,对于我们用户来说是不可见的。就是它有这么一个规则,哪怕这个TXID有总共虽然只有42亿,但是可以不断的循环,如果前面先用,前面的这个21亿用完以后再用后面的21亿,然后用完之后又回来用前面的21亿,是这样子循环使用的。

image.png

三、冻结处理概述

1.冻结处理

冻结是基于他的一个可见性规则,如果这个ID,比如是一个数据块,然后有一行数据,在这个数据库里有一行的数据标记了,它是由第100个事务ID修改好了,然后下面这个数据库用了很久,现在,我的数据库以我的事务ID,已经用到了后21亿,比如说是21亿加100。已经用到了这里,那么根据他的规则,你前20亿用到的这个事物ID就不可用了,这个前面的21亿以前的这个事物,所修改的行,按照正常情况下就不可见,但是这个数据块里头有数据,又不得不让你看见,那怎么办?那就要在这个行的某一个位上面做个标记,这个标记就是冻结的标记,为什么叫做冻结,其实,它其实就是做了一个英文标记,就是做了一个英文标记,那么这个英文它翻译过来叫做冻结,所以就把它称为冻结,就是在这一行做一个标记,标记说将来这一行是可见的,如果没有这个标记,那么这一行就找不到。所以这个冻结就是把很早以前超过了21亿的事务ID,以前这个事务ID所修改的行,做一个标记,那么这样的标记完以后,很早以前的事务ID修改的行,才能够把他给访问看得到。

在做标记的时候,要根据它的规则,是前面先用了21亿,用完以后,把前面用的21亿里头,比如把这一部分你所操作的这些事物,都帮你冻结一下,那么一种情况就是用完以后统一冻结,那这个冻结的时候,操作是非常巨大的,肯定不行,所以那polarDB它是平时运了一点一部分事物ID以后,它可能就冻结一下,然后又运了一部分以后又冻结一下,等于说将来如果要到了换另外21亿事务ID使用的时候,等于要冻结的时候,前面几乎都已经冻结完了,只要冻结一小部分没有冻结完的ID就可以了,换句话来说,把一个庞大的一个需要做的工程,把他分到平时,切成若干部分,先逐步的完成,到了最后,只要完成一小部分的就可以达到这个目标,把这个项目完成,就这么简单。

所以在冻结的时候,就分为小冻结和大冻结,在polarDB里把它叫做惰性冻结和急性冻结,之所以这么说,是按照他的意思翻译过来,在理解的时候,可以把惰性冻结理解为小冻结。然后把急切冻结理解为大冻结,冻结的多一点。还可以理解为,小冻结可以把它看作住的房间,要保持干净,小冻结可以理解为做日常的卫生,大冻结可以理解为年终大扫除。就可以把很大的一个工程,平时一步一步的做直到把这个大部分做好。

2.惰性冻结模式

下面介绍一下惰性冻结他是怎么冻结?它是根据一个公司,就是发生冻结的时候,哪一些事物ID要被冻结掉,当然它这里的控制,就是要被冻结的ID等于这个叫做oldestxmin就是当前事务中最小的一个,假设是100-102,都要去减去free_vacuum_min_age一般为五千万是个常数,都要去减掉五千万。

image.png

3.惰性冻结示例

我现在最小的事务ID是50,002,500,这是当前正在用的最小的事务ID,在这个时候做惰性冻结,那么按照公式,是把当前最小的减去五千万,等于2500,意味着要把小于或者等于2500的事务ID都冻结掉,首先计算出你要冻结的ID是多少,然后找出对应的ID,看VM比,VM比是如果有三个数据块,加入没有被标记,如果VM中的1代表Tuple1、2、3,里面没有被标记的行,就会跳过这个数据块,惰性冻结只冻结数据块中有被scan的,凡是事务ID小于2500的都在后面有标记叫做FROZEN,用这个标记来表示把它要冻结,比如这个块,这个块有三个行,有一行是被事务ID3000修改的,而我算出小于等于2500会被标记,那么这个块中前面两行会被标记,第三行不会被标记。所以平常的时候就会对一些事务ID进行标记,标记的时候要减去五千万,要小于这个数才能被标记。可以理解为这个数据块中包含了太早以前就修改的行。

image.png

4.急性冻结触发条件

急性冻结类似大扫除,数据字典中pg_database datfrozenxid是曾经标记过的,假如你标记过的事务ID,小于正在使用的事务ID的最小值减去一亿五千万,也就是说你的事务ID至少用过一亿五千万次之后才会被冻结,又用了一亿五千万做一次急性冻结,急性冻结它的范围就会大一点。看实例,如果还没有发生一亿五千万次,统一的会被560标示,只有在发生一亿五千万次之后才会被急性冻结。

image.png

5.急性冻结示例

如果已经发生一亿五千万次,polarDB是如何做的,假如已经用到的

最小的事务ID是一亿五千万零两千,我要发生的冻结事务ID是当前的减去一亿五千万,小于这个数的被急性冻结,那么当前数据块中,polarDB会扫描这些行,把事务ID小于算出来这个数的全都在后面标记上冻结标示,之后在运作代码时,这些行都能被识别出来,大于这个数的,可以理解为刚刚被使用,那么这一行就不会被标识,只有很久以前被修改过的行,这些行的事务ID才会被冻结,最近很新修改的行不会被冻结,之后很久才会被冻结。惰性冻结在平时就已经开始了,而急性冻结只有在够了一亿五千万才开始,惰性冻结只要做vacuum操作,polarDB都会去判断这个数据块中要不要冻结。

image.png

6.冻结后如何标记

如果在ID冻结之后,比如是急性冻结,这些事务ID号是这些,做完以后所有的列上面就会写上被冻结时候它的ID是多少,因为够一亿五千万次之后就会进行急性冻结,而事务ID用过21亿才会翻一翻。

image.png

7.显示表的冻结ID

在我的表当中,假如我的表发生过惰性冻结。这个过程也可以看得到,通过这个数据字典可以看到,比如这个表,曾经被惰性冻结的ID,那么如果看到这个651,其实是意味着你这个表,可能是由这个事务ID创建的,这个事务所创建的ID,当做第一次被冻结。那实际上,0在表上面就意味着如果这个表是数据字典,就是这个数据初始化的时候创建的。

8.提高惰性冻结效率

因为急性冻结,他要把曾经发生过的事物所修改的行要做个标记,所以这个操作实际上它是很大的,或者可以理解为它的操作是比较大的,那么如果说你在冻结的时候,操作太大。所以它的polarDB为了提高效率。一个项目看他的VM。假如里面有一表示的意思就是上一次冻结以后,不管是急性冻结还是惰性冻结。只要你下一次冻结以后,如果没有发生任何的变化,状态为1。换句话来说,如果这个号从来没有改变过,下一次发生急性冻结的时候这个块就直接跳过,因为前面冻结过,而且也没有发生变化,那么凡是0冻结过的代表这两种,一个是擅自冻结过以后,一个是擅自惰性冻结没有发生,因为有可能比这个再多一次,在做惰性冻结的时候,可能没有做过,来到我这做一次急性冻结。

比如上次在做惰性冻结的时候,因为这个数据库里没有包含被删除的,所以跳过去,但是,这一次也跳过去这一次及其冻结的时候还要跳过去,还有就是冻结过以后,这个数据库里又被修改,里面又包含有很多可能,这个被修改的也会被标注,凡是状态他都要去做。防止它跳过去,这样可以让他来减少动机的一个工作,这就是怎么样用VM来提高冻结的效率,所以我们前面讲的这个,每一张表都一样,每一张表他的数据文件都有三类,比如第一类是纯放数据的,文字是FSM,还有一个文件是VM里头存放,就是可见性。

image.png


四、Autovacuum 介绍

刚才说了半天这个问题谁去做,怎么做,什么时候做,从polarDB9.6后,他就有了一个专门的一个后台进程叫做Autovacuum,它是怎么定义呢?是每十分钟做一次,由这个参数来定义,定义每期每次做的时候呢,默认是三个进程去做,每个进程同一时间只能负责一个数据库里头的表,当然,如果我们想增加他这个Autovacuum的一个进程数,可以用autovacuum_max_workers参数来添加。


五、Full VACUUM

那下面讲一下Full VACUUM,vacuum他分普通vacuum和Full VACUUM,如果只是做了普通的vacuum,比如当前的有三个块,然后灰色的这个,标志为都是被删除的,那做了一个vacuum以后,假如说现在做的是普通的vacuum,那么vacuum之后,这三个块还保留,最后只剩下一两行的数字,比这个数据块还高,也就是说普通的操作完以后,文件的大小不会发生变化。这三个块现在还是三个,但是我们看到情况会发现,其实每个块里面,数据其实很少,我没必要的话,可能这里头只要一个块可能就可以,所以假如在空间整理的时候,如果你想减少数据文件的尺寸,那就可以做一个full vacuum了。

image.png

当把这个就是被清理的这个弄完以后,他首先也是先把这个块当中被删除的行的空间,把它给清理掉,最后剩一行,然后接下来他会怎么做呢?会再新建一个数据文件然后给他分一个块,接下来把原来剩下的这些把它放到这个块里。放完以后,然后把原来的这个数据文件的删掉。所以一删掉以后,原来的这个数据文件的名字就变了,就得变成新的。这是full vacuum的一个例子操作。

image.png

那下面讲一讲,比如什么时候要做full vacuum,要做full vacuum,就是如果检测到这个数据块当中数据块很多,但是里面每个块当中可用的空间很多,那这时候可以做full vacuum。可以这么做一下,首先创建一个插件,这个插件是不支持的,polarDB社区版的可能不支持,企业版的支持,不支持也没关系,我们主要说明一下怎么做,将来我把一个表大部分的数据删掉了,删完以后来看一下,其实,可以复印这个差距,可以看这个表的统计,

image.png

这个社区版的它不支持这种,这个差距,主是讲一下应该怎么去诊断,那么一开始,假如有这个插件,你可以去看一下,比如你当前我这个表当中总共有多少个数据块。然后看每个数据库里可用的空间有多少,只有99个字节,意味着我这块当中差不多都用完了,都有数据,那么接下来,做一个delete操作以后,我可能把表当中很多行的做法删掉,然后这时候,我们做了一个普通的vacuum,以后会发现这个总共的数据块没有发生变化,但是我们可以看到这个块当中平均已经空出差不多7K的数据,空间都是空的,也就是你可用的空间已经达到了80%,那就意味着这个块当中,经过空间处理完以后,很多被删除的行的空间已经释放,目前,只剩下一小部分。

image.png

如果是这样,就可以做full vacuum,看一下做完full vacuum以后,最大的一个变化是你的使用的块变少了,不需要那么多,所以full vacuum就是刚才看到的,会把剩下的数据做整理,整理完以后放到一个新的数据文件上面,然后把老的数据给删掉,这样就可以减少数据文件的尺寸

image.png

那下面就可以演示一下,比如在删除之前,看了一下这张表的统计,当时总共占了94个数据块,下面删掉一部分的数据,删完以后,如果是做一个普通的 vacuum,再查查看会发现这个统计信息的时候还是94个块,它没有变,但是如果做了 full vacuum,那我们再看一下这个数据块的统计,会发现只要用十个块就够了,明白这样子的好处就是将来这个表如果做全表扫描的时候,而做了full vacuum以后,你只要扫描十个,所以可以提高全表扫描的效率。那么这一点,跟Oracle也比较像是,Oracle 表预了一段时间以后,如果里头被删除的行比较多,是不是也要做一个空间,整理完以后,你全表扫描,所访问的数据块,就会减少,这样子就会提高我们访问的效果。

学习了 vacuum 操作,它是一个非常重要的进程,主要做的工作就是清理被删除的行,做冻结,特别是冻结,如果第一次学 polarDB,要理解为什么要冻结,它怎么冻结,冻结的过程。

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
存储 安全 索引
vacuum freeze无法回收事务号问题分析
vacuum freeze报错问题分析
4242 0
|
9月前
|
固态存储 关系型数据库 开发者
PG13并行vacuum
PG13并行vacuum
86 0
|
9月前
|
关系型数据库 数据库
加速PG中vacuum
加速PG中vacuum
82 1
|
11月前
|
SQL Oracle 算法
Oracle优化06-Hint
Oracle优化06-Hint
151 0
|
关系型数据库 MySQL
囧...执行analyze table意外导致waiting for table flush
囧...执行analyze table意外导致waiting for table flush
137 0
|
SQL 关系型数据库 数据库
|
关系型数据库 MySQL 索引
|
存储 关系型数据库 Go
PostgreSQL 11 内核优化 - 降低vacuum cleanup阶段index scan概率 ( vacuum_cleanup_index_scale_factor , skip index vacuum cleanup stage)
PostgreSQL 11 内核优化 - 降低vacuum cleanup阶段index scan概率 ( vacuum_cleanup_index_scale_factor , skip index vacuum cleanup stage)
1221 0
|
存储 关系型数据库 Java
Pgsql原理解析——Vacuum
title: Pgsql原理解析——Vacuum date: 2019-03-19 12:23:31 categories: - Postgresql - PgInternal vacuum的两个主要作用在之前的"并发控制"中已经有了一些介绍,本章针对vacuum的原理、使用做进一步讲解。 1 引言:案例分析 1.1 慢查询案例 tdb0529=&g
2141 0