代码之家  ›  专栏  ›  技术社区  ›  ddd

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

  •  8
  • ddd  · 技术社区  · 8 年前

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

    enter image description here

    令人惊讶的是,即使在我手动运行 vacuum 在某些表上执行命令时,它似乎根本没有删除这些死元组。 vacuum full 完成时间太长,通常会在一整晚后超时。

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

    2 回复  |  直到 8 年前
        1
  •  17
  •   Laurenz Albe    7 年前

    使用 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_cancel_backend() or pg_terminate_backend() .

    2. 存在尚未提交的已准备交易记录。你可以用

      SELECT gid, prepared, owner, database, transaction
      FROM pg_prepared_xacts
      ORDER BY age(transaction) DESC;
      

      使用者 COMMIT PREPARED 或 ROLLBACK PREPARED 关闭它们。

    3. 有 replication slots 未使用的。找到他们

      SELECT slot_name, slot_type, database, xmin
      FROM pg_replication_slots
      ORDER BY age(xmin) DESC;
      

      使用 pg_drop_replication_slot() 删除未使用的复制插槽。

        2
  •  0
  •   Vao Tsun    8 年前

    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_vacuum_threshold , ( ALTER TABLE )此处引用: https://www.postgresql.org/docs/current/static/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS