Hi,
On Tue, Nov 4, 2025 at 5:22 PM Álvaro Herrera <alvherre@kurilemu.de> wrote:
>
>
> > With my initial try of this test, just counting the number of BRIN
> > tuples, I was _really_ surprised that the index did indeed contain the
> > expected number of tuples, even when the error was being thrown. This
> > turned out to be expected, because the way BRIN summarization works is
> > that we insert a placeholder tuple first, then update it to the correct
> > value, and the error only aborts the second part.
>
> One thing that's not fully clear to me, but will test later, is that if
> this has happened to you, then the placeholder tuple remains in place
> and doesn't ever become non-placeholder. If vacuum (incl. autovacuum)
> sees such a tuple, it will gladly ignore the page range, as if it were
> already summarized. This makes your index scans potentially
> inefficient, because for placeholder tuples bringetbitmap will always
> include the affected page range.
>
> I think we should make vacuum clean it up somehow, but I'm not yet sure
> how safe it is.
>
+1. I noticed the same behavior while working on amcheck support for BRIN.
I think it should be safe because we hold ShareUpdateExclusiveLock
during any summarization, desummarization, or vacuum. So it means we
can't have concurrent summarization during the vacuum. So if we
encounter a placeholder during vacuum, it is always the result of
"aborted" summarization. At least brinRevmapDesummarizeRange always
treats placeholders this way. Maybe we can use
brinRevmapDesummarizeRange for this? FWIW there is a deadlock issue
with brinRevmapDesummarizeRange [0], maybe it is worth addressing if
we want to start using it during vacuum.
[0] https://www.postgresql.org/message-id/flat/261e68bc-f5f5-5234-fb2c-af4f583513c0%40enterprisedb.com
Best regards,
Arseniy Mukhin