PostgreSQL 难搞的事系列 --- vacuum 的由来与PG16的命令的改进 (1)

130e94df5176e71df3ebf4f39367e4c6.png

开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,在新加的朋友会分到2群(共1720人左右 1 + 2 + 3 + 4+5) 另欢迎 OpenGauss GAUSSDB的技术人员加入

PostgreSQL 的内容之前写上百篇,这里打算开一个系列,叫PostgreSQL难搞的事情,主要针对PostgreSQL中经常被问及的问题和一些导致这些问题深层次的原因的一个主题。这次的主题从PostgreSQL的vacuum 开始,

说到Vacuum 属于是几家欢喜几家愁的,一般发愁的都是那些PostgreSQL 业务繁忙的大库,并且经常出现业务高峰期的一些系统性能的波动。但大部分人都只关注Vacuum, autovacuum 而忽略了一些为什么会产生这样动作的原因,同时不少人对 aggressive vacuum 的是什么不了解,导致vacuum 和  aggressive vacuum 的问题搞不清,最终导致严重的问题。

首先vacuum 的由来这个问题需要反复的说,在我们进行多版本控制,MVCC multiversion concurrency control ,是产生PG vacuum的根源 mvcc主要目的就是提供在数据库访问中可以进行并发访问,并发访问则需要对于事务中的数据提供同一行数据,在不同时间中访问中的版本信息,而这些信息是集中式,还是分散式是两种数据库设计的不同。

在PostgreSQL中我们使用了分散式,也就是将所有的行的版本信息驻留在我们的数据表内,基于这样的处理方式,导致后续这些失效的版本行信息需要进行清理,而清理这些行的信息的过程称为vacuum,相对应的我们会有 vacuum 和 autovacuum的命令和相关的过程来进行相关的工作,而基于这样的形成方式,导致PostgreSQL 应对这部分工作并产生了一套与其他数据库截然相反的工作。

在工作中我们大概率会遇到以下的一些问题

1  回收不及时,触发数据库回卷,导致触发aggresive vaccum,或最终导致freezing boom 触发单用户模式。

2  触发Autovacuum进行回收与系统正在进行高耗能操作撞车,导致系统性能出现瓶颈影响正常业务

3  关于vacuum的命令和参数多每个版本都有新的东西的加入,变化多部分版本对于命令参数进行了改变,并且参数的细致程度高,大部分人无法进行有效配置和调配

所以基于这些问题,我们需要分几期来说这个问题,整体系统化的梳理,基于数据库设计产生的一些在PostgreSQL中的特殊的需求的问题。

本期是这个系列的第一篇,所以我们先从问题的起源来详细说一说,这里我们看下图,下面两个图清晰的展示了数据表中某行的数据产生新一个行版本和老版本行共存的过程,以及访问中通过老的行指向新的行的过程等。

ad5e7456aad516336a92e60b3ed4172a.png

0766fffc592f1f2ad5e6edd585275934.png

必然在上一个版本的行在所有事务中都成为历史行后,会成为死行,死行就相当于其他数据库中UNDO 中需要被清理的数据信息。

基于MVCC的形成,PostgreSQL的每行上都会对于他是那个数据库库事务的归属进行标记,在这样的情况下,标记每行属于那个事务的数字,txid也有使用耗费光的情况,基于这个数字的大小为2的32次方,那么在回收这些txid 号的情况下,很有可能由于一些情况而无法对这些txid的号进行收回,而长时间无法收回这些txid的情况就会导致数据库产生 aggressive vacuum ,aggressive vaccum 。

导致aggressive vacuum 后最大的问题是,aggressive vacuum中的扫描工作,普通的vacuum本身并不会对数据表中每页的数据进行扫描,而aggressive vacuum 则是针对未冻结的数据页面全部扫描,扫描中会导致大表较长时间在进行整体的页面扫描,扫描期间的CPU 和IO 均会为此项工作服务,同时还会导致长时间针对这张表无法进行DDL操作。所以我们在工作中,都在尽力的避免发生  aggressive vacuum 的工作。

下面我们通过一个列子来进行展示,我们找到一张表,其中我们计算出他的相关的age 是 478

postgres=# SELECT c.oid::regclass as table_name,greatest(age(c.relfrozenxid),age(t.relfrozenxid)) as age                                                                                                                                                    
postgres-# FROM pg_class c                                                                           
postgres-# LEFT JOIN pg_class t ON c.reltoastrelid = t.oid
postgres-# WHERE c.relkind IN ('r', 'm') and c.oid::regclass::varchar = 'time_test';
 table_name | age 
------------+-----
 time_test  | 478
(1 row)


然后我们针对这张表进行vacuum 的操作,然后我们在观察相关的这张表的age

postgres=# vacuum verbose time_test;
INFO:  vacuuming "public.time_test"
INFO:  table "time_test": found 0 removable, 1 nonremovable row versions in 1 out of 1 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 878875
0 pages removed.
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUM
postgres=#

在我们对表进行vacuum后,发现表的age还是 478,并未有任何的变化。在我们改变命令后,针对这个表进行freeze 的操作后,我们在观察age的部分已经变为0.

77e30f311630bd3977eaaa267513d47a.png

postgres=# vacuum freeze verbose  time_test;
INFO:  aggressively vacuuming "public.time_test"
INFO:  table "time_test": found 0 removable, 1 nonremovable row versions in 1 out of 1 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 878875
0 pages removed.
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUM
postgres=# SELECT c.oid::regclass as table_name,greatest(age(c.relfrozenxid),age(t.relfrozenxid)) as age                                                                                                                                                    
FROM pg_class c                                                                           
LEFT JOIN pg_class t ON c.reltoastrelid = t.oid
WHERE c.relkind IN ('r', 'm') and c.oid::regclass::varchar = 'time_test';
 table_name | age 
------------+-----
 time_test  |   0
(1 row)

d4017ab1467ab9c4a8e64c32417b8f6e.png

postgres=# SELECT
postgres-# oid::regclass::text AS table,
postgres-# age(relfrozenxid) AS xid_age,
postgres-# mxid_age(relminmxid) AS mxid_age,
postgres-# least(
postgres(# (SELECT setting::int
postgres(# FROM pg_settings
postgres(# WHERE name = 'autovacuum_freeze_max_age') - age(relfrozenxid),
postgres(# (SELECT setting::int
postgres(# FROM pg_settings
postgres(# WHERE name = 'autovacuum_multixact_freeze_max_age') - mxid_age(relminmxid)
postgres(# ) AS tx_before_wraparound_vacuum,
postgres-# pg_size_pretty(pg_total_relation_size(oid)) AS size,
postgres-# pg_stat_get_last_autovacuum_time(oid) AS last_autovacuum
postgres-# FROM pg_class
postgres-# WHERE not (relfrozenxid = 0)
postgres-# AND oid > 16384
postgres-# ORDER BY tx_before_wraparound_vacuum;
        table         | xid_age | mxid_age | tx_before_wraparound_vacuum |    size    | last_aut
----------------------+---------+----------+-----------------------------+------------+---------
 test_t               |     289 |        0 |                   199999711 | 127 MB     | 
 collates             |     253 |        0 |                   199999747 | 56 kB      | 
 test_table           |     234 |        0 |                   199999766 | 40 kB      | 
 xcc.xcc              |     210 |        0 |                   199999790 | 0 bytes    | 
 pgbench_history      |      14 |        0 |                   199999986 | 0 bytes    | 
 pgbench_accounts     |      14 |        0 |                   199999986 | 13 GB      | 
 pgbench_branches     |      14 |        0 |                   199999986 | 112 kB     | 
 pgbench_tellers      |      14 |        0 |                   199999986 | 712 kB     | 
 bank                 |       3 |        0 |                   199999997 | 40 kB      | 
 dba_autovacuum_table |       0 |        0 |                   200000000 | 8192 bytes | 
 time_test            |       0 |        0 |                   200000000 | 56 kB      | 
(11 rows)

上面的脚本可以方便的查看当前的数据库中表中的AGE 以及发生回卷的计数器的数值。

在PostgreSQL 16 中针对vaccumdb 命令有了一些变化,我们把PG14 和PG16 的vacuumdb 

7c0b6611b1b0d70fc53078eab59705e8.png

我们清晰的看到有四个部分是不同的

1 --buffer-usage-limit=SIZE

2   --no-process-main 

3   -n, --schema=PATTERN 

4   -N, --exclude-schema=PATTERN

具体上我们可以对1 ,2 两个部分进行更细的研究

buffer-usage-limit 命令主要的意义,主要的目的还是针对具有大内存的主机,在进行vaccum的过程中,可以给与更多的内存,尽量对于大表进行快速有效的vacuum。相关范围在不开启和 128KB - 16G 之间进行设置。

7fcdb2be1684a76ff002c3c40aab6216.png

3c12851bf8f05e11543c87c24b6d7773.png

--no-process-main 这个主要添加的参数是为了不进行表的vacuum 只对表中的toast进行vacuum。

1ed3d1a18d4a882e431f868a554cf11e.png

参考:https://www.postgresql.org/message-id/08930c0b541700a5264e5fbf3a685f5a@oss.nttdata.com

064f6345b201ef8e391de1fe161d8191.png

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从零开始:抖音酒店景区小程序开发指南

为了满足用户多样化的需求,开发一款抖音酒店景区小程序成为了业界的一个新兴趋势。在这篇文章中,我们将探讨如何开发一款引人注目的抖音风格的酒店景区小程序。 一、抖音风格的设计理念 在设计酒店景区小程序时,我们需要融入抖音的设计理念。…

22 - 如何优化垃圾回收机制?

我们知道,在 Java 开发中,开发人员是无需过度关注对象的回收与释放的,JVM 的垃圾回收机制可以减轻不少工作量。但完全交由 JVM 回收对象,也会增加回收性能的不确定性。在一些特殊的业务场景下,不合适的垃圾回收算法以及…

Leetcode—剑指OfferII LCR 022.环形链表II【中等】

2023每日刷题(三十三) Leetcode—LCR 022.环形链表II 算法思想 参考k神的博客 实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode *detectCycle(struct List…

【C++】类和对象(6)--运算符重载

目录 一 概念 二 运算符重载的实现 三 关于时间的所有运算符重载 四 默认赋值运算符 五 const取地址操作符重载 一 概念 C为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数…

Git 简介及使用

前言 假设有这样一个场景,老板让员工做一个档案,员工这个档案做好了之后交给老板看,此时老板不满意,又让回去改,改完给老板看,但是老板又不是很满意,就这样改了又改,给老板看过之后&…

代码随想录算法训练营第四十五天| 139.单词拆分

文档讲解:代码随想录 视频讲解:代码随想录B站账号 状态:看了视频题解和文章解析后做出来了 139.单词拆分 class Solution:def wordBreak(self, s: str, wordDict: List[str]) -> bool:n len(s)dp [False] * (n1)dp[0] Truemax_len m…

WMS重力式货架库位对应方法

鉴于重力式货架的特殊结构和功能,货物由高的一端存入,滑至低端,从低端取出。所以重力式货架的每个货位在物理上都会有一个进货口和一个出货口。因此,在空间上,对同一个货位执行出入库操作需要处于不同的位置。 比如对…

【AD封装】芯片IC-SOP,SOIC,SSOP,TSSOP,SOT(带3D)

包含了我们平时常用的芯片IC封装,包含SOP,SOIC,SSOP,TSSOP,SOT,总共171种封装及精美3D模型。完全能满足日常设计使用。每个封装都搭配了精美的3D模型哦。 ❖ TSSOP和SSOP 均为SOP衍生出来的封装。TSSOP的中文解释为:薄的缩小型 SOP封装。SSO…

GSVA,GSEA,KEGG,GO学习

目录 GSVA 1:获取注释基因集 2:运行 GSEA 1,示例数据集 2,运行 GSEA_KEGG富集分析 GSEA_GO富集分析 DO数据库GSEA MSigDB数据库选取GSEA KEGG 1:运行 2:绘图 bar图 气泡图 绘图美化 GO GSVA 1:获取注…

springBoot 配置druid多数据源 MySQL+SQLSERVER

1:pom 文件引入数据 <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.0</version> </dependency>…

mysql服务器数据同步

在Linux和Windows之间实现MySQL服务器数据的同步。下面是一些常见的方法和工具&#xff1a; 复制&#xff08;Replication&#xff09;&#xff1a;MySQL复制是一种常见的数据同步技术&#xff0c;可用于将一个MySQL服务器的数据复制到其他服务器。您可以设置主服务器&#xff…

CMSIS-RTOS在stm32使用

目录&#xff1a; 一、安装和配置CMSIS_RTOS.1.打开KEIL工程&#xff0c;点击MANAGE RUN-TIME Environment图标。2.勾选CMSIS CORE和RTX.3.配置RTOS 时钟频率、任务栈大小和数量&#xff0c; 软件定时器. 二、CMSIS_RTOS内核启动和创建线程。1.包含头文件。2.内核初始化和启动。…

C#,数值计算——插值和外推,曲线插值(Curve_interp)的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// Object for interpolating a curve specified by n points in dim dimensions. /// </summary> public class Curve_interp { private int dim { get; s…

openGauss通过VIP实现的故障转移

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

VisualGDB 6.0 R2 Crack

轻松跨平台"VisualGDB 使 Visual Studio 的跨平台开发变得简单、舒适。它支持&#xff1a; 准系统嵌入式系统和物联网模块&#xff08;查看完整列表&#xff09; C/C Linux 应用程序 本机 Android 应用程序和库 Raspberry Pi 和其他Linux 板 Linux 内核模块&#xff08;单…

【PTA题目】6-13 求叠数(递归版) 分数 10

6-13 求叠数(递归版) 分数 10 全屏浏览题目 切换布局 作者 李祥 单位 湖北经济学院 请编写递归函数&#xff0c;生成叠数。 例如&#xff1a;Redup(5,8)88888 函数原型 long long Redup(int n, int d); 说明&#xff1a;参数 n 为重复次数(非负整数)&#xff0c;d 为数字…

未来科技中的云计算之路

随着科技的不断发展&#xff0c;云计算已经不再是一个陌生的词汇&#xff0c;而是我们日常生活中不可或缺的一部分。从智能家居到无人驾驶&#xff0c;再到虚拟现实和人工智能&#xff0c;云计算在这些领域都扮演着至关重要的角色。在这篇博客中&#xff0c;我们将一同探索云计…

【如何学习Python自动化测试】—— 页面元素定位

接上篇自动化测试环境搭建&#xff0c;现在我们介绍 webdriver 对浏览器操作的 API。 2、 页面元素定位 通过自动化操作 web 页面&#xff0c;首先要解决的问题就是定位到要操作的对象&#xff0c;比如要模拟用户在页面上的输入框中输入一段字符串&#xff0c;那就必须得定位到…

UiPath Studio 2023.10 Crack

UiPath Studio是一款功能强大且用户友好的集成开发环境 (IDE)&#xff0c;专为机器人流程自动化 (RPA) 设计。它由自动化技术领域的领先公司UiPath开发。 以下是 UiPath Studio 的一些主要功能和组件&#xff1a; 图形用户界面 (GUI)&#xff1a;UiPath Studio 具有直观且用户友…

RT-Thread STM32F407 BMI088--SPI

BMI088是一款高性能6轴惯性传感器&#xff0c;由16位数字三轴24g加速度计和16位数字三轴2000/ s陀螺仪组成。 这里用SPI来驱动BMI088进行数据解读 第一步&#xff0c;首先在 RT-Thread Settings中进行配置 第二步&#xff0c;退出RT-Thread Settings&#xff0c;进入board.h…