From: Robert Haas Date: Thu, 14 Jun 2012 14:11:16 +0000 (-0400) Subject: Add new function log_newpage_buffer. X-Git-Tag: REL9_3_BETA1~1347 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6cd015bea38b8a59feb84bf238a880a3b503cf5f;p=postgresql Add new function log_newpage_buffer. When I implemented the ginbuildempty() function as part of implementing unlogged tables, I falsified the note in the header comment for log_newpage. Although we could fix that up by changing the comment, it seems cleaner to add a new function which is specifically intended to handle this case. So do that. --- diff --git a/src/backend/access/gin/gininsert.c b/src/backend/access/gin/gininsert.c index fe06bdcbfa..2f95f718e0 100644 --- a/src/backend/access/gin/gininsert.c +++ b/src/backend/access/gin/gininsert.c @@ -520,20 +520,14 @@ ginbuildempty(PG_FUNCTION_ARGS) ReadBufferExtended(index, INIT_FORKNUM, P_NEW, RBM_NORMAL, NULL); LockBuffer(RootBuffer, BUFFER_LOCK_EXCLUSIVE); - /* Initialize both pages, mark them dirty, unlock and release buffer. */ + /* Initialize and xlog metabuffer and root buffer. */ START_CRIT_SECTION(); GinInitMetabuffer(MetaBuffer); MarkBufferDirty(MetaBuffer); + log_newpage_buffer(MetaBuffer); GinInitBuffer(RootBuffer, GIN_LEAF); MarkBufferDirty(RootBuffer); - - /* XLOG the new pages */ - log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM, - BufferGetBlockNumber(MetaBuffer), - BufferGetPage(MetaBuffer)); - log_newpage(&index->rd_smgr->smgr_rnode.node, INIT_FORKNUM, - BufferGetBlockNumber(RootBuffer), - BufferGetPage(RootBuffer)); + log_newpage_buffer(RootBuffer); END_CRIT_SECTION(); /* Unlock and release the buffers. */ diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 9519e73e54..f28026be0f 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -4479,10 +4479,9 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from, * Perform XLogInsert of a HEAP_NEWPAGE record to WAL. Caller is responsible * for writing the page to disk after calling this routine. * - * Note: all current callers build pages in private memory and write them - * directly to smgr, rather than using bufmgr. Therefore there is no need - * to pass a buffer ID to XLogInsert, nor to perform MarkBufferDirty within - * the critical section. + * Note: If you're using this function, you should be building pages in private + * memory and writing them directly to smgr. If you're using buffers, call + * log_newpage_buffer instead. * * Note: the NEWPAGE log record is used for both heaps and indexes, so do * not do anything that assumes we are touching a heap. @@ -4529,6 +4528,53 @@ log_newpage(RelFileNode *rnode, ForkNumber forkNum, BlockNumber blkno, return recptr; } +/* + * Perform XLogInsert of a HEAP_NEWPAGE record to WAL. + * + * Caller should initialize the buffer and mark it dirty before calling this + * function. This function will set the page LSN and TLI. + * + * Note: the NEWPAGE log record is used for both heaps and indexes, so do + * not do anything that assumes we are touching a heap. + */ +XLogRecPtr +log_newpage_buffer(Buffer buffer) +{ + xl_heap_newpage xlrec; + XLogRecPtr recptr; + XLogRecData rdata[2]; + Page page = BufferGetPage(buffer); + + /* We should be in a critical section. */ + Assert(CritSectionCount > 0); + + BufferGetTag(buffer, &xlrec.node, &xlrec.forknum, &xlrec.blkno); + + rdata[0].data = (char *) &xlrec; + rdata[0].len = SizeOfHeapNewpage; + rdata[0].buffer = InvalidBuffer; + rdata[0].next = &(rdata[1]); + + rdata[1].data = page; + rdata[1].len = BLCKSZ; + rdata[1].buffer = InvalidBuffer; + rdata[1].next = NULL; + + recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_NEWPAGE, rdata); + + /* + * The page may be uninitialized. If so, we can't set the LSN and TLI + * because that would corrupt the page. + */ + if (!PageIsNew(page)) + { + PageSetLSN(page, recptr); + PageSetTLI(page, ThisTimeLineID); + } + + return recptr; +} + /* * Handles CLEANUP_INFO */ diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 026a19fa74..660a854b0e 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -144,6 +144,7 @@ extern XLogRecPtr log_heap_visible(RelFileNode rnode, BlockNumber block, Buffer vm_buffer, TransactionId cutoff_xid); extern XLogRecPtr log_newpage(RelFileNode *rnode, ForkNumber forkNum, BlockNumber blk, Page page); +extern XLogRecPtr log_newpage_buffer(Buffer buffer); /* in heap/pruneheap.c */ extern void heap_page_prune_opt(Relation relation, Buffer buffer,