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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy