vacuum无法清除死行(dead rows)的原因

文章目录

  • 1.需要执行vacuum的原因
  • 2.VACUUM存在的问题:表膨胀
  • 3.查找原因
  • 4.阻止vacuum清理死行的四个原因
    • 4.1 长事务:
    • 4.2 弃用的replication slot和VACUUM:
    • 4.3 孤立的prepared transactions:
    • 4.4 启用 hot_standby_feedback 的备用服务器(standby server)

1.需要执行vacuum的原因

每当update或delete表中的行时,都会留下死行(dead rows)。 VACUUM 将会负责清除它们,以便可以重复使用空间。 如果表没有被清理,它将变得臃肿,这会浪费磁盘空间并减慢全表扫描(以及在较小程度上 - 索引扫描)。
VACUUM 还负责冻结(freezing)表行,以避免transaction ID 计数器回绕时出现问题。
通常不必关心这些,因为 PostgreSQL 中内置的 autovacuum 守护进程会自动完成这些工作。 要了解有关启用和禁用autovacumm的信息,请阅读PG在线文档。

2.VACUUM存在的问题:表膨胀

如果表膨胀,首先要检查的是 autovacuum 是否处理了它们:

SELECT schemaname, relname, n_live_tup, n_dead_tup, last_autovacuum
FROM pg_stat_all_tables
ORDER BY n_dead_tup/ (n_live_tup* current_setting('autovacuum_vacuum_scale_factor')::float8+ current_setting('autovacuum_vacuum_threshold')::float8)DESC
LIMIT 10;

如果膨胀的表没有显示在此处,n_dead_tup 为零且last_autovacuum 为NULL,则统计收集可能存在问题。
如果膨胀的表位于顶部,但 last_autovacuum 为 NULL,则可能需要将 autovacuum 配置为更积极。

但有时结果会是这样:

 schemaname |    relname   | n_live_tup | n_dead_tup |   last_autovacuum
------------+--------------+------------+------------+---------------------public     | t1           |        500   |      500 | 2024-03-13 11:05:18pg_catalog | pg_attribute |         42 |        165 |pg_catalog | pg_amop      |        871 |        162 |pg_catalog | pg_class     |          9 |         31 |pg_catalog | pg_type      |         17 |         27 |pg_catalog | pg_index     |          5 |         15 |pg_catalog | pg_depend    |       9162 |        471 |pg_catalog | pg_trigger   |          0 |         12 |pg_catalog | pg_proc      |        183 |         16 |pg_catalog | pg_shdepend  |          7 |          6 |

以上显示最近运行了 autovacuum,但它却没有释放死元组!

3.查找原因

可以通过运行 VACUUM (VERBOSE) 来验证问题:

vacuum (verbose) public.t1

输出如下:

INFO: vacuuming “public.t1”
INFO: “t1”: found 0 removable, 1000 nonremovable row versions in 5 out of 5 pages
DETAIL: 500 dead row versions cannot be removed yet, oldest xmin: 33783784
There were 0 unused item pointers.
Skipped 0 pages due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
VACUUM
Query returned successfully in 78 msec.

为什么 VACUUM 未能删除死行?
因为VACUUM 只会移除那些“不再需要”的行版本(也称为“元组”)。如果删除事务的事务ID(存储在 xmax 系统列中)比 PostgreSQL 数据库中仍然活跃的最老事务的事务 ID(或者对于共享表而言,整个集群中的最老事务)要旧,那么该元组就被视为“不再需要”。

在上面的 VACUUM 输出中,这个值(33783784)称为“xmin horizon”。

4.阻止vacuum清理死行的四个原因

在 PostgreSQL 集群中,有三件事会阻碍这个 xmin 范围:

4.1 长事务:

SELECT pid, datname, usename, state, backend_xmin, backend_xid
FROM pg_stat_activity
WHERE backend_xmin IS NOT NULL OR backend_xid IS NOT NULL
ORDER BY greatest(age(backend_xmin), age(backend_xid)) DESC;

可以使用 pg_terminate_backend() 函数来终止阻止 VACUUM 的数据库会话。

pg_terminate_backend() 

4.2 弃用的replication slot和VACUUM:

application slot是一种数据结构,它可以防止 PostgreSQL 服务器丢弃仍然需要的信息,这些信息对于备用服务器来说是必要的,以便跟上主服务器的步伐。
可以使用以下查询找到所有application slot及其 xmin 值:

SELECT slot_name, slot_type, database, xmin
FROM pg_replication_slots
ORDER BY age(xmin) DESC;

使用 pg_drop_replication_slot() 函数删除不再需要的application slot。

 pg_drop_replication_slot() 

注意:只有当 hot_standby_feedback = on 时,才会在物理复制中发生这种情况。 对于逻辑复制也存在类似的危险,但它只影响系统catalog。 在这种情况下,请检查 Catalog_xmin 列。

4.3 孤立的prepared transactions:

在两阶段提交期间,首先使用 PREPARE 语句准备分布式事务,然后使用 COMMIT PREPARED 语句提交。
一旦 Postgres 准备好事务,该事务就会保持“挂起”状态,直到 Postgres 提交或中止它。 它甚至必须在服务器重新启动后继续存在! 通常,事务不会长时间保持"prepared"状态,但有时会出现问题,管理员必须手动删除"prepared"的事务。
可以使用以下查询找到所有准备好的交易及其 xmin 值:

SELECT gid, prepared, owner, database, transaction AS xmin
FROM pg_prepared_xacts
ORDER BY age(transaction) DESC;

使用 ROLLBACK PREPARED SQL 语句删除准备好的事务。

ROLLBACK PREPARED

4.4 启用 hot_standby_feedback 的备用服务器(standby server)

通常,流复制设置中的主服务器不关心备用服务器上运行的查询。 因此,VACUUM 会很高兴地删除死行,备用数据库上长时间运行的查询可能仍然需要这些死行,这可能会导致复制冲突。 为了减少复制冲突,可以在备用服务器上设置hot_standby_feedback = on。 然后,备用数据库将向主数据库通报最旧的打开事务,并且主数据库上的 VACUUM 不会删除备用数据库上仍需要的旧行版本。
要找出所有备用服务器的 xmin,您可以在主服务器上运行以下查询:

SELECT application_name, client_addr, backend_xmin
FROM pg_stat_replication
ORDER BY age(backend_xmin) DESC;

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

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

相关文章

注意:腾讯云轻量应用服务器地域选择攻略,选错很麻烦!

腾讯云轻量应用服务器地域如何选择?地域就近选择,北方选北京地域、南方选广州地域,华东地区选上海地域。广州上海北京地域有什么区别?哪个好?区别就是城市地理位置不同,其他的差不多,不区分好坏…

AI壁纸号一周增加上千粉丝,轻松变现的成功案例分享

前言 随着AI绘画技术的发展,传统的互联网副业壁纸号在新的技术加持下迎来了第二春。本文将分享一位壁纸号创作者的成功案例,并为大家提供创作门槛和硬件要求等相关信息。 该项目的创作门槛极低,基本上可以由AI完成内容创作。不过&#xff0…

界面开发框架DevExpress XAF v24.1新版预告 - 跨平台应用UI(二)

DevExpress XAF是一款强大的现代应用程序框架,允许同时开发ASP.NET和WinForms。XAF采用模块化设计,开发人员可以选择内建模块,也可以自行创建,从而以更快的速度和比开发人员当前更强有力的方式创建应用程序。 本文中的内容概述了…

【算法积累】辗转相除法

【算法积累】辗转相除法,python实现两种 辗转相除法(又称欧几里得算法)减法(不常用)代码实现执行结果 辗转相除法代码实现执行结果 辗转相除法(又称欧几里得算法) 又称欧几里得算法&#xff0c…

使用helm部署clickhouse

(作者:陈玓玏) 前置条件 已安装 Kubernetes 集群; 已安装 Helm 包管理工具。 部署 1 添加 RadonDB ClickHouse 的 Helm 仓库 helm repo add ck https://radondb.github.io/radondb-clickhouse-kubernetes/ helm repo upd…

苹果Vision Pro+:医疗领域创新引领者

在数字化浪潮的推动下,苹果以其前沿的Vision Pro技术,正引领着医疗领域迈向全新的创新高峰。该公司深信,通过数字化技术与传统医疗领域的深度融合,可以创造出更多创新性和实用性的解决方案,为患者和医护人员带来前所未…

【算法设计】实验四回溯算法(附源代码)

这里写目录标题 一、上机目的二、上机内容与要求三、上机步骤四、上机结果1、将课本5.2节算法改为程序,并输入数据及进行测试;2、自学5.4节,并完成符号三角形问题。 一、上机目的 1、通过回溯法的示例程序理解回溯法的基本思想; …

信号处理-探索相邻数据点之间的变化和关联性的操作方法

当前值减去前一个值,乘上当前值与前一个值差值的绝对值 当前值减去后一个值,乘上当前值与后一个值差值的绝对值。 意义何在? 当前值减去前一个值:表示当前数据点与前一个数据点之间的变化量。当前值与前一个值差值的绝对值&…

Pycharm的Project Structure (项目结构)

文章目录 一、Sources二、Tests三、Exeluded四、Namespace packages五、Templates六、Resources 一、Sources 源代码根目录:包含项目的主要源代码,它会在这个目录下搜索代码,然后自动补全和只能提示都通过这里的代码提供。若项目运行自定义代…

luatos框架中LVGL如何使用中文字体〈二〉编写脚本设置中文字体

本节内容,将和大家一同学习,在luatos环境中,使用lvgl库,一步步的编译固件、编写脚本,最终实现中文字体的显示。 芯片:AIR101 LCD屏:ST7789 上一节,我们一同学习了,硬件引…

使用vue动态在列表中添加或者删除某一行

** 使用vue动态在列表中添加或者删除某一行 ** 先看一下展示的效果&#xff1a; 好了上代码&#xff1a; 样式界面&#xff1a; <template><div class"container"><h4 style"margin-left: 20px;">线路停靠站站点</h4><el-b…

无缝集成 MongoDB Relational Migrator,Tapdata 提供关系型到 MongoDB 实时迁移优化方案

在去年的 MongoDB 用户大会纽约站上&#xff0c;MongoDB 正式宣布全面推出新工具 MongoDB Relational Migrator&#xff08;MongoDB RM&#xff09;&#xff0c;用以简化应用程序迁移和转换——即从传统关系型数据模型到现代的文档数据模型&#xff0c;助力组织快速提升运营效率…

C#控制台应用程序

C#控制台应用程序时基于文本的&#xff0c;在命令行中运行。它们通常执行需要编写的脚本的简单任务&#xff0c;例如编译文件或加密配置文件的一部分。 一、向用户显示输出 控制台应用程序执行的两个最常见的任务是写入和读取数据&#xff0c;前者使用WriteLine、Write方法来…

数字图像处理 使用C#进行图像处理九 实现傅里叶变换

一、简述 傅立叶变换将图像分解为其正弦和余弦分量。换句话说,它将图像从空间域变换到频率域。这个想法是任何函数都可以用无限正弦函数和余弦函数之和来精确近似。傅里叶变换是实现此目的的一种方法。 网上有很多关于傅里叶变换的文章,这里就不进行赘述了,这里主要结合代码…

java中xml概述

1.xml 1.1概述【理解】 万维网联盟(W3C) 万维网联盟(W3C)创建于1994年&#xff0c;又称W3C理事会。1994年10月在麻省理工学院计算机科学实验室成立。 建立者&#xff1a; Tim Berners-Lee (蒂姆伯纳斯李)。 是Web技术领域最具权威和影响力的国际中立性技术标准机构。 到目前为…

山东省各地市“专精特新”补贴奖励政策汇总

“专精特新”已成为我国经济领域的热词。国家高度重视中小企业发展&#xff0c;对“专精特新”企业的支持更是上升至国家层面。在国家政策引导下&#xff0c;各地各部门为加快培育“专精特新”企业&#xff0c;推动产业链创新链协同发展&#xff0c;采取了一系列举措&#xff0…

java中常见的设计模式以及常见的面试题

在Java中&#xff0c;常见的设计模式同样包括创建型模式、结构型模式和行为型模式。下面是一些在Java中特别常见的设计模式及其简要描述&#xff1a; 创建型模式&#xff1a; 单例模式&#xff08;Singleton Pattern&#xff09;&#xff1a;确保一个类只有一个实例&#xff…

element ui 中文离线文档(百度云盘下载)

一般内网开发上不了网&#xff0c;用离线版本比较方便&#xff0c;下载地址&#xff1a; https://download.csdn.net/download/li836779537/88355878?spm1001.2014.3001.5503 下载后里面有个 index.hrml 双击打开就可以用 效果如下&#xff1a;

Python程序设计基础——代码习题

1 __name__属性 import demodef main():if __name__ __main__:print(这个程序被直接运行。)elif __name__demo:print(这个程序作为模块被使用。) main()3.3 编写程序&#xff0c;生成包含1000个0~100之间的随机整数&#xff0c;并统计每个元素出现的次数。 import randomx[r…

[word[::-1] for word in s.split()] 得到的是一个列表

你可以将上述的列表推导式代码拆分为更明确的几个步骤&#xff0c;如下所示&#xff1a; # 原始字符串 s "hello world" # 使用 split() 方法将字符串分割成单词列表 words s.split() # 创建一个空列表&#xff0c;用于存储反转后的单词 reversed_words [] # 遍历…