Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5b51805

Browse files
committed
Fix bug leading to restoring unlogged relations from empty files.
At the end of crash recovery, unlogged relations are reset to the emptystate, using their init fork as the template. The init fork is copied tothe main fork without going through shared buffers. Unfortunately WALreplay so far has not necessarily flushed writes from shared buffers todisk at that point. In normal crash recovery, and before theintroduction of 'fast promotions' infd4ced5 / 9.3, theEND_OF_RECOVERY checkpoint flushes the buffers out in time. But withfast promotions that's not the case anymore.To fix, force WAL writes targeting the init fork to be flushedimmediately (using the new FlushOneBuffer() function). In 9.5+ thatflush can centrally be triggered from the code dealing with restoringfull page writes (XLogReadBufferForRedoExtended), in earlier releasesthat responsibility is in the hands of XLOG_HEAP_NEWPAGE's replayfunction.Backpatch to 9.1, even if this currently is only known to trigger in9.3+. Flushing earlier is more robust, and it is advantageous to keepthe branches similar.Typical symptoms of this bug are errors like'ERROR: index "..." contains unexpected zero page at block 0'shortly after promoting a node.Reported-By: Thom BrownAuthor: Andres Freund and Michael PaquierDiscussion: 20150326175024.GJ451@alap3.anarazel.deBackpatch: 9.1-
1 parent2355faa commit5b51805

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

‎src/backend/access/transam/xlogutils.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,15 @@ XLogReadBufferForRedoExtended(XLogReaderState *record,
368368

369369
MarkBufferDirty(*buf);
370370

371+
/*
372+
* At the end of crash recovery the init forks of unlogged relations
373+
* are copied, without going through shared buffers. So we need to
374+
* force the on-disk state of init forks to always be in sync with the
375+
* state in shared buffers.
376+
*/
377+
if (forknum==INIT_FORKNUM)
378+
FlushOneBuffer(*buf);
379+
371380
returnBLK_RESTORED;
372381
}
373382
else

‎src/backend/storage/buffer/bufmgr.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2927,6 +2927,27 @@ FlushDatabaseBuffers(Oid dbid)
29272927
}
29282928
}
29292929

2930+
/*
2931+
* Flush a previously, shared or exclusively, locked and pinned buffer to the
2932+
* OS.
2933+
*/
2934+
void
2935+
FlushOneBuffer(Bufferbuffer)
2936+
{
2937+
volatileBufferDesc*bufHdr;
2938+
2939+
/* currently not needed, but no fundamental reason not to support */
2940+
Assert(!BufferIsLocal(buffer));
2941+
2942+
Assert(BufferIsPinned(buffer));
2943+
2944+
bufHdr=GetBufferDescriptor(buffer-1);
2945+
2946+
LWLockHeldByMe(bufHdr->content_lock);
2947+
2948+
FlushBuffer(bufHdr,NULL);
2949+
}
2950+
29302951
/*
29312952
* ReleaseBuffer -- release the pin on a buffer
29322953
*/

‎src/include/storage/bufmgr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ extern void CheckPointBuffers(int flags);
169169
externBlockNumberBufferGetBlockNumber(Bufferbuffer);
170170
externBlockNumberRelationGetNumberOfBlocksInFork(Relationrelation,
171171
ForkNumberforkNum);
172+
externvoidFlushOneBuffer(Bufferbuffer);
172173
externvoidFlushRelationBuffers(Relationrel);
173174
externvoidFlushDatabaseBuffers(Oiddbid);
174175
externvoidDropRelFileNodeBuffers(RelFileNodeBackendrnode,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp