Postgres:"vacuum" 命令不清除死元组
Postgres: "vacuum" command does not clean up dead tuples
我们在 Amazon RDS 中有一个 postgres 数据库。最初,我们需要快速加载大量数据,所以根据best practice suggestion from Amazon关闭了autovacuum
。最近我在 运行 查询时注意到一些性能问题。然后我意识到它已经很久没有吸尘了。事实证明,许多表都有很多死元组。
令人惊讶的是,即使我在某些表上手动执行 运行 vacuum
命令后,它似乎也根本没有删除这些死元组。 vacuum full
完成时间太长,通常会在一整夜后超时。
为什么 vacuum
命令不起作用?我的其他选择是什么,重启实例?
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,他们还明确建议使用它:
Important
Not running autovacuum can result in an eventual required outage to
perform a much more intrusive vacuum operation.
取消所有会话并清理 table 应该有助于解决以前的死元组(关于您重启集群的建议)。但我建议您首先做的是 - 打开 autovacuum。最好控制 table 上的真空,而不是 autovacuum_vacuum_threshold
整个集群上的真空,(ALTER TABLE
) 参考:https://www.postgresql.org/docs/current/static/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS
使用 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
or ROLLBACK PREPARED
关闭它们。
还有replication slots没有用到。用
找到他们
SELECT slot_name, slot_type, database, xmin
FROM pg_replication_slots
ORDER BY age(xmin) DESC;
使用pg_drop_replication_slot()
删除未使用的复制槽。
我们在 Amazon RDS 中有一个 postgres 数据库。最初,我们需要快速加载大量数据,所以根据best practice suggestion from Amazon关闭了autovacuum
。最近我在 运行 查询时注意到一些性能问题。然后我意识到它已经很久没有吸尘了。事实证明,许多表都有很多死元组。
令人惊讶的是,即使我在某些表上手动执行 运行 vacuum
命令后,它似乎也根本没有删除这些死元组。 vacuum full
完成时间太长,通常会在一整夜后超时。
为什么 vacuum
命令不起作用?我的其他选择是什么,重启实例?
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,他们还明确建议使用它:
Important
Not running autovacuum can result in an eventual required outage to perform a much more intrusive vacuum operation.
取消所有会话并清理 table 应该有助于解决以前的死元组(关于您重启集群的建议)。但我建议您首先做的是 - 打开 autovacuum。最好控制 table 上的真空,而不是 autovacuum_vacuum_threshold
整个集群上的真空,(ALTER TABLE
) 参考:https://www.postgresql.org/docs/current/static/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS
使用 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
orROLLBACK PREPARED
关闭它们。还有replication slots没有用到。用
找到他们SELECT slot_name, slot_type, database, xmin FROM pg_replication_slots ORDER BY age(xmin) DESC;
使用
pg_drop_replication_slot()
删除未使用的复制槽。