短小精悍的一篇:你需要知道的PostgreSQL数据库Vacuum基础知识

文摘   科技   2024-08-02 06:00   北京  

前言

我们甚至听不到“数据库维护”这个术语。那么它到底是指什么呢? 😄

任何东西都需要有效的维护,包括你的数据库。定期维护可以帮助它有效地运行和执行,以满足您的业务期望。数据库维护描述了为改进数据库而运行的一组任务,其中有一些命令可以帮助提高性能、释放磁盘空间、检查数据错误、硬件故障、更新内部统计以及许多其他独立(但通常很重要)的事情。

数据库维护是日常PostgreSQL操作中经常被忽略的一个话题。虽然大家都知道数据库备份需要定期进行,但只有少数用户意识到其中的额外工作。您看不到很多数据库维护工作的主要原因之一是缺乏对SQL本身的深入了解,并且无法使用高效的行来执行任务。

有时,数据库维护不当可能会导致不受重视,但当数据库性能受到影响时;  才会变成真正的问题。这个时候,是不是感觉为时已晚?🤣

本白皮书将带您了解postgresql中常见的数据库维护任务。

主要亮点:

1、Vacuum 在PostgreSQL中进行处理,它会清理死行或死元组。它类似于对死行/元组(通常称为膨胀)的碎片整理。

2、PostgreSQL通过MVCC维护旧的元组版本,以便在事务上可见。因此,它不会立即删除,并且由于MVCC功能,它保留这些版本的数据,除非有人告诉它删除。

3、在PostgreSQL中有一个auto vacuum过程,但是对于特定的负载,DBA更喜欢调度它以获得更好的性能。

4、如果不经常进行vacuum处理,那么随着数据元组版本的增加,数据库性能会下降。事实上,在几天或几个月后,它可能会因为事务重新封装而崩溃。

关于Postgres Vacuum

与大多数其他数据库管理系统相比,PostgreSQL是一个维护代价比较低的数据库。尽管如此,对维护任务的适当关注将大大有助于确保系统的愉快和富有成效的体验。

在PostgreSQL中,像UPDATE或DELETE这样的操作不会立即删除旧版本的行。如果您的应用程序经常在数据库中执行许多UPDATE/DELETE操作,那么它可能会快速增长,并且需要定期维护。

通常,在PostgreSQL数据库中,定期执行维护活动,称为vacuuming(抽真空)。它的两个主要任务是移除死行和冻结事务id

Vacuum操作提供两种方式去除死行; 一个是VACUUM,另一个是VACUUM FULL

VACUUM操作负责删除表文件每一页的死行,当这个进程运行时,其他事务可以读取表。

而另一方面,Full VACUUM删除整个文件的死行并整理活动行,并且在Full VACUUM运行时,其他事务(如任何DDL, DML和Select)不能访问这些表。

VACUUM:

Vacuum用于恢复表中被“死元组”占用的空间。当记录被删除或更新(删除后插入)时,将创建死元组。PostgreSQL不会从表中物理地删除旧行,而是在其上放置一个“标记”,以便查询不会返回该行。当Vacuum进程运行时,这些死元组所占用的空间被标记为可被其他元组重用。

Vacuum处理对数据库中的指定表或所有表执行以下任务:

1、从指定的表中获取每个表。 
2、获取表的ShareUpdateExclusiveLock锁。该锁允许从其他事务读取数据。
3、扫描所有页面以获取所有失效元组,并在必要时冻结旧元组。

4、删除指向相应死元组(如果它们存在)的索引元组。

5、对表格的每一页执行以下任务,步骤(6)和(7)。
6、删除死元组并整理页面上的活元组。
7、分别更新目标表的FSM和VM。

8、使用内置函数清理索引。

9、如果最后一页没有任何元组,则截断最后一页。

10、更新与目标表的真空处理相关的状态表和系统目录。

11、释放ShareUpdateExclusiveLock锁。

12、更新真空处理相关的状态表和系统目录。

13、如果可能的话,删除clog中不需要的文件和页面。

这里有两个新术语:Free Space Map (FSM)和Visibility Map (VM)。让我对这些术语作一个简短的解释。

Free Space Map (FSM):

在PostgreSQL中,每个表和索引都有一个FSM来跟踪可用空间。它将所有与空间相关的空闲信息存储在主关系旁边,该关系以文件节点号加上后缀_fsm开始。

Visibility Map (VM):

可见性映射与每个表和索引相关联,并用于跟踪哪些页面只包含已知对所有事务可见的元组。它与主关联存储在单独的关联中,它以文件节点号加上后缀_vm开始。

死元组

例如,正如您在上图中看到的,一个表有两个页面。让我们把注意力集中在第0页,也就是第一页。该页有四个元组。tuple -2是一个死元组。在这种情况下,PostgreSQL删除Tuple-2并重新排序剩余的元组来修复fragmenta on/bloat,然后更新该页面的FSM和VM。PostgreSQL会在最后一页继续这个过程。

PostgreSQL-13 for vacuum operation PARALLEL 选项的引入,有助于并行运行索引vacuum和清理。

请注意,只有当表中至少有两个索引时,PARALLEL操作才有用。我们将在本文后面解释冻结过程。

Vacuum Full:

Vacuum Full进程对数据库中的指定表或所有表执行以下任务:

1、从指定的表中获取每个表。
2、为表获取“AccessExclusiveLock”锁。该锁不允许从任何其他事务读取和写入。3、创建一个大小为8 KB的新表文件。
4、PostgreSQL只将旧表文件中的活元组复制到新表中。
5、删除旧的表文件。
6、重建所有索引
7、同时更新状态目录和系统目录。
8、释放“AccessExclusiveLock”锁
9、如果可能的话,删除不需要的clog文件和页面。

Vacuum Full

例如,正如您在上图中看到的,一个表有两个页面。第0页有四个元组。Tuple-2和Tuple-4是死元组。第一页也有另外四个元组,Tuple-5和8是死元组。当我们执行Vacuum Full命令时,PostgreSQL开始删除死元组,比如首先为该表获取“AccessExclusiveLock”锁,并创建一个大小为8kb的新表文件。因此,PostgreSQL只将旧表文件中的活动元组复制到新表中,并且在复制所有活动元组时,PostgreSQL删除旧文件,重建所有相关的表索引,更新相关的状态和系统目录。

请注意,由于“AccessExclusiveLock”,当Full VACUUM运行时,没有人可以访问表,并且这种方法还需要临时额外的磁盘空间,因为它写入表的新副本,并且在操作完成之前不会释放旧副本。磁盘空间需要是表大小的两倍。Vacuum Full帮助您从表中回收空闲空间到磁盘。

现在,问题立即浮现在脑海中: 如果磁盘空间即将满,并且不能快速增加大小,该怎么办? 那么,在这种情况下我们该如何继续呢?那么我将推荐以下方法。

方法一:

从比较小的表开始总是好的,这样可以很容易地容纳可用的磁盘空间。因此,慢慢地,您将获得更自由的磁盘空间然后很有可能获得足够的磁盘空间来容纳那些由于磁盘空间较少和表大小较大而不适合VACUUM FULL的表

方法二:

对于VACUUM FULL,删除要执行VACUUM FULL的表的所有索引,然后执行VACUUM FULL。一旦这个操作成功完成,就重新创建该表上所有被删除的索引。

如果以上两种方法都不可行,那么,在这种情况下,您必须增加磁盘空间,这是唯一可行的操作。

现在,让我们来理解vacuum冻结的概念,但在继续之前,我们应该知道PostgreSQL中的transacon ID回卷的问题。

什么是PostgreSQL中的transacon ID环绕问题?

在PostgreSQL中,事务控制机制为数据库中被修改的每一行分配一个事务 ID (Txid); 这些id控制该行对其他并发事务的可见性

事务回卷是由多版本并发控制(MVCC)引起的问题。MVCC依赖于获取两个事务的txid并确定哪个事务先出现。在Postgres中,txid只有32位整数长。这意味着只有2^^32个,或者我们可以说大约有40亿个Txids。坦率地说,40亿听起来可能很多,但是如果写量非常大,工作负载可以在几天或几周内达到40亿事务(笔者注:事实上,如果要快速模拟,几个小时就可以达到)。

现在,一个即时的问题出现在脑海中,当PostgreSQL达到40亿事务时将会发生什么?

因此,答案是PostgreSQL从一个循环中依次分配Txids。循环回到0,看起来像0,1,2,…, 2^^32-1, 0,1,…以确定哪两个txid较旧。因此,在这种逻辑下,Postgres必须确保当前使用的所有txid都在彼此的2^^31范围内。这样,所有使用的txid形成一致的顺序。

PostgreSQL还通过定期删除所有旧的txid来确保只使用有效范围的txid。如果旧的Txid没有定期清除,那么就会出现一个新的Txid,它比最新的Txid更新,同时看起来比最旧的Txid老;  这就是所谓的事务回卷。

在这种情况下,PostgreSQL将终止正常的操作,以防止数据损坏,并停止接受新的事务请求,从而导致停机。

为了自动清除旧的txids, Postgres使用了一种特殊的vacuum。auto vacuum将“防止回卷”消息添加到流程中,如下所示。

请注意,如果在您的环境中看到此消息,则无法停止auto vacuum过程,即使您在postgresql.conf或postgresql.auto.conf文件中设置autovacuum=off。

VACCUM FREEZE

现在,我们回到原点,也就是vacuum freeze。Autovacuum进程负责冻结表的transac - on ID,并将其替换为Frozen Txid,以避免transac - on ID封装失败。简单地说,我们可以说,冻结的心永远是不可见的。

作为一种预防性措施,DBA需要监控表,以确保在auto vacuum进程无法对频繁访问的表进行vacuum处理的大型表中,Txid不会耗尽。

下面的SQL命令可以帮助DBA监控数据库的最老版本和数据库的当前状态。

SELECT datname, age(datfrozenxid), current_setting('autovacuum_freeze_max_age')FROM pg_database ORDER BY 2 DESC;

如果任何特定的数据库接近freeze_max_age值,则应该执行连接到该特定数据库的以下查询。该查询给出了应该手动进行冻结操作的带有最老事务ID的表的列表。

SELECT c.oid::regclass, age(c.relfrozenxid), pg_size_pretty(pg_total_relation_size(c.oid)) FROM pg_class c JOIN pg_namespace n on c.relnamespace = n.oid WHERE relkind IN ('r', 't', 'm') AND n.nspname NOT IN ('pg_toast') ORDER BY 2 DESC;

现在,如您所知,如果您想在非常繁忙的产品环境中执行Vacuum Full,则必须为“AccessExclusiveLock”的长开销付出代价。因此,为了克服这个问题,许多企业级客户正在使用“pg_repack”扩展。

pg_repack

pg_repack是一个PostgreSQL扩展工具,它可以做很多FULL VACUUM可以做的事情,比如从表和索引中删除膨胀,恢复聚集索引的物理顺序。与VACUUM FULL不同的是,它可以在线工作而无需持一个“AccessExclusiveLock”锁在被处理的表上。

Pg_repack进程对数据库中的指定表或所有表执行以下任务:

1、创建一个日志表来记录对原始表所做的更改
2、在原始表上添加一个触发器,将insert、UPDATEs和DELETEs记录到日志表中。3、创建一个包含旧表中所有行的新表
4、在这个新表上构建索引
5、将日志表中累积的所有更改应用到新表中
6、使用系统编目交换表,包括索引和toast表
7、删除原始表

pg_repack将只在初始步骤(如上所述步骤1和2)和最后的交换和删除阶段(步骤6和7)期间短暂地持有“ACCESSEXCLUSIVELOCK”锁。

对于它的其余部分,pg_repack只需要在原始表上持有一个“ACCESSSHARELLOCK”锁,这意味着select、insert、UPDATEs和delete可以照常进行。

我希望本文能帮助您了解VACUUM的概念,并有效地计划维护活动。要了解更多信息,可以访问:www.ashnik.com[1]

原文标题:Everything you need to kno PostgreSQL Database Mainte Getting Inside ‘VACUUM’ Date:

21 June 2021 white paper from: [ASHNIK](www.ashnik.com[2])

参考资料

[1]

www.ashnik.com: http://www.ashnik.com

[2]

ASHNIK: http://www.ashnik.com

我是【Sean】,  欢迎大家长按关注并加星公众号:数据库杂记。有好资源相送,同时为你提供及时更新。已关注的朋友,发送0、1到7,都有好资源相送。

往期导读: 
1. PostgreSQL中配置单双向SSL连接详解
2. 提升PSQL使用技巧:PostgreSQL中PSQL使用技巧汇集(1)
3. 提升PSQL使用技巧:PostgreSQL中PSQL使用技巧汇集(2)
4. PostgreSQL SQL的基础使用及技巧
5. PostgreSQL开发技术基础:过程与函数
6. PostgreSQL中vacuum 物理文件truncate发生的条件
7. PostgreSQL中表的年龄与Vacuum的实验探索:Vacuum有大用
8. PostgreSQL利用分区表来弥补AutoVacuum的不足
9. 也聊聊PostgreSQL中的空间膨胀与AutoVacuum
10. 正确理解SAP BTP中hyperscaler PG中的IOPS (AWS篇)

数据库杂记
PostgreSQL,SAP HANA,Sybase ASE/ASA,Oracle,MySQL,SQLite各类数据库, SAP BTP云计算技术, 以及陈式太极拳教学倾情分享。
 最新文章