mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-04 00:02:52 -05:00 
			
		
		
		
	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:
		
							parent
							
								
									a475c60367
								
							
						
					
					
						commit
						6cd015bea3
					
				@ -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. */
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user