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

时间:2017-12-21 03:41:13

标签: postgresql vacuum

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

enter image description here

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

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

2 个答案:

答案 0 :(得分: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()删除未使用的复制槽。

答案 1 :(得分: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