@@ -414,13 +414,14 @@ rumInsertValue(Relation index, RumBtree btree, RumBtreeStack * stack,
414
414
btree -> placeToPage (btree , page , stack -> off );
415
415
416
416
if (btree -> rumstate -> isBuild )
417
+ {
417
418
MarkBufferDirty (stack -> buffer );
419
+ END_CRIT_SECTION ();
420
+ }
418
421
else
419
422
GenericXLogFinish (state );
420
423
421
424
LockBuffer (stack -> buffer , RUM_UNLOCK );
422
- if (btree -> rumstate -> isBuild )
423
- END_CRIT_SECTION ();
424
425
freeRumBtreeStack (stack );
425
426
426
427
return ;
@@ -520,6 +521,9 @@ rumInsertValue(Relation index, RumBtree btree, RumBtreeStack * stack,
520
521
}
521
522
else
522
523
{
524
+ BlockNumber rightrightBlkno = InvalidBlockNumber ;
525
+ Buffer rightrightBuffer ;
526
+
523
527
/* split non-root page */
524
528
if (btree -> rumstate -> isBuild )
525
529
{
@@ -534,6 +538,8 @@ rumInsertValue(Relation index, RumBtree btree, RumBtreeStack * stack,
534
538
rpage = GenericXLogRegisterBuffer (state , rbuffer , 0 );
535
539
}
536
540
541
+ rightrightBlkno = RumPageGetOpaque (lpage )-> rightlink ;
542
+
537
543
/*
538
544
* newlpage is a pointer to memory page, it doesn't associate
539
545
* with buffer, stack->buffer should be untouched
@@ -546,6 +552,29 @@ rumInsertValue(Relation index, RumBtree btree, RumBtreeStack * stack,
546
552
RumPageGetOpaque (rpage )-> leftlink = BufferGetBlockNumber (stack -> buffer );
547
553
RumPageGetOpaque (newlpage )-> rightlink = BufferGetBlockNumber (rbuffer );
548
554
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
+
549
578
if (btree -> rumstate -> isBuild )
550
579
START_CRIT_SECTION ();
551
580
PageRestoreTempPage (newlpage , lpage );
@@ -554,13 +583,16 @@ rumInsertValue(Relation index, RumBtree btree, RumBtreeStack * stack,
554
583
{
555
584
MarkBufferDirty (rbuffer );
556
585
MarkBufferDirty (stack -> buffer );
586
+ if (rightrightBlkno != InvalidBlockNumber )
587
+ MarkBufferDirty (rightrightBuffer );
588
+ END_CRIT_SECTION ();
557
589
}
558
590
else
559
591
GenericXLogFinish (state );
560
592
561
593
UnlockReleaseBuffer (rbuffer );
562
- if (btree -> rumstate -> isBuild )
563
- END_CRIT_SECTION ( );
594
+ if (rightrightBlkno != InvalidBlockNumber )
595
+ UnlockReleaseBuffer ( rightrightBuffer );
564
596
}
565
597
}
566
598
0 commit comments