具有 READ COMMITTED 隔离级别,已执行写操作的空闲事务将防止清理事务写入的表的死行。
对于由仍在进行中的事务写入的表来说,这一点很清楚。在这里你可以找到一个很好的解释。
但我不清楚为什么这个限制也会影响任何其他表。
例如:事务 T 启动并更新表 B,当 T 处于“事务中的空闲”状态时,对表 A 执行真空。在这种情况下,为什么无法删除 A 中的死行?
这是我所做的:
# show default_transaction_isolation;
default_transaction_isolation
-------------------------------
read committed
(1 row)
# create table a (v int);
CREATE TABLE
# create table b (v int);
CREATE TABLE
# insert into a values (generate_series(1,1000));
INSERT 0 1000
此时我进行更新以生成新的 1000 死行
# update a set v = v + 1;
UPDATE 1000
吸尘将按预期删除它们:
# vacuum verbose a;
INFO: vacuuming "public.a"
INFO: "a": removed 1000 row versions in 5 pages
INFO: "a": found 1000 removable, 1000 nonremovable row versions in 9 out of 9 pages
DETAIL: 0 dead row versions cannot be removed yet.
There were 0 unused item pointers.
0 pages are entirely empty.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
VACUUM
我现在开始在表 b 中写入事务 T:
# begin;
BEGIN
# insert into b values (generate_series(1,1000));
INSERT 0 1000
我在 T 之后开始的不同事务 T1 中再次生成更多死行:
# begin;
# update a set v = v + 1;
# commit;
在不同的交易中:
# vacuum verbose a;
INFO: vacuuming "public.a"
INFO: "a": found 0 removable, 2000 nonremovable row versions in 9 out of 9 pages
DETAIL: 1000 dead row versions cannot be removed yet.
There were 34 unused item pointers.
0 pages are entirely empty.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
VACUUM
这是相关部分:细节:1000 个死行版本还不能被删除。
如果我提交事务 T 并再次执行真空,我会按预期删除死行:
# vacuum verbose a;
INFO: vacuuming "public.a"
INFO: "a": removed 1000 row versions in 5 pages
INFO: "a": found 1000 removable, 1000 nonremovable row versions in 9 out of 9 pages
DETAIL: 0 dead row versions cannot be removed yet.
There were 34 unused item pointers.
0 pages are entirely empty.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
VACUUM