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.mzph.cn/news/147532.shtml

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

相关文章

Git配置代理:fatal: unable to access*** github Failure when receiving data from

~吐槽一下 github自从被微软收购以后,大多数情况没点科技上网都进不去了,还是怀念以前随时访问的时光。 我一直都是开着系统代理的,但是今天拉一个项目发现拉不下来了,报错: fatal: unable to access https://githu…

【Git学习二】时光回溯:git reset和git checkout命令详解

😁 作者简介:一名大四的学生,致力学习前端开发技术 ⭐️个人主页:夜宵饽饽的主页 ❔ 系列专栏:Git等软件工具技术的使用 👐学习格言:成功不是终点,失败也并非末日,最重要…

关于Android音效播放,【备忘】

主要还是希望开箱即用。所以才有了这篇&#xff0c;也是备忘。 以下代码适合Android5.0版本以后 private SoundPool soundPool;//特效播放private Map<String,Integer> soundPoolMap;// Builder buildernew SoundPool.Builder();builder.setMaxStreams(4);///最大…

为什么Go是后端开发的未来

近年来&#xff0c;Go 编程语言的流行度迅速增加。Go 最初由 Google 开发&#xff0c;迅速成为后端开发中最受欢迎的语言之一&#xff0c;特别是在分布式系统和微服务的开发中。本文将讨论为什么 Go 是后端开发的未来。 Go 简介 Go&#xff0c;又称为 Golang&#xff0c;是由…

组合模式 rust和java的实现

文章目录 组合模式介绍实现javarsut 组合模式 组合模式&#xff08;Composite Pattern&#xff09;&#xff0c;又叫部分整体模式&#xff0c;是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象&#xff0c;用来表示部分以及整体层次。这种类型的设计…

探索亚马逊大语言模型:开启人工智能时代的语言创作新篇章

文章目录 前言一、大语言模型是什么&#xff1f;应用范围 二、Amazon Bedrock总结 前言 想必大家在ChatGPT的突然兴起&#xff0c;大家多多少少都会有各种各样的问题&#xff0c;比如&#xff1a;大语言模型和生成式AI有什么关系呢&#xff1f;大语言模型为什么这么火&#xf…

C++二分查找算法:查找和最小的 K 对数字

相关专题 二分查找相关题目 题目 给定两个以 非递减顺序排列 的整数数组 nums1 和 nums2 , 以及一个整数 k 。 定义一对值 (u,v)&#xff0c;其中第一个元素来自 nums1&#xff0c;第二个元素来自 nums2 。 请找到和最小的 k 个数对 (u1,v1), (u2,v2) … (uk,vk) 。 示例 1:…

MFC 对话框

目录 一、对话款基本认识 二、对话框项目创建 三、控件操作 四、对话框创建和显示 模态对话框 非模态对话框 五、动态创建按钮 六、访问控件 控件添加控制变量 访问对话框 操作对话框 SendMessage() 七、对话框伸缩功能实现 八、对话框小项目-逃跑按钮 九、小项…

jQuery Ajax前后端数据交互

ajax是用来做前后端交互的&#xff0c;前端使用ajax去去发送一个请求&#xff0c;后端给其响应拿到数据&#xff0c;前端做些展示。 浏览器访问网站一个页面时&#xff0c; Web 服务器处理完后会以消息体方式返回浏览器&#xff0c;浏览器自动解析 HTML 内容。如果局部有新数…

python算法例15 合并数字

1. 问题描述 给出n个数&#xff0c;将这n个数合并成一个数&#xff0c;每次只能选择两个数a、b合并&#xff0c;合并需要消耗的能量为ab&#xff0c;输出将n个数合并成一个数后消耗的最小能量。 2. 问题示例 给出[1&#xff0c;2&#xff0c;3&#xff0c;4]&#xff0c;返回…

分类预测 | Matlab实现PSO-GRU-Attention粒子群算法优化门控循环单元融合注意力机制多特征分类预测

分类预测 | Matlab实现PSO-GRU-Attention粒子群算法优化门控循环单元融合注意力机制多特征分类预测 目录 分类预测 | Matlab实现PSO-GRU-Attention粒子群算法优化门控循环单元融合注意力机制多特征分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现PSO…

C语言的由来与发展历程

C语言的起源可以追溯到上世纪70年代&#xff0c;由Dennis Ritchie在贝尔实验室开发出来。C语言的设计目标是提供一种简洁、高效、可移植的编程语言&#xff0c;以便于开发底层的系统软件。在那个时代&#xff0c;计算机技术正在迅速发展&#xff0c;出现了多种高级编程语言&…

python二分查找

什么是二分查找&#xff1a; 二分查找又称折半查找&#xff0c;优点是比较次数少&#xff0c;查找速度快&#xff0c;平均性能好&#xff1b;其缺点是要求待查表为有序表&#xff0c;且插入删除困难。因此&#xff0c;折半查找方法适用于不经常变动而查找频繁的有序列表。 首先…

APIcloud 【现已更名 用友开发中心】 iOS发版 应用程序请求用户同意访问相机和照片,但没有在目的字符串中充分说明相机和照片的使用。

iOS 审核时 提示 首次安装软件 获取相机 相册 提示信息 怎么修改 我们注意到你的应用程序请求用户同意访问相机和照片&#xff0c;但没有在目的字符串中充分说明相机和照片的使用。 为了解决这个问题&#xff0c;修改应用信息中的目的字符串是合适的。相机和照片的Plist文件&a…

【C++11】lambda表达式 | 包装器

文章目录 一、 lambda表达式lambda表达式的引入lambda表达式的语法lambda表达式与函数对象lambda表达式的捕捉列表 二、包装器function包装器bind包装器 一、 lambda表达式 lambda表达式的引入 在C98中&#xff0c;为了替代函数指针&#xff0c;C设计出了仿函数&#xff0c;也…

Seaborn 回归(Regression)及矩阵(Matrix)绘图

Seaborn中的回归包括回归拟合曲线图以及回归误差图。Matrix图主要是热度图。 1. 回归及矩阵绘图API概述 seaborn中“回归”绘图函数共3个&#xff1a; lmplot&#xff08;回归统计绘图&#xff09;&#xff1a;figure级regplot函数&#xff0c;绘图同regplot完全相同。(lm指lin…

【计算机网络笔记】IPv6简介

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

websocket详解

一、什么是Websocket WebSocket 是一种在单个 TCP 连接上进行 全双工 通信的协议&#xff0c;它可以让客户端和服务器之间进行实时的双向通信。 WebSocket 使用一个长连接&#xff0c;在客户端和服务器之间保持持久的连接&#xff0c;从而可以实时地发送和接收数据。 在 Web…

ElasticSearch快速入门

一、全文检索 1、什么是全文检索 全文索引是一种通过对文本内容进行全面索引和搜索的技术。它可以快速的在大量文本数据中查找包含特定关键词或短语的文档&#xff0c;并返回相关的搜索结果。 全文检索广泛应用于各种信息管理系统和应用中&#xff0c;如搜索引擎、文档管理系…

Android SdkManager简介

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、 安装使用3.1 安装3.2 使用3.3 选项…