Skip to content

Commit 8dcbdea

Browse files
committed
fix leftlink on right page while page is splitting
1 parent dfbffd8 commit 8dcbdea

File tree

1 file changed

+36
-4
lines changed

1 file changed

+36
-4
lines changed

rumbtree.c

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -414,13 +414,14 @@ rumInsertValue(Relation index, RumBtree btree, RumBtreeStack * stack,
414414
btree->placeToPage(btree, page, stack->off);
415415

416416
if (btree->rumstate->isBuild)
417+
{
417418
MarkBufferDirty(stack->buffer);
419+
END_CRIT_SECTION();
420+
}
418421
else
419422
GenericXLogFinish(state);
420423

421424
LockBuffer(stack->buffer, RUM_UNLOCK);
422-
if (btree->rumstate->isBuild)
423-
END_CRIT_SECTION();
424425
freeRumBtreeStack(stack);
425426

426427
return;
@@ -520,6 +521,9 @@ rumInsertValue(Relation index, RumBtree btree, RumBtreeStack * stack,
520521
}
521522
else
522523
{
524+
BlockNumber rightrightBlkno = InvalidBlockNumber;
525+
Buffer rightrightBuffer;
526+
523527
/* split non-root page */
524528
if (btree->rumstate->isBuild)
525529
{
@@ -534,6 +538,8 @@ rumInsertValue(Relation index, RumBtree btree, RumBtreeStack * stack,
534538
rpage = GenericXLogRegisterBuffer(state, rbuffer, 0);
535539
}
536540

541+
rightrightBlkno = RumPageGetOpaque(lpage)->rightlink;
542+
537543
/*
538544
* newlpage is a pointer to memory page, it doesn't associate
539545
* with buffer, stack->buffer should be untouched
@@ -546,6 +552,29 @@ rumInsertValue(Relation index, RumBtree btree, RumBtreeStack * stack,
546552
RumPageGetOpaque(rpage)->leftlink = BufferGetBlockNumber(stack->buffer);
547553
RumPageGetOpaque(newlpage)->rightlink = BufferGetBlockNumber(rbuffer);
548554

555+
/*
556+
* it's safe because we don't have right-to-left walking
557+
* with locking bth pages except vacuum. But vacuum will
558+
* try to lock all pages with conditional lock
559+
*/
560+
if (rightrightBlkno != InvalidBlockNumber)
561+
{
562+
Page rightrightPage;
563+
564+
rightrightBuffer = ReadBuffer(btree->index,
565+
rightrightBlkno);
566+
567+
LockBuffer(rightrightBuffer, RUM_EXCLUSIVE);
568+
if (btree->rumstate->isBuild)
569+
rightrightPage = BufferGetPage(rightrightBuffer);
570+
else
571+
rightrightPage =
572+
GenericXLogRegisterBuffer(state, rightrightBuffer, 0);
573+
574+
RumPageGetOpaque(rightrightPage)->leftlink =
575+
BufferGetBlockNumber(rbuffer);
576+
}
577+
549578
if (btree->rumstate->isBuild)
550579
START_CRIT_SECTION();
551580
PageRestoreTempPage(newlpage, lpage);
@@ -554,13 +583,16 @@ rumInsertValue(Relation index, RumBtree btree, RumBtreeStack * stack,
554583
{
555584
MarkBufferDirty(rbuffer);
556585
MarkBufferDirty(stack->buffer);
586+
if (rightrightBlkno != InvalidBlockNumber)
587+
MarkBufferDirty(rightrightBuffer);
588+
END_CRIT_SECTION();
557589
}
558590
else
559591
GenericXLogFinish(state);
560592

561593
UnlockReleaseBuffer(rbuffer);
562-
if (btree->rumstate->isBuild)
563-
END_CRIT_SECTION();
594+
if (rightrightBlkno != InvalidBlockNumber)
595+
UnlockReleaseBuffer(rightrightBuffer);
564596
}
565597
}
566598

0 commit comments

Comments
 (0)