raf*_*fbm 9 postgresql select vacuum postgresql-11
我在摆弄VACUUM
并注意到一些意想不到的行为,其中SELECT
从表中ing 行似乎减少了VACUUM
之后必须做的工作。
注意:autovacuum 被禁用
CREATE TABLE numbers (num bigint);
ALTER TABLE numbers SET (
autovacuum_enabled = 'f',
toast.autovacuum_enabled = 'f'
);
INSERT INTO numbers SELECT generate_series(1, 5000);
Run Code Online (Sandbox Code Playgroud)
现在我们对所有行运行更新,
UPDATE numbers SET num = 0;
Run Code Online (Sandbox Code Playgroud)
当我们跑步时,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.
Run Code Online (Sandbox Code Playgroud)
现在我们发出另一个UPDATE
,但这次我们在SELECT
后面添加一个,
UPDATE numbers SET num = 1;
SELECT * FROM numbers;
Run Code Online (Sandbox Code Playgroud)
当我们跑步时,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.
Run Code Online (Sandbox Code Playgroud)
这里到底发生了什么?为什么我运行的第二个版本,在SELECT
从它访问的页面中删除死元组之后,很像VACUUM
?
我在 macOS 10.14.5 上运行 Postgres 11.3。
从/r/PostgreSQL 上的这篇文章到Laurenz Albe的回答,似乎只对堆元组 (HOT) 更新负责。来自HOT 更新的描述src/backend/access/heap/README.HOT
实际上,当页面几乎已满(<10% 空闲)并且可以获得缓冲区清理锁时,在元组检索期间会发生空间回收。这意味着
UPDATE
,DELETE
, 和SELECT
可以触发空间回收,但通常不会触发空间回收,INSERT ... VALUES
因为它不会检索行。
引用不在原始答案中,但其余部分是引用,
要支持或反驳这个理论,请运行以下查询:
Run Code Online (Sandbox Code Playgroud)SELECT n_tup_upd, n_tup_hot_upd FROM pg_stat_user_tables WHERE schemaname = 'public' AND relname = 'TABLE_NAME';
如果
n_tup_hot_upd
大于零,我们有一个案例。
归档时间: |
|
查看次数: |
884 次 |
最近记录: |