首页 > 数据库 >postgresql VACUUM 不会从表中删除死行的三个原因

postgresql VACUUM 不会从表中删除死行的三个原因

时间:2023-02-28 11:25:27浏览次数:50  
标签:事务 postgresql autovacuum 从表中 catalog pg VACUUM xmin

一、为什么是VACUUM?

每当更新或删除PostgreSQL表中的行时,都会留下死元组。VACUUM摆脱了它们,以便空间可以重复使用。如果一个表没有被清理,它就会变得臃肿,这会浪费磁盘空间并减慢表的顺序扫描(以及索引扫描)。VACUUM还负责冻结表行,以避免在事务ID计数器环绕时出现问题,但这是另一回事。通常,您不必处理所有这些,因为PostgreSQL中内置的autovacuum 守护程序会为您完成这些工作。

二、问题

如果你的表变得臃肿,首先你需要检查的是 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是0并且last_autovacuum是 NULL,你可能有统计信息收集器的问题。

如果臃肿的表就在顶部,但last_autovacuum为NULL,则您可能需要将autovacuum 配置为更积极,以便完成对表的处理。

但有时结果会如下所示:

schemaname |    relname   | n_live_tup | n_dead_tup |   last_autovacuum
------------+--------------+------------+------------+---------------------
 laurenz    | vacme        |      50000 |      50000 | 2018-02-22 13:20:16
 pg_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 |
(10 rows)

autovacuum最近在这里运行,但它没有释放死元组!

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

test=> VACUUM (VERBOSE) vacme;
INFO:  vacuuming "laurenz.vacme"
INFO:  "vacme": found 0 removable, 100000 nonremovable row versions in
       443 out of 443 pages
DETAIL:  50000 dead row versions cannot be removed yet,
         oldest xmin: 22300
There were 0 unused item pointers.
Skipped 0 pages due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 0.01 s, system: 0.00 s, elapsed: 0.01 s.

三、为什么VACUUM不能删除死元组?

VACUUM只能删除不再需要的那些行版本(也称为“元组”)。如果删除事务的事务 ID(存储在xmax中)早于 PostgreSQL 数据库(或共享表的整个集群)中仍处于活动状态的最旧事务,则无法清除元组。

这个值(VACUUM上面输出中的 22300)称为“xmin 水平”。

在 PostgreSQL集群中,有三件事可以阻止这个xmin范围:

1、长时间运行的事务:

可以通过以下查询找到长时间运行的事务及其xmin值:

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

可以使用该pg_terminate_backend()函数来终止阻止您的VACUUM.

2、废弃的Replication Slot:

复制槽是一种数据结构,保持从主库丢弃但仍需要由备用服务器赶上主要信息PostgreSQL服务器的数据。

如果复制延迟或备用服务器关闭,复制槽将阻

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

使用该pg_drop_replication_slot()函数删除不再需要的复制槽。

注意:如果hot_standby_feedback = on. 对于逻辑复制存在类似的危险(无法回收元组),但只有系统目录受到影响。catalog_xmin在这种情况下检查列。

hot_standby_feedback参数之后备库会定期向主库通知最小活跃事务id(xmin)值,这样使得主库vacuum进程不会清理大于xmin值的事务。

3、孤立的准备运行的事务:

两阶段提交期间,分布式事务首先用PREPARE语句准备,然后用COMMIT PREPARED语句提交。

一旦一个事务准备好,它就会一直“等待”直到它被提交或中止。它甚至必须在服务器重启后还需要保留下来!通常,事务不会长时间保持准备状态,但有时会出错,必须由管理员手动删除准备好的事务。

可以xmin使用以下查询找到所有准备好的交易及其价值:

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

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

 

 

标签:事务,postgresql,autovacuum,从表中,catalog,pg,VACUUM,xmin
From: https://www.cnblogs.com/zhenren001/p/17163317.html

相关文章

  • mybatis plus映射postgreSQL数组
    首先自定义一个数组处理器packagecom.ctsy.l3a1.handler;importorg.apache.ibatis.type.BaseTypeHandler;importorg.apache.ibatis.type.JdbcType;importorg.apa......
  • KingbaseES V8R6 集群环境备库不结束旧事务快照将影响主库的vacuum操作
    前言昨天同事遇到了一个有关vacuum的典型问题。V8R6读写分离集群环境,一主多备。版本:kingbaseesv008r006c004问题现象:主库日常巡检发现日志大量记录:waring:oldestxmi......
  • 必看!PostgreSQL参数优化
    前不久,一个朋友所在的公司,业务人员整天都喊慢。朋友是搞开发的,不是很懂DB,他说他们应用的其实没什么问题,但是就是每天一到高峰期就办理特别的慢啊,各种堵塞,一堆请求无法完成......
  • 数据库 postgresql 监控 IO 脚本
    #!/bin/bash##########################################################查看当前1分钟负载大于50,自动kill超10秒长查询##########################################......
  • Spring 保存带Array字段的记录到PostgreSQL
    前言本文继续学习PostgreSQL,看到PostgreSQL有个Array字段,感觉可以用来存储某种表,比如股票每天的价格,我们称为market_price表,先来看下最开始market_price表的定义cre......
  • 银河麒麟V10系统的 postgresql/postgis完整部署
    一、posgresql部署1、安装前可以先进行用户以及用户组的配置,方便后面进行授权(通过编译安装也需要,后续步骤会体现)。用户配置#新增用户组groupaddpostgres#创建用户......
  • 10个常见的 PostgreSQL 错误及避坑指南
    PostgreSQL作为当下流行的数据库,不少开发者因其开源、可靠、可扩展等特性把它应用到实际的生产环境中,帮助无数PostgreSQL厂商的Percona编制了一个最常见......
  • 10个常见的 PostgreSQL 错误及避坑指南
    PostgreSQL作为当下流行的数据库,不少开发者因其开源、可靠、可扩展等特性把它应用到实际的生产环境中,帮助无数PostgreSQL厂商的Percona编制了一个最常见......
  • 10个常见的 PostgreSQL 错误及避坑指南
    PostgreSQL作为当下流行的数据库,不少开发者因其开源、可靠、可扩展等特性把它应用到实际的生产环境中,帮助无数PostgreSQL厂商的Percona编制了一个最常见......
  • linux安装postgresql三种方式
    本文转载自:http://blog.itpub.net/29654823/viewspace-2923532/linux下安装PostgreSQL可采用三种方式,二进制已编绎安装包、安装、源码安装三种方式进行安装方式1:yum安装,......