mirror of
https://github.com/postgres/postgres.git
synced 2025-11-12 05:01:15 +03:00
hash: Fix write-ahead logging bugs related to init forks.
One, logging for CREATE INDEX was oblivious to the fact that when an unlogged table is created, *only* operations on the init fork should be logged. Two, init fork buffers need to be flushed after they are written; otherwise, a filesystem-level copy following recovery may do the wrong thing. (There may be a better fix for this issue than the one used here, but this is transposed from the similar logic already present in XLogReadBufferForRedoExtended, and a broader refactoring after beta2 seems inadvisable.) Amit Kapila, reviewed by Ashutosh Sharma, Kyotaro Horiguchi, and Michael Paquier Discussion: http://postgr.es/m/CAA4eK1JpcMsEtOL_J7WODumeEfyrPi7FPYHeVdS7fyyrCrgp4w@mail.gmail.com
This commit is contained in:
@@ -33,6 +33,7 @@ hash_xlog_init_meta_page(XLogReaderState *record)
|
||||
XLogRecPtr lsn = record->EndRecPtr;
|
||||
Page page;
|
||||
Buffer metabuf;
|
||||
ForkNumber forknum;
|
||||
|
||||
xl_hash_init_meta_page *xlrec = (xl_hash_init_meta_page *) XLogRecGetData(record);
|
||||
|
||||
@@ -44,6 +45,17 @@ hash_xlog_init_meta_page(XLogReaderState *record)
|
||||
page = (Page) BufferGetPage(metabuf);
|
||||
PageSetLSN(page, lsn);
|
||||
MarkBufferDirty(metabuf);
|
||||
|
||||
/*
|
||||
* Force the on-disk state of init forks to always be in sync with the
|
||||
* state in shared buffers. See XLogReadBufferForRedoExtended. We need
|
||||
* special handling for init forks as create index operations don't log a
|
||||
* full page image of the metapage.
|
||||
*/
|
||||
XLogRecGetBlockTag(record, 0, NULL, &forknum, NULL);
|
||||
if (forknum == INIT_FORKNUM)
|
||||
FlushOneBuffer(metabuf);
|
||||
|
||||
/* all done */
|
||||
UnlockReleaseBuffer(metabuf);
|
||||
}
|
||||
@@ -60,6 +72,7 @@ hash_xlog_init_bitmap_page(XLogReaderState *record)
|
||||
Page page;
|
||||
HashMetaPage metap;
|
||||
uint32 num_buckets;
|
||||
ForkNumber forknum;
|
||||
|
||||
xl_hash_init_bitmap_page *xlrec = (xl_hash_init_bitmap_page *) XLogRecGetData(record);
|
||||
|
||||
@@ -70,6 +83,16 @@ hash_xlog_init_bitmap_page(XLogReaderState *record)
|
||||
_hash_initbitmapbuffer(bitmapbuf, xlrec->bmsize, true);
|
||||
PageSetLSN(BufferGetPage(bitmapbuf), lsn);
|
||||
MarkBufferDirty(bitmapbuf);
|
||||
|
||||
/*
|
||||
* Force the on-disk state of init forks to always be in sync with the
|
||||
* state in shared buffers. See XLogReadBufferForRedoExtended. We need
|
||||
* special handling for init forks as create index operations don't log a
|
||||
* full page image of the metapage.
|
||||
*/
|
||||
XLogRecGetBlockTag(record, 0, NULL, &forknum, NULL);
|
||||
if (forknum == INIT_FORKNUM)
|
||||
FlushOneBuffer(bitmapbuf);
|
||||
UnlockReleaseBuffer(bitmapbuf);
|
||||
|
||||
/* add the new bitmap page to the metapage's list of bitmaps */
|
||||
@@ -90,6 +113,10 @@ hash_xlog_init_bitmap_page(XLogReaderState *record)
|
||||
|
||||
PageSetLSN(page, lsn);
|
||||
MarkBufferDirty(metabuf);
|
||||
|
||||
XLogRecGetBlockTag(record, 1, NULL, &forknum, NULL);
|
||||
if (forknum == INIT_FORKNUM)
|
||||
FlushOneBuffer(metabuf);
|
||||
}
|
||||
if (BufferIsValid(metabuf))
|
||||
UnlockReleaseBuffer(metabuf);
|
||||
|
||||
Reference in New Issue
Block a user