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.
This commit is contained in:
Jeff Davis 2013-06-17 08:02:12 -07:00
parent 2bc4ab4f9c
commit b8fd1a09f3
15 changed files with 29 additions and 29 deletions

View File

@ -287,7 +287,7 @@ hashgettuple(PG_FUNCTION_ARGS)
/* /*
* Since this can be redone later if needed, mark as a hint. * Since this can be redone later if needed, mark as a hint.
*/ */
MarkBufferDirtyHint(buf); MarkBufferDirtyHint(buf, true);
} }
/* /*

View File

@ -262,7 +262,7 @@ heap_page_prune(Relation relation, Buffer buffer, TransactionId OldestXmin,
{ {
((PageHeader) page)->pd_prune_xid = prstate.new_prune_xid; ((PageHeader) page)->pd_prune_xid = prstate.new_prune_xid;
PageClearFull(page); PageClearFull(page);
MarkBufferDirtyHint(buffer); MarkBufferDirtyHint(buffer, true);
} }
} }

View File

@ -413,9 +413,9 @@ _bt_check_unique(Relation rel, IndexTuple itup, Relation heapRel,
* crucial. Be sure to mark the proper buffer dirty. * crucial. Be sure to mark the proper buffer dirty.
*/ */
if (nbuf != InvalidBuffer) if (nbuf != InvalidBuffer)
MarkBufferDirtyHint(nbuf); MarkBufferDirtyHint(nbuf, true);
else else
MarkBufferDirtyHint(buf); MarkBufferDirtyHint(buf, true);
} }
} }
} }

View File

@ -1052,7 +1052,7 @@ restart:
opaque->btpo_cycleid == vstate->cycleid) opaque->btpo_cycleid == vstate->cycleid)
{ {
opaque->btpo_cycleid = 0; opaque->btpo_cycleid = 0;
MarkBufferDirtyHint(buf); MarkBufferDirtyHint(buf, true);
} }
} }

View File

@ -1789,7 +1789,7 @@ _bt_killitems(IndexScanDesc scan, bool haveLock)
if (killedsomething) if (killedsomething)
{ {
opaque->btpo_flags |= BTP_HAS_GARBAGE; opaque->btpo_flags |= BTP_HAS_GARBAGE;
MarkBufferDirtyHint(so->currPos.buf); MarkBufferDirtyHint(so->currPos.buf, true);
} }
if (!haveLock) if (!haveLock)

View File

@ -82,11 +82,11 @@ xlog_desc(StringInfo buf, uint8 xl_info, char *rec)
appendStringInfo(buf, "restore point: %s", xlrec->rp_name); appendStringInfo(buf, "restore point: %s", xlrec->rp_name);
} }
else if (info == XLOG_HINT) else if (info == XLOG_FPI)
{ {
BkpBlock *bkp = (BkpBlock *) rec; BkpBlock *bkp = (BkpBlock *) rec;
appendStringInfo(buf, "page hint: %s block %u", appendStringInfo(buf, "full-page image: %s block %u",
relpathperm(bkp->node, bkp->fork), relpathperm(bkp->node, bkp->fork),
bkp->block); bkp->block);
} }

View File

@ -7681,12 +7681,9 @@ XLogRestorePoint(const char *rpName)
* records. In that case, multiple copies of the same block would be recorded * 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 * in separate WAL records by different backends, though that is still OK from
* a correctness perspective. * 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 XLogRecPtr
XLogSaveBufferForHint(Buffer buffer) XLogSaveBufferForHint(Buffer buffer, bool buffer_std)
{ {
XLogRecPtr recptr = InvalidXLogRecPtr; XLogRecPtr recptr = InvalidXLogRecPtr;
XLogRecPtr lsn; XLogRecPtr lsn;
@ -7708,7 +7705,7 @@ XLogSaveBufferForHint(Buffer buffer)
* and reset rdata for any actual WAL record insert. * and reset rdata for any actual WAL record insert.
*/ */
rdata[0].buffer = buffer; rdata[0].buffer = buffer;
rdata[0].buffer_std = true; rdata[0].buffer_std = buffer_std;
/* /*
* Check buffer while not holding an exclusive lock. * 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 * 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 * lsn updates. We assume pd_lower/upper cannot be changed without an
* exclusive lock, so the contents bkp are not racy. * 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, origdata, bkpb.hole_offset);
memcpy(copied_buffer + bkpb.hole_offset, memcpy(copied_buffer + bkpb.hole_offset,
@ -7744,7 +7744,7 @@ XLogSaveBufferForHint(Buffer buffer)
rdata[1].buffer = InvalidBuffer; rdata[1].buffer = InvalidBuffer;
rdata[1].next = NULL; rdata[1].next = NULL;
recptr = XLogInsert(RM_XLOG_ID, XLOG_HINT, rdata); recptr = XLogInsert(RM_XLOG_ID, XLOG_FPI, rdata);
} }
return recptr; return recptr;
@ -8109,14 +8109,14 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record)
{ {
/* nothing to do here */ /* nothing to do here */
} }
else if (info == XLOG_HINT) else if (info == XLOG_FPI)
{ {
char *data; char *data;
BkpBlock bkpb; BkpBlock bkpb;
/* /*
* Hint bit records contain a backup block stored "inline" in the * Full-page image (FPI) records contain a backup block stored "inline"
* normal data since the locking when writing hint records isn't * in the normal data since the locking when writing hint records isn't
* sufficient to use the normal backup block mechanism, which assumes * sufficient to use the normal backup block mechanism, which assumes
* exclusive lock on the buffer supplied. * exclusive lock on the buffer supplied.
* *

View File

@ -1118,7 +1118,7 @@ read_seq_tuple(SeqTable elm, Relation rel, Buffer *buf, HeapTuple seqtuple)
HeapTupleHeaderSetXmax(seqtuple->t_data, InvalidTransactionId); HeapTupleHeaderSetXmax(seqtuple->t_data, InvalidTransactionId);
seqtuple->t_data->t_infomask &= ~HEAP_XMAX_COMMITTED; seqtuple->t_data->t_infomask &= ~HEAP_XMAX_COMMITTED;
seqtuple->t_data->t_infomask |= HEAP_XMAX_INVALID; seqtuple->t_data->t_infomask |= HEAP_XMAX_INVALID;
MarkBufferDirtyHint(*buf); MarkBufferDirtyHint(*buf, true);
} }
seq = (Form_pg_sequence) GETSTRUCT(seqtuple); seq = (Form_pg_sequence) GETSTRUCT(seqtuple);

View File

@ -2587,7 +2587,7 @@ IncrBufferRefCount(Buffer buffer)
* (due to a race condition), so it cannot be used for important changes. * (due to a race condition), so it cannot be used for important changes.
*/ */
void void
MarkBufferDirtyHint(Buffer buffer) MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
{ {
volatile BufferDesc *bufHdr; volatile BufferDesc *bufHdr;
Page page = BufferGetPage(buffer); Page page = BufferGetPage(buffer);
@ -2671,7 +2671,7 @@ MarkBufferDirtyHint(Buffer buffer)
* rather than full transactionids. * rather than full transactionids.
*/ */
MyPgXact->delayChkpt = delayChkpt = true; MyPgXact->delayChkpt = delayChkpt = true;
lsn = XLogSaveBufferForHint(buffer); lsn = XLogSaveBufferForHint(buffer, buffer_std);
} }
LockBufHdr(bufHdr); LockBufHdr(bufHdr);

View File

@ -216,7 +216,7 @@ XLogRecordPageWithFreeSpace(RelFileNode rnode, BlockNumber heapBlk,
PageInit(page, BLCKSZ, 0); PageInit(page, BLCKSZ, 0);
if (fsm_set_avail(page, slot, new_cat)) if (fsm_set_avail(page, slot, new_cat))
MarkBufferDirtyHint(buf); MarkBufferDirtyHint(buf, false);
UnlockReleaseBuffer(buf); UnlockReleaseBuffer(buf);
} }
@ -286,7 +286,7 @@ FreeSpaceMapTruncateRel(Relation rel, BlockNumber nblocks)
return; /* nothing to do; the FSM was already smaller */ return; /* nothing to do; the FSM was already smaller */
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
fsm_truncate_avail(BufferGetPage(buf), first_removed_slot); fsm_truncate_avail(BufferGetPage(buf), first_removed_slot);
MarkBufferDirtyHint(buf); MarkBufferDirtyHint(buf, false);
UnlockReleaseBuffer(buf); UnlockReleaseBuffer(buf);
new_nfsmblocks = fsm_logical_to_physical(first_removed_address) + 1; 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); page = BufferGetPage(buf);
if (fsm_set_avail(page, slot, newValue)) if (fsm_set_avail(page, slot, newValue))
MarkBufferDirtyHint(buf); MarkBufferDirtyHint(buf, false);
if (minValue != 0) if (minValue != 0)
{ {
@ -770,7 +770,7 @@ fsm_vacuum_page(Relation rel, FSMAddress addr, bool *eof_p)
{ {
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE); LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
fsm_set_avail(BufferGetPage(buf), slot, child_avail); fsm_set_avail(BufferGetPage(buf), slot, child_avail);
MarkBufferDirtyHint(buf); MarkBufferDirtyHint(buf, false);
LockBuffer(buf, BUFFER_LOCK_UNLOCK); LockBuffer(buf, BUFFER_LOCK_UNLOCK);
} }
} }

View File

@ -284,7 +284,7 @@ restart:
exclusive_lock_held = true; exclusive_lock_held = true;
} }
fsm_rebuild_page(page); fsm_rebuild_page(page);
MarkBufferDirtyHint(buf); MarkBufferDirtyHint(buf, false);
goto restart; goto restart;
} }
} }

View File

@ -121,7 +121,7 @@ SetHintBits(HeapTupleHeader tuple, Buffer buffer,
} }
tuple->t_infomask |= infomask; tuple->t_infomask |= infomask;
MarkBufferDirtyHint(buffer); MarkBufferDirtyHint(buffer, true);
} }
/* /*

View File

@ -267,7 +267,7 @@ extern bool XLogNeedsFlush(XLogRecPtr RecPtr);
extern int XLogFileInit(XLogSegNo segno, bool *use_existent, bool use_lock); extern int XLogFileInit(XLogSegNo segno, bool *use_existent, bool use_lock);
extern int XLogFileOpen(XLogSegNo segno); 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 CheckXLogRemoved(XLogSegNo segno, TimeLineID tli);
extern void XLogSetAsyncXactLSN(XLogRecPtr record); extern void XLogSetAsyncXactLSN(XLogRecPtr record);

View File

@ -67,7 +67,7 @@ typedef struct CheckPoint
#define XLOG_RESTORE_POINT 0x70 #define XLOG_RESTORE_POINT 0x70
#define XLOG_FPW_CHANGE 0x80 #define XLOG_FPW_CHANGE 0x80
#define XLOG_END_OF_RECOVERY 0x90 #define XLOG_END_OF_RECOVERY 0x90
#define XLOG_HINT 0xA0 #define XLOG_FPI 0xA0
/* /*

View File

@ -204,7 +204,7 @@ extern Size BufferShmemSize(void);
extern void BufferGetTag(Buffer buffer, RelFileNode *rnode, extern void BufferGetTag(Buffer buffer, RelFileNode *rnode,
ForkNumber *forknum, BlockNumber *blknum); ForkNumber *forknum, BlockNumber *blknum);
extern void MarkBufferDirtyHint(Buffer buffer); extern void MarkBufferDirtyHint(Buffer buffer, bool buffer_std);
extern void UnlockBuffers(void); extern void UnlockBuffers(void);
extern void LockBuffer(Buffer buffer, int mode); extern void LockBuffer(Buffer buffer, int mode);