From: | Peter Geoghegan <pg(at)bowt(dot)ie> |
---|---|
To: | PostgreSQL mailing lists <pgsql-bugs(at)lists(dot)postgresql(dot)org> |
Cc: | Robert Haas <robertmhaas(at)gmail(dot)com>, Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com> |
Subject: | VACUUM can set pages all-frozen without also setting them all-visible |
Date: | 2022-03-16 07:24:08 |
Message-ID: | CAH2-WznOKC4SS-7wHfjBpwc5meekzs+Yr8Gux5nFm7-VN3xMmA@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-bugs |
Attached are two patches. The first patch adds assertions that verify
that calls to visibilitymap_set() don't set VISIBILITYMAP_ALL_FROZEN
for a page without also setting VISIBILITYMAP_ALL_VISIBLE (plus a
similar assertion for visibilitymap_clear()). When I run "make
check-world" with just the first patch, several tests fail because one
of the new assertions fails.
The second patch tentatively addresses the issue by making two of the
calls to visibilitymap_set() made by vacuumlazy.c set
VISIBILITYMAP_ALL_VISIBLE | VISIBILITYMAP_ALL_FROZEN -- as opposed to
just setting VISIBILITYMAP_ALL_FROZEN, which is what happens on HEAD.
It's not clear whether or not it's strictly correct to only set
VISIBILITYMAP_ALL_FROZEN, but it seems questionable. It's also likely
to have negative performance implications. Non-aggressive VACUUMs
won't actually use VISIBILITYMAP_ALL_FROZEN to skip -- they could in
principle, but they don't.
VACUUM's skipping logic doesn't just refuse to skip
VISIBILITYMAP_ALL_VISIBLE pages during an aggressive VACUUM (which is
necessary and makes sense); it also refuses to skip
VISIBILITYMAP_ALL_FROZEN pages during non-aggressive VACUUMs. And so
any page that just has its VISIBILITYMAP_ALL_FROZEN bit set is not
skippable by non-aggressive VACUUMs. I'm referring to this code:
while (next_unskippable_block < rel_pages)
{
uint8 vmskipflags;
vmskipflags = visibilitymap_get_status(vacrel->rel,
next_unskippable_block,
&vmbuffer);
if (vacrel->aggressive)
{
if ((vmskipflags & VISIBILITYMAP_ALL_FROZEN) == 0)
break;
}
else
{
if ((vmskipflags & VISIBILITYMAP_ALL_VISIBLE) == 0)
break;
}
vacuum_delay_point();
next_unskippable_block++;
}
--
Peter Geoghegan
Attachment | Content-Type | Size |
---|---|---|
v1-0002-VACUUM-Don-t-set-pages-all-frozen-but-not-all-vis.patch | application/octet-stream | 1.9 KB |
v1-0001-Add-visibilitymap.c-assertions.patch | application/octet-stream | 1.3 KB |
From | Date | Subject | |
---|---|---|---|
Next Message | Peter Geoghegan | 2022-03-16 08:22:52 | Re: VACUUM can set pages all-frozen without also setting them all-visible |
Previous Message | David G. Johnston | 2022-03-16 02:28:09 | Re: BUG #17439: DROP FUNCTION functionName(); drops associated generated column without using CASCADE |