postgres.git / summary / log / commit / refs

commit    721ef4d28aae0afff6b714af9c545825f86a76da
Author:   Alvaro Herrera <alvherre@alvh.no-ip.org>
Date:     Wed Aug 12 19:33:36 2020 +0000
First released in: 14.0, 9.5.24, 9.6.20, 10.15, 11.10, 12.5, 13.0

    BRIN: Handle concurrent desummarization properly
    
    If a page range is desummarized at just the right time concurrently with
    an index walk, BRIN would raise an error indicating index corruption.
    This is scary and unhelpful; silently returning that the page range is
    not summarized is sufficient reaction.
    
    This bug was introduced by commit 975ad4e602ff as additional protection
    against a bug whose actual fix was elsewhere.  Backpatch equally.
    
    Reported-By: Anastasia Lubennikova <a.lubennikova@postgrespro.ru>
    Diagnosed-By: Alexander Lakhin <exclusion@gmail.com>
    Discussion: https://postgr.es/m/2588667e-d07d-7e10-74e2-7e1e46194491@postgrespro.ru
    Backpatch: 9.5 - master


src/backend/access/brin/brin_revmap.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/backend/access/brin/brin_revmap.c b/src/backend/access/brin/brin_revmap.c index ec84b9ee1d3..5232048fda3 100644 --- a/src/backend/access/brin/brin_revmap.c +++ b/src/backend/access/brin/brin_revmap.c @@ -282,10 +282,17 @@ brinGetTupleForHeapBlock(BrinRevmap *revmap, BlockNumber heapBlk, /* If we land on a revmap page, start over */ if (BRIN_IS_REGULAR_PAGE(page)) { + /* + * If the offset number is greater than what's in the page, it's + * possible that the range was desummarized concurrently. Just + * return NULL to handle that case. + */ if (*off > PageGetMaxOffsetNumber(page)) - ereport(ERROR, - (errcode(ERRCODE_INDEX_CORRUPTED), - errmsg_internal("corrupted BRIN index: inconsistent range map"))); + { + LockBuffer(*buf, BUFFER_LOCK_UNLOCK); + return NULL; + } + lp = PageGetItemId(page, *off); if (ItemIdIsUsed(lp)) { [parent: a293b42e5274]