我在摆弄,VACUUM
并注意到一些意外的行为,其中SELECT
从表中读取行似乎减少了VACUUM
以后的工作量。
测试数据
注意:自动真空已禁用
CREATE TABLE numbers (num bigint);
ALTER TABLE numbers SET (
autovacuum_enabled = 'f',
toast.autovacuum_enabled = 'f'
);
INSERT INTO numbers SELECT generate_series(1, 5000);
试验1
现在,我们对所有行进行更新,
UPDATE numbers SET num = 0;
当我们跑步时,VACUUM (VERBOSE) numbers;
我们得到了,
INFO: vacuuming "public.numbers"
INFO: "numbers": removed 5000 row versions in 23 pages
INFO: "numbers": found 5000 removable, 5000 nonremovable row versions in 45 out of 45 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 6585
There were 0 unused item pointers.
试用2
现在我们发布另一个UPDATE
,但是这次我们添加一个SELECT
之后,
UPDATE numbers SET num = 1;
SELECT * FROM numbers;
当我们跑步时,VACUUM (VERBOSE) numbers;
我们得到了,
INFO: vacuuming "public.numbers"
INFO: "numbers": removed 56 row versions in 22 pages
INFO: "numbers": found 56 removable, 5000 nonremovable row versions in 45 out of 45 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 6586
There were 56 unused item pointers.
这里到底发生了什么?在SELECT
从访问的页面中删除死元组之后,为什么我运行第二个版本,就像这样VACUUM
做?
我在macOS 10.14.5上运行Postgres 11.3。
2
您使用哪个客户端来运行命令?是否启用了自动提交功能?
—
mustaccio
我要删除问题“ VACUUM表基本上只是SELECT * FROM表盖吗?” (不是)我认为这是一个很好的跟进,这里的答案很简单,就是SELECT可以删除死行,并且确实与VACUUM共享。它们之间的不同之处将是有关XID过渡的详尽讨论,以及大量其他内容。这个问题基本上是“除了清除死行之外,真空还有什么其他作用”。(有些含糊)
—
Evan Carroll
@mustaccio我使用ActiveRecord使用Ruby脚本对这些测试进行了测试,该脚本使用了引擎盖下的PG gem。我认为默认情况下会启用自动提交,因为除非明确使用了BEGIN,否则您无需发出任何COMMIT。
—
rafbm