MVCC 下的 relpages 和 reltuples

Relpages and reltuples under MVCC

如果我理解正确,在MVCC(多版本并发控制)下,死元组留在页面中,直到Vacuum进来并将它们标记为“未使用”,直到“vacuum full”进来并重新组织它们对 space 进行碎片整理——因此我们对相同的数据使用较少的 space。

我有一个 table,在一个尚未完成的环境中 vacuum full 大约有:

SELECT relpages, reltuples from pg_class where relname='pg_toast_16450';
 relpages  |  reltuples
-----------+--------------
 544447814 | 6.394397e+06

在经历过 vacuum full 的另一个环境中有:

SELECT relpages, reltuples from pg_class where relname='pg_toast_16450';
 relpages |  reltuples
----------+--------------
  2476625 | 4.439228e+06

看起来 relpages 确实大幅下降,这符合我的理解。但是,reltuples 没有。 (relpages 有 250 倍的变化,而 reltuples 只有 1.33X)这是否意味着 reltuples 不包括死元组?如果是这样的话,使用 reltuples 设计查询计划的查询计划器是否有办法绕过死元组?

reltuples 是 table 中活动行数的估计值。正如 the documentation 所说,

It is updated by VACUUM, ANALYZE, and a few DDL commands such as CREATE INDEX.

因此,如果最后一个这样的命令(可能由 autovacuum 触发)在 table 上有 运行,那么数字总是会略有偏差,而 VACUUM (FULL) 会解决这个问题。

然而,还有第二件事要考虑,因为这是一个 TOAST table:它可能包含一些属于 table 中死行的条目。死行的 TOAST 条目本身不一定是死的,但 VACUUM (FULL) 不会复制它们,因此数量可以额外减少。我怀疑这已经发生了,因为这个数字减少了超过我预期的 10%。