我们在Amazon RDS中有一个postgres数据库。最初,我们需要快速加载大量数据,因此根据best practice suggestion from Amazon关闭autovacuum
。最近我在运行查询时发现了一些性能问题。然后我意识到它已经很长时间没有被吸尘了。事实证明,许多表都有很多死元组。
令人惊讶的是,即使我在某些表上手动运行vacuum
命令,它似乎根本不会删除这些死元组。 vacuum full
需要很长时间才能完成,这通常会在一整夜之后结束。
为什么vacuum
命令不起作用?我的其他选择是什么,重启实例?
答案 0 :(得分:3)
使用VACUUM (VERBOSE)
详细了解它的作用和原因。
无法删除死元组有三个原因:
有一个尚未关闭的长时间运行的事务。你可以找到坏男孩
SELECT pid, datname, usename, state, backend_xmin
FROM pg_stat_activity
WHERE backend_xmin IS NOT NULL
ORDER BY age(backend_xmin) DESC;
有准备好的交易尚未提交。你可以用
找到它们SELECT gid, prepared, owner, database, transaction
FROM pg_prepared_xacts
ORDER BY age(transaction) DESC;
用户COMMIT PREPARED
或ROLLBACK PREPARED
关闭它们。
有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