From b8fd1a09f382f04c41128fded4d56da2127ce92d Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Mon, 17 Jun 2013 08:02:12 -0700 Subject: [PATCH] Add buffer_std flag to MarkBufferDirtyHint(). MarkBufferDirtyHint() writes WAL, and should know if it's got a standard buffer or not. Currently, the only callers where buffer_std is false are related to the FSM. In passing, rename XLOG_HINT to XLOG_FPI, which is more descriptive. Back-patch to 9.3. --- src/backend/access/hash/hash.c | 2 +- src/backend/access/heap/pruneheap.c | 2 +- src/backend/access/nbtree/nbtinsert.c | 4 ++-- src/backend/access/nbtree/nbtree.c | 2 +- src/backend/access/nbtree/nbtutils.c | 2 +- src/backend/access/rmgrdesc/xlogdesc.c | 4 ++-- src/backend/access/transam/xlog.c | 18 +++++++++--------- src/backend/commands/sequence.c | 2 +- src/backend/storage/buffer/bufmgr.c | 4 ++-- src/backend/storage/freespace/freespace.c | 8 ++++---- src/backend/storage/freespace/fsmpage.c | 2 +- src/backend/utils/time/tqual.c | 2 +- src/include/access/xlog.h | 2 +- src/include/catalog/pg_control.h | 2 +- src/include/storage/bufmgr.h | 2 +- 15 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/backend/access/hash/hash.c b/src/backend/access/hash/hash.c index 5ca27a231e..8895f58503 100644 --- a/src/backend/access/hash/hash.c +++ b/src/backend/access/hash/hash.c @@ -287,7 +287,7 @@ hashgettuple(PG_FUNCTION_ARGS) /* * Since this can be redone later if needed, mark as a hint. */ - MarkBufferDirtyHint(buf); + MarkBufferDirtyHint(buf, true); } /* diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c index 2ab723ddf1..c6e3154293 100644 --- a/src/backend/access/heap/pruneheap.c +++ b/src/backend/access/heap/pruneheap.c @@ -262,7 +262,7 @@ heap_page_prune(Relation relation, Buffer buffer, TransactionId OldestXmin, { ((PageHeader) page)->pd_prune_xid = prstate.new_prune_xid; PageClearFull(page); - MarkBufferDirtyHint(buffer); + MarkBufferDirtyHint(buffer, true); } } diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c index 6ad4f765f5..a452fea841 100644 --- a/src/backend/access/nbtree/nbtinsert.c +++ b/src/backend/access/nbtree/nbtinsert.c @@ -413,9 +413,9 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel, * crucial. Be sure to mark the proper buffer dirty. */ if (nbuf != InvalidBuffer) - MarkBufferDirtyHint(nbuf); + MarkBufferDirtyHint(nbuf, true); else - MarkBufferDirtyHint(buf); + MarkBufferDirtyHint(buf, true); } } } diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c index 621b055639..073190ffd5 100644 --- a/src/backend/access/nbtree/nbtree.c +++ b/src/backend/access/nbtree/nbtree.c @@ -1052,7 +1052,7 @@ restart: opaque->btpo_cycleid == vstate->cycleid) { opaque->btpo_cycleid = 0; - MarkBufferDirtyHint(buf); + MarkBufferDirtyHint(buf, true); } } diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index fe53ec1fe0..352c77cbea 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -1789,7 +1789,7 @@ _bt_killitems(IndexScanDesc scan, bool haveLock) if (killedsomething) { opaque->btpo_flags |= BTP_HAS_GARBAGE; - MarkBufferDirtyHint(so->currPos.buf); + MarkBufferDirtyHint(so->currPos.buf, true); } if (!haveLock) diff --git a/src/backend/access/rmgrdesc/xlogdesc.c b/src/backend/access/rmgrdesc/xlogdesc.c index 2bad52748a..12370521d4 100644 --- a/src/backend/access/rmgrdesc/xlogdesc.c +++ b/src/backend/access/rmgrdesc/xlogdesc.c @@ -82,11 +82,11 @@ xlog_desc(StringInfo buf, uint8 xl_info, char *rec) appendStringInfo(buf, "restore point: %s", xlrec->rp_name); } - else if (info == XLOG_HINT) + else if (info == XLOG_FPI) { BkpBlock *bkp = (BkpBlock *) rec; - appendStringInfo(buf, "page hint: %s block %u", + appendStringInfo(buf, "full-page image: %s block %u", relpathperm(bkp->node, bkp->fork), bkp->block); } diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 654c9c18d8..9f858995d1 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -7681,12 +7681,9 @@ XLogRestorePoint(const char *rpName) * records. In that case, multiple copies of the same block would be recorded * in separate WAL records by different backends, though that is still OK from * a correctness perspective. - * - * Note that this only works for buffers that fit the standard page model, - * i.e. those for which buffer_std == true */ XLogRecPtr -XLogSaveBufferForHint(Buffer buffer) +XLogSaveBufferForHint(Buffer buffer, bool buffer_std) { XLogRecPtr recptr = InvalidXLogRecPtr; XLogRecPtr lsn; @@ -7708,7 +7705,7 @@ XLogSaveBufferForHint(Buffer buffer) * and reset rdata for any actual WAL record insert. */ rdata[0].buffer = buffer; - rdata[0].buffer_std = true; + rdata[0].buffer_std = buffer_std; /* * Check buffer while not holding an exclusive lock. @@ -7722,6 +7719,9 @@ XLogSaveBufferForHint(Buffer buffer) * Copy buffer so we don't have to worry about concurrent hint bit or * lsn updates. We assume pd_lower/upper cannot be changed without an * exclusive lock, so the contents bkp are not racy. + * + * With buffer_std set to false, XLogCheckBuffer() sets hole_length and + * hole_offset to 0; so the following code is safe for either case. */ memcpy(copied_buffer, origdata, bkpb.hole_offset); memcpy(copied_buffer + bkpb.hole_offset, @@ -7744,7 +7744,7 @@ XLogSaveBufferForHint(Buffer buffer) rdata[1].buffer = InvalidBuffer; rdata[1].next = NULL; - recptr = XLogInsert(RM_XLOG_ID, XLOG_HINT, rdata); + recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI, rdata); } return recptr; @@ -8109,14 +8109,14 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record) { /* nothing to do here */ } - else if (info == XLOG_HINT) + else if (info == XLOG_FPI) { char *data; BkpBlock bkpb; /* - * Hint bit records contain a backup block stored "inline" in the - * normal data since the locking when writing hint records isn't + * Full-page image (FPI) records contain a backup block stored "inline" + * in the normal data since the locking when writing hint records isn't * sufficient to use the normal backup block mechanism, which assumes * exclusive lock on the buffer supplied. * diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index bffc12ed0e..ddfaf3bd29 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -1118,7 +1118,7 @@ read_seq_tuple(SeqTable elm, Relation rel, Buffer *buf, HeapTuple seqtuple) HeapTupleHeaderSetXmax(seqtuple->t_data, InvalidTransactionId); seqtuple->t_data->t_infomask &= ~HEAP_XMAX_COMMITTED; seqtuple->t_data->t_infomask |= HEAP_XMAX_INVALID; - MarkBufferDirtyHint(*buf); + MarkBufferDirtyHint(*buf, true); } seq = (Form_pg_sequence) GETSTRUCT(seqtuple); diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index c6b033cf41..8079226864 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -2587,7 +2587,7 @@ IncrBufferRefCount(Buffer buffer) * (due to a race condition), so it cannot be used for important changes. */ void -MarkBufferDirtyHint(Buffer buffer) +MarkBufferDirtyHint(Buffer buffer, bool buffer_std) { volatile BufferDesc *bufHdr; Page page = BufferGetPage(buffer); @@ -2671,7 +2671,7 @@ MarkBufferDirtyHint(Buffer buffer) * rather than full transactionids. */ MyPgXact->delayChkpt = delayChkpt = true; - lsn = XLogSaveBufferForHint(buffer); + lsn = XLogSaveBufferForHint(buffer, buffer_std); } LockBufHdr(bufHdr); diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c index b76bf9be6b..b15cf8fe45 100644 --- a/src/backend/storage/freespace/freespace.c +++ b/src/backend/storage/freespace/freespace.c @@ -216,7 +216,7 @@ XLogRecordPageWithFreeSpace(RelFileNode rnode, BlockNumber heapBlk, PageInit(page, BLCKSZ, 0); if (fsm_set_avail(page, slot, new_cat)) - MarkBufferDirtyHint(buf); + MarkBufferDirtyHint(buf, false); UnlockReleaseBuffer(buf); } @@ -286,7 +286,7 @@ FreeSpaceMapTruncateRel(Relation rel, BlockNumber nblocks) return; /* nothing to do; the FSM was already smaller */ LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); fsm_truncate_avail(BufferGetPage(buf), first_removed_slot); - MarkBufferDirtyHint(buf); + MarkBufferDirtyHint(buf, false); UnlockReleaseBuffer(buf); new_nfsmblocks = fsm_logical_to_physical(first_removed_address) + 1; @@ -619,7 +619,7 @@ fsm_set_and_search(Relation rel, FSMAddress addr, uint16 slot, page = BufferGetPage(buf); if (fsm_set_avail(page, slot, newValue)) - MarkBufferDirtyHint(buf); + MarkBufferDirtyHint(buf, false); if (minValue != 0) { @@ -770,7 +770,7 @@ fsm_vacuum_page(Relation rel, FSMAddress addr, bool *eof_p) { LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); fsm_set_avail(BufferGetPage(buf), slot, child_avail); - MarkBufferDirtyHint(buf); + MarkBufferDirtyHint(buf, false); LockBuffer(buf, BUFFER_LOCK_UNLOCK); } } diff --git a/src/backend/storage/freespace/fsmpage.c b/src/backend/storage/freespace/fsmpage.c index 19c8e09148..8376a7fc0f 100644 --- a/src/backend/storage/freespace/fsmpage.c +++ b/src/backend/storage/freespace/fsmpage.c @@ -284,7 +284,7 @@ restart: exclusive_lock_held = true; } fsm_rebuild_page(page); - MarkBufferDirtyHint(buf); + MarkBufferDirtyHint(buf, false); goto restart; } } diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c index ab4020a710..55563ea335 100644 --- a/src/backend/utils/time/tqual.c +++ b/src/backend/utils/time/tqual.c @@ -121,7 +121,7 @@ SetHintBits(HeapTupleHeader tuple, Buffer buffer, } tuple->t_infomask |= infomask; - MarkBufferDirtyHint(buffer); + MarkBufferDirtyHint(buffer, true); } /* diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index b4a75cee22..83e583259d 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -267,7 +267,7 @@ extern bool XLogNeedsFlush(XLogRecPtr RecPtr); extern int XLogFileInit(XLogSegNo segno, bool *use_existent, bool use_lock); extern int XLogFileOpen(XLogSegNo segno); -extern XLogRecPtr XLogSaveBufferForHint(Buffer buffer); +extern XLogRecPtr XLogSaveBufferForHint(Buffer buffer, bool buffer_std); extern void CheckXLogRemoved(XLogSegNo segno, TimeLineID tli); extern void XLogSetAsyncXactLSN(XLogRecPtr record); diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h index 4f154a9589..0e297610d8 100644 --- a/src/include/catalog/pg_control.h +++ b/src/include/catalog/pg_control.h @@ -67,7 +67,7 @@ typedef struct CheckPoint #define XLOG_RESTORE_POINT 0x70 #define XLOG_FPW_CHANGE 0x80 #define XLOG_END_OF_RECOVERY 0x90 -#define XLOG_HINT 0xA0 +#define XLOG_FPI 0xA0 /* diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h index 9be1860842..6dc031ead5 100644 --- a/src/include/storage/bufmgr.h +++ b/src/include/storage/bufmgr.h @@ -204,7 +204,7 @@ extern Size BufferShmemSize(void); extern void BufferGetTag(Buffer buffer, RelFileNode *rnode, ForkNumber *forknum, BlockNumber *blknum); -extern void MarkBufferDirtyHint(Buffer buffer); +extern void MarkBufferDirtyHint(Buffer buffer, bool buffer_std); extern void UnlockBuffers(void); extern void LockBuffer(Buffer buffer, int mode);