Re: PANIC: wrong buffer passed to visibilitymap_clear

From: Andres Freund <andres(at)anarazel(dot)de>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Peter Geoghegan <pg(at)bowt(dot)ie>
Cc: pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: PANIC: wrong buffer passed to visibilitymap_clear
Date: 2021-04-09 23:27:39
Message-ID: 20210409232739.sazp5p4xnnagrusa@alap3.anarazel.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

On 2021-04-09 18:40:27 -0400, Tom Lane wrote:
> Buildfarm members spurfowl[1] and thorntail[2] have each shown $SUBJECT
> once in the past two days. The circumstances are not quite the same;
> spurfowl's failure is in autovacuum while thorntail's is in a manual
> VACUUM command. Still, it seems clear that there's a recently-introduced
> bug here somewhere. I don't see any obvious candidate for the culprit,
> though. Any ideas?

commit 7ab96cf6b312cfcd79cdc1a69c6bdb75de0ed30f
Author: Peter Geoghegan <pg(at)bowt(dot)ie>
Date: 2021-04-06 07:49:39 -0700

Refactor lazy_scan_heap() loop.

or some of the other changes in the vicinity could be related. There's
some changes when pages are marked as AllVisible, when their free space
is tracked etc.

Just looking at the code in heap_update: I'm a bit confused about
RelationGetBufferForTuple()'s vmbuffer and vmbuffer_other
arguments. It looks like it's not at all clear which of the two
arguments will have the vmbuffer for which of the pages?

if (otherBuffer == InvalidBuffer || targetBlock <= otherBlock)
GetVisibilityMapPins(relation, buffer, otherBuffer,
targetBlock, otherBlock, vmbuffer,
vmbuffer_other);
else
GetVisibilityMapPins(relation, otherBuffer, buffer,
otherBlock, targetBlock, vmbuffer_other,
vmbuffer);

Which then would make any subsequent use of vmbuffer vs vmbuffer_new in
heap_update() bogus? Because clearly that code associates vmbuffer /
vmbuffer_new with the respective page?

/* clear PD_ALL_VISIBLE flags, reset all visibilitymap bits */
if (PageIsAllVisible(BufferGetPage(buffer)))
{
all_visible_cleared = true;
PageClearAllVisible(BufferGetPage(buffer));
visibilitymap_clear(relation, BufferGetBlockNumber(buffer),
vmbuffer, VISIBILITYMAP_VALID_BITS);
}
if (newbuf != buffer && PageIsAllVisible(BufferGetPage(newbuf)))
{
all_visible_cleared_new = true;
PageClearAllVisible(BufferGetPage(newbuf));
visibilitymap_clear(relation, BufferGetBlockNumber(newbuf),
vmbuffer_new, VISIBILITYMAP_VALID_BITS);
}

Greetings,

Andres Freund

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Andres Freund 2021-04-09 23:30:44 Re: PANIC: wrong buffer passed to visibilitymap_clear
Previous Message Peter Geoghegan 2021-04-09 23:27:12 Re: PANIC: wrong buffer passed to visibilitymap_clear