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