一、为什么是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 语句删除准备好的事务。

 

最新文章

  1. 2DToolkit官方文档中文版打地鼠教程(三):Sprite Collections 精灵集合
  2. MyEclipse使用前优化与配置
  3. 网站上点击自定义按钮发起QQ聊天的解决方案
  4. lucene 3.0.2 基本操作入门
  5. BZOJ 3289 Mato的文件管理(莫队+离散化求逆序数)
  6. angularjs制作的iframe后台管理页切换页面
  7. 关于(x&y)+((x^y)>>1)的探究
  8. NYNU_省赛选拔题(7)
  9. 创建android phonegap项目
  10. 安卓组件-BroadcastReceiver
  11. .Net基础体系和跨框架开发普及
  12. Android Debug Bridge
  13. 云主机和vps的区别
  14. laravel-admin 上传图片过程中遇到的问题
  15. luogu P2387 [NOI2014]魔法森林
  16. Android Studio 解决ADB检测不到手机导致无法连接的问题
  17. [Spark][Python]Spark 访问 mysql , 生成 dataframe 的例子:
  18. Go Example--常量
  19. Mac 下使用 brew 安装软件
  20. 安装/移除 MySQL 服务

热门文章

  1. 网络基础与osi七层与TCP/IP协议
  2. 监控Windows(生成php木马)
  3. 第五篇:前端之JQuery
  4. JavaScript:操作符:逻辑运算符及其隐式转换数据类型
  5. 一款极简的流媒体Web服务器(Streaming Media Web Server),提供视频音乐的在线播放功能
  6. Sql Server中order by对varchar类型排序结果不对
  7. Spark详解(07) - SparkStreaming
  8. 数据分析中的SQL如何解决业务问题
  9. lwl-resume 个人简历编辑使用说明
  10. DevGridView表格导出自定义页脚