Skip to content

Commit eb11de8

Browse files
committed
Sanity-check that a page zeroed by redo routine is marked with WILL_INIT.
There was already a sanity-check in the other direction: if a page was marked with WILL_INIT, it had to be initialized by the redo routine. It's not strictly necessary for correctness that a page is marked with WILL_INIT if it's going to be initialized at redo, but it's a missed optimization if nothing else. Fix a few instances of this issue in SP-GiST, where a block in WAL record was not marked with WILL_INIT, but was in fact always initialized at redo. We were creating a full-page image of the page unnecessarily in those cases. Backpatch to 9.5, where the new WILL_INIT flag was added.
1 parent e52b690 commit eb11de8

File tree

2 files changed

+38
-12
lines changed

2 files changed

+38
-12
lines changed

src/backend/access/spgist/spgdoinsert.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,12 +291,16 @@ addLeafTuple(Relation index, SpGistState *state, SpGistLeafTuple leafTuple,
291291
if (RelationNeedsWAL(index))
292292
{
293293
XLogRecPtr recptr;
294+
int flags;
294295

295296
XLogBeginInsert();
296297
XLogRegisterData((char *) &xlrec, sizeof(xlrec));
297298
XLogRegisterData((char *) leafTuple, leafTuple->size);
298299

299-
XLogRegisterBuffer(0, current->buffer, REGBUF_STANDARD);
300+
flags = REGBUF_STANDARD;
301+
if (xlrec.newPage)
302+
flags |= REGBUF_WILL_INIT;
303+
XLogRegisterBuffer(0, current->buffer, flags);
300304
if (xlrec.offnumParent != InvalidOffsetNumber)
301305
XLogRegisterBuffer(1, parent->buffer, REGBUF_STANDARD);
302306

@@ -1348,20 +1352,31 @@ doPickSplit(Relation index, SpGistState *state,
13481352
XLogRegisterData((char *) innerTuple, innerTuple->size);
13491353
XLogRegisterData(leafdata, leafptr - leafdata);
13501354

1351-
flags = REGBUF_STANDARD;
1352-
if (xlrec.initSrc)
1353-
flags |= REGBUF_WILL_INIT;
1355+
/* Old leaf page */
13541356
if (BufferIsValid(saveCurrent.buffer))
1357+
{
1358+
flags = REGBUF_STANDARD;
1359+
if (xlrec.initSrc)
1360+
flags |= REGBUF_WILL_INIT;
13551361
XLogRegisterBuffer(0, saveCurrent.buffer, flags);
1362+
}
13561363

1364+
/* New leaf page */
13571365
if (BufferIsValid(newLeafBuffer))
13581366
{
13591367
flags = REGBUF_STANDARD;
13601368
if (xlrec.initDest)
13611369
flags |= REGBUF_WILL_INIT;
13621370
XLogRegisterBuffer(1, newLeafBuffer, flags);
13631371
}
1364-
XLogRegisterBuffer(2, current->buffer, REGBUF_STANDARD);
1372+
1373+
/* Inner page */
1374+
flags = REGBUF_STANDARD;
1375+
if (xlrec.initInner)
1376+
flags |= REGBUF_WILL_INIT;
1377+
XLogRegisterBuffer(2, current->buffer, flags);
1378+
1379+
/* Parent page, if different from inner page */
13651380
if (parent->buffer != InvalidBuffer)
13661381
{
13671382
if (parent->buffer != current->buffer)
@@ -1631,13 +1646,17 @@ spgAddNodeAction(Relation index, SpGistState *state,
16311646
if (RelationNeedsWAL(index))
16321647
{
16331648
XLogRecPtr recptr;
1649+
int flags;
16341650

16351651
XLogBeginInsert();
16361652

16371653
/* orig page */
16381654
XLogRegisterBuffer(0, saveCurrent.buffer, REGBUF_STANDARD);
16391655
/* new page */
1640-
XLogRegisterBuffer(1, current->buffer, REGBUF_STANDARD);
1656+
flags = REGBUF_STANDARD;
1657+
if (xlrec.newPage)
1658+
flags |= REGBUF_WILL_INIT;
1659+
XLogRegisterBuffer(1, current->buffer, flags);
16411660
/* parent page (if different from orig and new) */
16421661
if (xlrec.parentBlk == 2)
16431662
XLogRegisterBuffer(2, parent->buffer, REGBUF_STANDARD);

src/backend/access/transam/xlogutils.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -328,13 +328,26 @@ XLogReadBufferForRedoExtended(XLogReaderState *record,
328328
ForkNumber forknum;
329329
BlockNumber blkno;
330330
Page page;
331+
bool zeromode;
332+
bool willinit;
331333

332334
if (!XLogRecGetBlockTag(record, block_id, &rnode, &forknum, &blkno))
333335
{
334336
/* Caller specified a bogus block_id */
335337
elog(PANIC, "failed to locate backup block with ID %d", block_id);
336338
}
337339

340+
/*
341+
* Make sure that if the block is marked with WILL_INIT, the caller is
342+
* going to initialize it. And vice versa.
343+
*/
344+
zeromode = (mode == RBM_ZERO_AND_LOCK || mode == RBM_ZERO_AND_CLEANUP_LOCK);
345+
willinit = (record->blocks[block_id].flags & BKPBLOCK_WILL_INIT) != 0;
346+
if (willinit && !zeromode)
347+
elog(PANIC, "block with WILL_INIT flag in WAL record must be zeroed by redo routine");
348+
if (!willinit && zeromode)
349+
elog(PANIC, "block to be initialized in redo routine must be marked with WILL_INIT flag in the WAL record");
350+
338351
/* If it's a full-page image, restore it. */
339352
if (XLogRecHasBlockImage(record, block_id))
340353
{
@@ -359,12 +372,6 @@ XLogReadBufferForRedoExtended(XLogReaderState *record,
359372
}
360373
else
361374
{
362-
if ((record->blocks[block_id].flags & BKPBLOCK_WILL_INIT) != 0 &&
363-
mode != RBM_ZERO_AND_LOCK && mode != RBM_ZERO_AND_CLEANUP_LOCK)
364-
{
365-
elog(PANIC, "block with WILL_INIT flag in WAL record must be zeroed by redo routine");
366-
}
367-
368375
*buf = XLogReadBufferExtended(rnode, forknum, blkno, mode);
369376
if (BufferIsValid(*buf))
370377
{

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