Fix yet another crash in page split during GiST index creation.
Commit a7ee7c8513
fixed a bug in GiST page split during index creation,
where we failed to re-find the position of a downlink after the page
containing it was split. However, that fix was incomplete; the other call
to gistinserttuples() in the same function needs to also clear
'downlinkoffnum'.
Fixes bug #16134 reported by Alexander Lakhin, for real this time. The
previous fix was enough to fix the crash with the reproducer script for
bug #16162, but the original script for #16134 was still crashing.
Backpatch to v12, like the previous incomplete fix.
Discussion: https://www.postgresql.org/message-id/d869f537-abe4-d2ea-0510-38cd053f5152%40gmail.com
This commit is contained in:
parent
502423180a
commit
741b884353
|
@ -1325,10 +1325,9 @@ gistfinishsplit(GISTInsertState *state, GISTInsertStack *stack,
|
|||
* downlink for the original page as one operation.
|
||||
*/
|
||||
LockBuffer(stack->parent->buffer, GIST_EXCLUSIVE);
|
||||
gistFindCorrectParent(state->r, stack);
|
||||
|
||||
/*
|
||||
* insert downlinks for the siblings from right to left, until there are
|
||||
* Insert downlinks for the siblings from right to left, until there are
|
||||
* only two siblings left.
|
||||
*/
|
||||
for (int pos = list_length(splitinfo) - 1; pos > 1; pos--)
|
||||
|
@ -1336,17 +1335,17 @@ gistfinishsplit(GISTInsertState *state, GISTInsertStack *stack,
|
|||
right = (GISTPageSplitInfo *) list_nth(splitinfo, pos);
|
||||
left = (GISTPageSplitInfo *) list_nth(splitinfo, pos - 1);
|
||||
|
||||
gistFindCorrectParent(state->r, stack);
|
||||
if (gistinserttuples(state, stack->parent, giststate,
|
||||
&right->downlink, 1,
|
||||
InvalidOffsetNumber,
|
||||
left->buf, right->buf, false, false))
|
||||
{
|
||||
/*
|
||||
* If the parent page was split, need to relocate the original
|
||||
* parent pointer.
|
||||
* If the parent page was split, the existing downlink might
|
||||
* have moved.
|
||||
*/
|
||||
stack->downlinkoffnum = InvalidOffsetNumber;
|
||||
gistFindCorrectParent(state->r, stack);
|
||||
}
|
||||
/* gistinserttuples() released the lock on right->buf. */
|
||||
}
|
||||
|
@ -1361,13 +1360,21 @@ gistfinishsplit(GISTInsertState *state, GISTInsertStack *stack,
|
|||
*/
|
||||
tuples[0] = left->downlink;
|
||||
tuples[1] = right->downlink;
|
||||
gistinserttuples(state, stack->parent, giststate,
|
||||
tuples, 2,
|
||||
stack->downlinkoffnum,
|
||||
left->buf, right->buf,
|
||||
true, /* Unlock parent */
|
||||
unlockbuf /* Unlock stack->buffer if caller wants that */
|
||||
);
|
||||
gistFindCorrectParent(state->r, stack);
|
||||
if (gistinserttuples(state, stack->parent, giststate,
|
||||
tuples, 2,
|
||||
stack->downlinkoffnum,
|
||||
left->buf, right->buf,
|
||||
true, /* Unlock parent */
|
||||
unlockbuf /* Unlock stack->buffer if caller wants that */
|
||||
))
|
||||
{
|
||||
/*
|
||||
* If the parent page was split, the downlink might have moved.
|
||||
*/
|
||||
stack->downlinkoffnum = InvalidOffsetNumber;
|
||||
}
|
||||
|
||||
Assert(left->buf == stack->buffer);
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue