Postgres:“vacuum”命令不会清除死元组

问题描述 投票:2回答:2

我们在Amazon RDS中有一个postgres数据库。最初,我们需要快速加载大量数据,因此根据autovacuum关闭了best practice suggestion from Amazon。最近我在运行查询时发现了一些性能问题。然后我意识到它已经很长时间没有被吸尘了。事实证明,许多表都有很多死元组。

enter image description here

令人惊讶的是,即使我在某些表上手动运行vacuum命令,它似乎也没有删除这些死元组。 vacuum full需要很长时间才能完成,这通常会在一整夜之后结束。

为什么vacuum命令不起作用?我的其他选择是什么,重启实例?

postgresql vacuum
2个回答
3
投票

使用VACUUM (VERBOSE)获取有关它正在做什么以及为什么做的详细统计数据。

无法删除死元组有三个原因:

  1. 有一个尚未关闭的长期运行事务。你可以找到坏男孩 SELECT pid, datname, usename, state, backend_xmin FROM pg_stat_activity WHERE backend_xmin IS NOT NULL ORDER BY age(backend_xmin) DESC; 你可以用pg_cacnel_backend() or pg_terminate_backend()摆脱交易。
  2. 有准备好的交易尚未提交。你可以找到它们 SELECT gid, prepared, owner, database, transaction FROM pg_prepared_xacts ORDER BY age(transaction) DESC; 用户COMMIT PREPAREDROLLBACK PREPARED关闭它们。
  3. replication slots没有使用。找到他们 SELECT slot_name, slot_type, database, xmin FROM pg_replication_slots ORDER BY age(xmin) DESC; 使用pg_drop_replication_slot()删除未使用的复制槽。

0
投票

https://dba.stackexchange.com/a/77587/30035解释了为什么不删除所有死元组。

vacuum full不要超时,设置statement_timeout = 0

http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_BestPractices.html#CHAP_BestPractices.PostgreSQL建议在数据库恢复时禁用autovacuum,进一步他们建议使用它:

重要

不运行autovacuum可能导致最终需要中断以执行更具侵入性的真空操作。

取消所有会话和清理表应该有助于以前的死元组(关于重新启动集群的建议)。但我建议你先做的事情 - 切换autovacuum。更好的可能控制真空在桌子上,而不是整个集群与autovacuum_vacuum_threshold,(ALTER TABLE)参考这里:https://www.postgresql.org/docs/current/static/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS

© www.soinside.com 2019 - 2024. All rights reserved.