Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f8f4227

Browse files
committed
Refactor per-page logic common to all redo routines to a new function.
Every redo routine uses the same idiom to determine what to do to a page: check if there's a backup block for it, and if not read, the buffer if the block exists, and check its LSN. Refactor that into a common function, XLogReadBufferForRedo, making all the redo routines shorter and more readable. This has no user-visible effect, and makes no changes to the WAL format. Reviewed by Andres Freund, Alvaro Herrera, Michael Paquier.
1 parent 26f8b99 commit f8f4227

File tree

8 files changed

+1347
-1656
lines changed

8 files changed

+1347
-1656
lines changed

src/backend/access/gin/ginxlog.c

Lines changed: 88 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,25 @@
2020
static MemoryContext opCtx; /* working memory for operations */
2121

2222
static void
23-
ginRedoClearIncompleteSplit(XLogRecPtr lsn, RelFileNode node, BlockNumber blkno)
23+
ginRedoClearIncompleteSplit(XLogRecPtr lsn, XLogRecord *record,
24+
int block_index,
25+
RelFileNode node, BlockNumber blkno)
2426
{
2527
Buffer buffer;
2628
Page page;
2729

28-
buffer = XLogReadBuffer(node, blkno, false);
29-
if (!BufferIsValid(buffer))
30-
return; /* page was deleted, nothing to do */
31-
page = (Page) BufferGetPage(buffer);
32-
33-
if (lsn > PageGetLSN(page))
30+
if (XLogReadBufferForRedo(lsn, record, block_index, node, blkno, &buffer)
31+
== BLK_NEEDS_REDO)
3432
{
33+
page = (Page) BufferGetPage(buffer);
34+
3535
GinPageGetOpaque(page)->flags &= ~GIN_INCOMPLETE_SPLIT;
3636

3737
PageSetLSN(page, lsn);
3838
MarkBufferDirty(buffer);
3939
}
40-
41-
UnlockReleaseBuffer(buffer);
40+
if (BufferIsValid(buffer))
41+
UnlockReleaseBuffer(buffer);
4242
}
4343

4444
static void
@@ -332,7 +332,6 @@ ginRedoInsert(XLogRecPtr lsn, XLogRecord *record)
332332
{
333333
ginxlogInsert *data = (ginxlogInsert *) XLogRecGetData(record);
334334
Buffer buffer;
335-
Page page;
336335
char *payload;
337336
BlockNumber leftChildBlkno = InvalidBlockNumber;
338337
BlockNumber rightChildBlkno = InvalidBlockNumber;
@@ -351,26 +350,14 @@ ginRedoInsert(XLogRecPtr lsn, XLogRecord *record)
351350
rightChildBlkno = BlockIdGetBlockNumber((BlockId) payload);
352351
payload += sizeof(BlockIdData);
353352

354-
if (record->xl_info & XLR_BKP_BLOCK(0))
355-
(void) RestoreBackupBlock(lsn, record, 0, false, false);
356-
else
357-
ginRedoClearIncompleteSplit(lsn, data->node, leftChildBlkno);
353+
ginRedoClearIncompleteSplit(lsn, record, 0, data->node, leftChildBlkno);
358354
}
359355

360-
/* If we have a full-page image, restore it and we're done */
361-
if (record->xl_info & XLR_BKP_BLOCK(isLeaf ? 0 : 1))
356+
if (XLogReadBufferForRedo(lsn, record, isLeaf ? 0 : 1, data->node,
357+
data->blkno, &buffer) == BLK_NEEDS_REDO)
362358
{
363-
(void) RestoreBackupBlock(lsn, record, isLeaf ? 0 : 1, false, false);
364-
return;
365-
}
366-
367-
buffer = XLogReadBuffer(data->node, data->blkno, false);
368-
if (!BufferIsValid(buffer))
369-
return; /* page was deleted, nothing to do */
370-
page = (Page) BufferGetPage(buffer);
359+
Page page = BufferGetPage(buffer);
371360

372-
if (lsn > PageGetLSN(page))
373-
{
374361
/* How to insert the payload is tree-type specific */
375362
if (data->flags & GIN_INSERT_ISDATA)
376363
{
@@ -386,8 +373,8 @@ ginRedoInsert(XLogRecPtr lsn, XLogRecord *record)
386373
PageSetLSN(page, lsn);
387374
MarkBufferDirty(buffer);
388375
}
389-
390-
UnlockReleaseBuffer(buffer);
376+
if (BufferIsValid(buffer))
377+
UnlockReleaseBuffer(buffer);
391378
}
392379

393380
static void
@@ -476,12 +463,7 @@ ginRedoSplit(XLogRecPtr lsn, XLogRecord *record)
476463
* split
477464
*/
478465
if (!isLeaf)
479-
{
480-
if (record->xl_info & XLR_BKP_BLOCK(0))
481-
(void) RestoreBackupBlock(lsn, record, 0, false, false);
482-
else
483-
ginRedoClearIncompleteSplit(lsn, data->node, data->leftChildBlkno);
484-
}
466+
ginRedoClearIncompleteSplit(lsn, record, 0, data->node, data->leftChildBlkno);
485467

486468
flags = 0;
487469
if (isLeaf)
@@ -605,31 +587,21 @@ ginRedoVacuumDataLeafPage(XLogRecPtr lsn, XLogRecord *record)
605587
{
606588
ginxlogVacuumDataLeafPage *xlrec = (ginxlogVacuumDataLeafPage *) XLogRecGetData(record);
607589
Buffer buffer;
608-
Page page;
609590

610-
/* If we have a full-page image, restore it and we're done */
611-
if (record->xl_info & XLR_BKP_BLOCK(0))
591+
if (XLogReadBufferForRedo(lsn, record, 0, xlrec->node, xlrec->blkno,
592+
&buffer) == BLK_NEEDS_REDO)
612593
{
613-
(void) RestoreBackupBlock(lsn, record, 0, false, false);
614-
return;
615-
}
616-
617-
buffer = XLogReadBuffer(xlrec->node, xlrec->blkno, false);
618-
if (!BufferIsValid(buffer))
619-
return;
620-
page = (Page) BufferGetPage(buffer);
594+
Page page = BufferGetPage(buffer);
621595

622-
Assert(GinPageIsLeaf(page));
623-
Assert(GinPageIsData(page));
596+
Assert(GinPageIsLeaf(page));
597+
Assert(GinPageIsData(page));
624598

625-
if (lsn > PageGetLSN(page))
626-
{
627599
ginRedoRecompress(page, &xlrec->data);
628600
PageSetLSN(page, lsn);
629601
MarkBufferDirty(buffer);
630602
}
631-
632-
UnlockReleaseBuffer(buffer);
603+
if (BufferIsValid(buffer))
604+
UnlockReleaseBuffer(buffer);
633605
}
634606

635607
static void
@@ -641,62 +613,42 @@ ginRedoDeletePage(XLogRecPtr lsn, XLogRecord *record)
641613
Buffer lbuffer;
642614
Page page;
643615

644-
if (record->xl_info & XLR_BKP_BLOCK(0))
645-
dbuffer = RestoreBackupBlock(lsn, record, 0, false, true);
646-
else
616+
if (XLogReadBufferForRedo(lsn, record, 0, data->node, data->blkno, &dbuffer)
617+
== BLK_NEEDS_REDO)
647618
{
648-
dbuffer = XLogReadBuffer(data->node, data->blkno, false);
649-
if (BufferIsValid(dbuffer))
650-
{
651-
page = BufferGetPage(dbuffer);
652-
if (lsn > PageGetLSN(page))
653-
{
654-
Assert(GinPageIsData(page));
655-
GinPageGetOpaque(page)->flags = GIN_DELETED;
656-
PageSetLSN(page, lsn);
657-
MarkBufferDirty(dbuffer);
658-
}
659-
}
619+
page = BufferGetPage(dbuffer);
620+
621+
Assert(GinPageIsData(page));
622+
GinPageGetOpaque(page)->flags = GIN_DELETED;
623+
PageSetLSN(page, lsn);
624+
MarkBufferDirty(dbuffer);
660625
}
661626

662-
if (record->xl_info & XLR_BKP_BLOCK(1))
663-
pbuffer = RestoreBackupBlock(lsn, record, 1, false, true);
664-
else
627+
if (XLogReadBufferForRedo(lsn, record, 1, data->node, data->parentBlkno,
628+
&pbuffer) == BLK_NEEDS_REDO)
665629
{
666-
pbuffer = XLogReadBuffer(data->node, data->parentBlkno, false);
667-
if (BufferIsValid(pbuffer))
668-
{
669-
page = BufferGetPage(pbuffer);
670-
if (lsn > PageGetLSN(page))
671-
{
672-
Assert(GinPageIsData(page));
673-
Assert(!GinPageIsLeaf(page));
674-
GinPageDeletePostingItem(page, data->parentOffset);
675-
PageSetLSN(page, lsn);
676-
MarkBufferDirty(pbuffer);
677-
}
678-
}
630+
page = BufferGetPage(pbuffer);
631+
632+
Assert(GinPageIsData(page));
633+
Assert(!GinPageIsLeaf(page));
634+
GinPageDeletePostingItem(page, data->parentOffset);
635+
PageSetLSN(page, lsn);
636+
MarkBufferDirty(pbuffer);
679637
}
680638

681-
if (record->xl_info & XLR_BKP_BLOCK(2))
682-
(void) RestoreBackupBlock(lsn, record, 2, false, false);
683-
else if (data->leftBlkno != InvalidBlockNumber)
639+
if (XLogReadBufferForRedo(lsn, record, 2, data->node, data->leftBlkno,
640+
&lbuffer) == BLK_NEEDS_REDO)
684641
{
685-
lbuffer = XLogReadBuffer(data->node, data->leftBlkno, false);
686-
if (BufferIsValid(lbuffer))
687-
{
688-
page = BufferGetPage(lbuffer);
689-
if (lsn > PageGetLSN(page))
690-
{
691-
Assert(GinPageIsData(page));
692-
GinPageGetOpaque(page)->rightlink = data->rightLink;
693-
PageSetLSN(page, lsn);
694-
MarkBufferDirty(lbuffer);
695-
}
696-
UnlockReleaseBuffer(lbuffer);
697-
}
642+
page = BufferGetPage(lbuffer);
643+
644+
Assert(GinPageIsData(page));
645+
GinPageGetOpaque(page)->rightlink = data->rightLink;
646+
PageSetLSN(page, lsn);
647+
MarkBufferDirty(lbuffer);
698648
}
699649

650+
if (BufferIsValid(lbuffer))
651+
UnlockReleaseBuffer(lbuffer);
700652
if (BufferIsValid(pbuffer))
701653
UnlockReleaseBuffer(pbuffer);
702654
if (BufferIsValid(dbuffer))
@@ -730,74 +682,64 @@ ginRedoUpdateMetapage(XLogRecPtr lsn, XLogRecord *record)
730682
/*
731683
* insert into tail page
732684
*/
733-
if (record->xl_info & XLR_BKP_BLOCK(0))
734-
(void) RestoreBackupBlock(lsn, record, 0, false, false);
735-
else
685+
if (XLogReadBufferForRedo(lsn, record, 0, data->node,
686+
data->metadata.tail, &buffer)
687+
== BLK_NEEDS_REDO)
736688
{
737-
buffer = XLogReadBuffer(data->node, data->metadata.tail, false);
738-
if (BufferIsValid(buffer))
739-
{
740-
Page page = BufferGetPage(buffer);
689+
Page page = BufferGetPage(buffer);
690+
OffsetNumber off;
691+
int i;
692+
Size tupsize;
693+
IndexTuple tuples;
741694

742-
if (lsn > PageGetLSN(page))
743-
{
744-
OffsetNumber l,
745-
off = (PageIsEmpty(page)) ? FirstOffsetNumber :
746-
OffsetNumberNext(PageGetMaxOffsetNumber(page));
747-
int i,
748-
tupsize;
749-
IndexTuple tuples = (IndexTuple) (XLogRecGetData(record) + sizeof(ginxlogUpdateMeta));
695+
tuples = (IndexTuple) (XLogRecGetData(record) + sizeof(ginxlogUpdateMeta));
750696

751-
for (i = 0; i < data->ntuples; i++)
752-
{
753-
tupsize = IndexTupleSize(tuples);
697+
if (PageIsEmpty(page))
698+
off = FirstOffsetNumber;
699+
else
700+
off = OffsetNumberNext(PageGetMaxOffsetNumber(page));
754701

755-
l = PageAddItem(page, (Item) tuples, tupsize, off, false, false);
702+
for (i = 0; i < data->ntuples; i++)
703+
{
704+
tupsize = IndexTupleSize(tuples);
756705

757-
if (l == InvalidOffsetNumber)
758-
elog(ERROR, "failed to add item to index page");
706+
if (PageAddItem(page, (Item) tuples, tupsize, off,
707+
false, false) == InvalidOffsetNumber)
708+
elog(ERROR, "failed to add item to index page");
759709

760-
tuples = (IndexTuple) (((char *) tuples) + tupsize);
710+
tuples = (IndexTuple) (((char *) tuples) + tupsize);
761711

762-
off++;
763-
}
712+
off++;
713+
}
764714

765-
/*
766-
* Increase counter of heap tuples
767-
*/
768-
GinPageGetOpaque(page)->maxoff++;
715+
/*
716+
* Increase counter of heap tuples
717+
*/
718+
GinPageGetOpaque(page)->maxoff++;
769719

770-
PageSetLSN(page, lsn);
771-
MarkBufferDirty(buffer);
772-
}
773-
UnlockReleaseBuffer(buffer);
774-
}
720+
PageSetLSN(page, lsn);
721+
MarkBufferDirty(buffer);
775722
}
723+
if (BufferIsValid(buffer))
724+
UnlockReleaseBuffer(buffer);
776725
}
777726
else if (data->prevTail != InvalidBlockNumber)
778727
{
779728
/*
780729
* New tail
781730
*/
782-
if (record->xl_info & XLR_BKP_BLOCK(0))
783-
(void) RestoreBackupBlock(lsn, record, 0, false, false);
784-
else
731+
if (XLogReadBufferForRedo(lsn, record, 0, data->node, data->prevTail,
732+
&buffer) == BLK_NEEDS_REDO)
785733
{
786-
buffer = XLogReadBuffer(data->node, data->prevTail, false);
787-
if (BufferIsValid(buffer))
788-
{
789-
Page page = BufferGetPage(buffer);
734+
Page page = BufferGetPage(buffer);
790735

791-
if (lsn > PageGetLSN(page))
792-
{
793-
GinPageGetOpaque(page)->rightlink = data->newRightlink;
736+
GinPageGetOpaque(page)->rightlink = data->newRightlink;
794737

795-
PageSetLSN(page, lsn);
796-
MarkBufferDirty(buffer);
797-
}
798-
UnlockReleaseBuffer(buffer);
799-
}
738+
PageSetLSN(page, lsn);
739+
MarkBufferDirty(buffer);
800740
}
741+
if (BufferIsValid(buffer))
742+
UnlockReleaseBuffer(buffer);
801743
}
802744

803745
UnlockReleaseBuffer(metabuffer);

0 commit comments

Comments
 (0)