当前位置: 首页 > article >正文

【PostgreSQL里vacuum但是无法回收死元组的原因】

PostgreSQL数据库里的vacuum/autvacuum在我们日长的使用中可能会遇到很多问题,例如vacuum被阻塞,vacuum时间长,vacuum成功执行后,仍旧无法回收死元组等等。,本文主要介绍PostgreSQL的vacuum成功执行后,仍旧无法回收死元组的几种原因。

1.失效复制槽

select * from pg_replication_slots;

//删除失效的复制槽
SELECT pg_drop_replication_slot('slot_name');

2.长事务导致

如果数据库中存在长时间运行的事务,VACUUM 操作可能会被阻塞。这是因为 VACUUM 需要确保没有任何事务仍在访问那些它试图清理的行。如果有一个长事务存在,那长事务时间的其它表也没办法Vacuum,因为它不确认你是否会查其它表。


//根据事物开启时间排序
 SELECT  datname,
      usename,
      query,
      xact_start,
      now()-xact_start xact_duration,
      query_start,
      now()-query_start query_duration, state
FROM pg_stat_activity
WHERE state<>$$idle$$
    AND (backend_xid is NOT null
    OR backend_xmin is NOT null)
AND pid !=pg_backend_pid()
ORDER BY xact_start DESC;

//大于30min的长事务
 SELECT  datname,
      usename,
      query,
      xact_start,
      now()-xact_start xact_duration,
      query_start,
      now()-query_start query_duration, state
FROM pg_stat_activity
WHERE state<>$$idle$$
    AND (backend_xid is NOT null
    OR backend_xmin is NOT null)
    AND now()-xact_start > interval $$30 min$$
ORDER BY xact_start;



3.存在未提交的prepare事务


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

//大于30min的预处理语句
 SELECT  name,
      statement,
      prepare_time,
      now()-prepare_time,
      parameter_types, from_sql
FROM pg_prepared_statements
WHERE now()-prepare_time > interval $$30 min$$
ORDER BY prepare_time DESC;

4.idle in transaction状态的事务

select * from pg_stat_activity where state='idle in transaction';

VACUUM 依赖于事务的快照。如果某个事务正在运行并持有对某些数据的锁,VACUUM 可能会等待这个事务完成才能清理死元组。即使 VACUUM 执行完了,如果相关的事务没有提交,这些死元组仍然存在。

5.函数等内部结构涉及到表的访问

函数等内部结构涉及到表的访问,可以通过pg_locks去间接验证。

select * from pg_locks where relation='表名'::regclass ;

6.hot_standby_feedback参数问题

hot_standby_feedback参数打开,备库将向主库通报最旧的打开事务,并且主数据库上的 VACUUM 不会删除备用数据库上仍需要的旧行版本。

7.索引状态问题

VACUUM 处理表的死元组时也会扫描索引。如果索引存在问题或者不一致,可能导致死元组无法被清理。
解决方案: 确保索引状态,如不正常考虑重建索引。

select indexrelid::regclass,indrelid::regclass,indisvalid,indisready,indislive 
from pg_index where indisvalid='f';

8.表和索引的并发访问

如果表和索引正在被其他并发操作访问,可能会导致 VACUUM 无法完全清理死元组。

select * from pg_stat_activity where query like '%表名%' AND pid !=pg_backend_pid();

http://www.kler.cn/a/309060.html

相关文章:

  • 微服务各组件整合
  • C获取程序名称的方法
  • C++模板特化实战:在使用开源库boost::geometry::index::rtree时,用特化来让其支持自己的数据类型
  • 继承和多态(上)
  • 前端神经网络入门(三):深度学习与机器学习的关系、区别及核心理论支撑 - 以Brain.js示例
  • 【Webpack实用指南】如何拆分CSS资源(2)
  • 解决 Docker 端口映射错误:“No public port ‘80’ published”
  • linux驱动开发-内核并发控制
  • 【网络安全】分享4个高危业务逻辑漏洞
  • 软件测试工程师面试整理-测试工具
  • unity UnityWebRequest 的request.downloadHandler 空应用
  • 承压设备032认证-全网最全解读
  • 随笔十一、wsl子系统ubuntu磁盘清理
  • 在Ubuntu 18.04上安装R的方法
  • navicate远程linux上的pgsql提示密码失败
  • Effective C++笔记之二十三:非void函数不写return
  • 基于STM32的非接触式红外测温系统
  • 采用qt做一个命令行终端
  • 计算机人工智能前沿进展-大语言模型方向-2024-09-17
  • Vue点击按钮生成pdf文件/Vue点击按钮生成png图片
  • AJAX(一)HTTP协议(请求响应报文),AJAX发送请求,请求问题处理
  • SAM 2: Segment Anything in Images and Videos
  • c语言中“typedef”关键字,对类型进行重命名
  • 渗透测试入门学习——php文件上传与文件包含
  • ubuntu个人实用配置问题
  • 零基础小白能学网络安全吗?