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.
This commit is contained in:
Robert Haas 2012-06-14 10:11:16 -04:00
parent a475c60367
commit 6cd015bea3
3 changed files with 54 additions and 13 deletions

View File

@ -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. */

View File

@ -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
*/

View File

@ -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,