回复:Re: PANIC: wrong buffer passed to visibilitymap_clear

Поиск
Список
Период
Сортировка
От 王伟(学弈)
Тема 回复:Re: PANIC: wrong buffer passed to visibilitymap_clear
Дата
Msg-id 3a7f4285-bf43-4f94-b706-e9d98f5962c6.rogers.ww@alibaba-inc.com
обсуждение исходный текст
Список pgsql-hackers
On Fri, Jul 22, 2022 at 14:49 Peter Geoghegan wrote:
> The line numbers from your stack trace don't match up with
> REL_14_STABLE. Is this actually a fork of Postgres 14? (Oh, looks like
> it's an old beta release.)

Yeah, I was testing on 14beta2 branch once. So I considered your
advices and test on REL_14_STABLE branch. But I'm not lucky
enough to repeat this core file during the past few days.

> It would also be helpful if you told us about the specific table
> involved. Though the important thing (the essential thing) is to test
> today's REL_14_STABLE. There have been *lots* of bug fixes since
> Postgres 14 beta2 was current.

Besides, the logic of heap_update and RelationGetBufferForTuple functions
are mostly same between 14beta2 and REL_14_STABLE versions. 
So, I take a deep research on heap_update and RelationGetBufferForTuple
functions and find one code path for missing recheck of all-visible flag after
locking buffer with BUFFER_LOCK_EXCLUSIVE.

The following is the code path:
(1) heap_update calls RelationGetBufferForTuple to get new suitable buffer;
(2) during 'loop' loop of RelationGetBufferForTuple, it looks up one suitable new
buffer via FSM. But we assume that it was failed to find one available buffer here
and old buffer ('otherBuffer') was not set the all-visible flag.
(3) Next, it decides to bulk-extend the relation via RelationAddExtraBlocks and
get one new locked empty buffer via ReadBufferBI within ExclusiveLock.
(4) Then, it's succeed to ConditionalLockBuffer old buffer ('otherBuffer') and
returns the new buffer number without rechecking the all-visibility flag of old buffer.
(5) Finally, heap_update do the real update work and clear the all-visibility flag of
both old buffer and new buffer. It finds that the old buffer was set all-visibility
flag but vmbuffer is still 0. At last, visibilitymap_clear reports error 'wrong buffer
passed to visibilitymap_clear'.

I propose one patch which rechecks the all-visibility flag of old buffer after
ConditionalLockBuffer old buffer is successful. I start to test this patch for
couple of days and it seems to work well for me till now.

--
Regards,
rogers.ww
Вложения

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Simon Riggs
Дата:
Сообщение: Max compact as an FSM strategy
Следующее
От: Peter Smith
Дата:
Сообщение: Re: Perform streaming logical transactions by background workers and parallel apply