postgresql VACUUM 不会从表中删除死行的三个原因
一、为什么是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 VACUUM 不会从表中删除死行的三个原因的更多相关文章
- InnoDB引擎,从大表中删除多行
官方建议: InnoDB Tables If you are deleting many rows from a large table, you may exceed the lock table ...
- 一定要 先删除 sc表 中的 某元组 行,,, 再删除 course表中的 元组行
一定要 先删除 sc表 中的 某元组 行,,, 再删除 course表中的 元组行 course表 SC表 删除 course表中的 元组行,,出现错误 sc ---->参 ...
- 解决在mysql表中删除自增id数据后,再添加数据时,id不会自增1的问题
https://blog.csdn.net/shaojunbo24/article/details/50036859 问题:mysql表中删除自增id数据后,再添加数据时,id不会紧接.比如:自增id ...
- SQL语句的使用,SELECT - 从数据库表中获取数据 UPDATE - 更新数据库表中的数据 DELETE - 从数据库表中删除数据 INSERT INTO - 向数据库表中插入数据
SQL DML 和 DDL 可以把 SQL 分为两个部分:数据操作语言 (DML) 和 数据定义语言 (DDL). SQL (结构化查询语言)是用于执行查询的语法. 但是 SQL 语言也包含用于更新. ...
- SQL中将某个表中的多行数据在一个字段显示
项目需求:将某个表中的多行数据在一个字段显示,如下: 比如表A中有字段 ID,NAME, 表B中有字段ID,PID,DES, 表A,表B中的数据分别如下: ID NAME1 张三2 李四 ID PID ...
- INSERT - 在表中创建新行
SYNOPSIS INSERT INTO table [ ( column [, ...] ) ] { DEFAULT VALUES | VALUES ( { expression | DEFAULT ...
- 函数模块:CTVB_COMPARE_TABLES--两个表中删除/变更/粘贴分解
这个函数模块比较两个内表,将被删除.增加和修改的内表行分别分组输出. 输入参数:TABLE_OLD:旧表TABLE_NEW:新表KEY_LENGTH:键长度,指定内表中的前若干个字节(在 Unicod ...
- 从表中删除重复记录的sql
--有一个表,假设是这样的 CREATE TABLE Test ( field1 ) primary key, field2 )); --假设field1上有索引. 要删除表中所有field1重复的记 ...
- MYSQL delete 从多人表中删除
语法 1. delete table_list_A from table_list_B where bool_expression; 从delete_table_list_A 删除 bool expr ...
- C# DataAdapter.Update() 无法更新数据表中删除的数据行
用DataAdapter.Update() 方法更新删除了部分DataRow 的 DataTable .但是数据库中的数据没有随着更新而变化. 原因:DataTable 删除 DataRow 时,使用 ...
随机推荐
- 【每日一题】2021年12月11日-69. Sqrt(x)/x的平方根
给你一个非负整数 x ,计算并返回 x 的 算术平方根 . 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 . 注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或 ...
- 【FAQ】申请Health Kit权限的常见问题及解答
华为运动健康服务(HUAWEI Health Kit)提供原子化数据开放,用户数据被授权获取后,应用可通过接口访问运动健康数据,对相关数据进行增.删.改.查等操作.这篇文章汇总了申请开通Health ...
- week_4
Andrew Ng 机器学习笔记---by Orangestar Week4_Neural Networks : Representation 1. Non-linear Hypotheses 当特征 ...
- ESXI 7.0封装网卡驱动
前段时间配置的All In One 主机,由于华擎H410M-ITX/AC主板的板载网卡为intel I219-V,在安装ESXI后网卡无法驱动.查询之后发现原来ESXI7.0.2的版本不含该网卡驱动 ...
- 腾讯微信开源数据库PhxSQL简单部署记录
1.建立文件夹与互信关系 [root@mysql-100 ~]# mkdir -p /app/soft/phxsql [root@mysql-100 phxsql]# ssh-keygen -t rs ...
- (22)go-micro微服务kibana使用
目录 一 kibana介绍 二 Kibana主要功能 三 Kibana侧边栏 四 Kibana安装 1.拉取镜像 2.运行命令 3.查看是否运行 五 Kibana使用 六 Kibana图形化界面 七 ...
- 都用过@Autowired,但你知道它是怎么实现的吗
前言 在使用Spring开发的时候,配置的方式主要有两种,一种是xml的方式,另外一种是 java config的方式.在使用的过程中java config,我们难免会与注解进行各种打交道,其中,我们 ...
- LinkedList集合-Vector集合
LinkedList集合 java.util.LinkedList集合数据存储的结构是链表结构.方便元素添加.删除的集合.LinkedList是一个双向链表,那么双向链表是什么样子的呢,我们用个图了解 ...
- Quartz.Net 官方教程 Best Practices
最佳实践 JobDataMap 建议只存储基本数据(含String),避免序列化问题 作业执行期间,JobDetail和Trgger的底层共用一个JobDataMap 实例,因此Trigger的数据会 ...
- Linux存储服务
存储服务 一.概述 存储:用于存放用户上传的内容(数据),一般应用在网站集群中 为什么要存储? 如果不使用存储,用户上传的数据就直接存放在某一台网站服务器上了,用户下次访问就可能找不到 如果使用存储, ...