aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/heap/heapam.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/heap/heapam.c')
-rw-r--r--src/backend/access/heap/heapam.c187
1 files changed, 44 insertions, 143 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 0d9ad2af045..9983ff65c8a 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.285 2010/02/03 10:01:29 heikki Exp $
+ * $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.286 2010/02/08 04:33:52 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -79,7 +79,7 @@ static HeapScanDesc heap_beginscan_internal(Relation relation,
bool allow_strat, bool allow_sync,
bool is_bitmapscan);
static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf,
- ItemPointerData from, Buffer newbuf, HeapTuple newtup, bool move,
+ ItemPointerData from, Buffer newbuf, HeapTuple newtup,
bool all_visible_cleared, bool new_all_visible_cleared);
static bool HeapSatisfiesHOTUpdate(Relation relation, Bitmapset *hot_attrs,
HeapTuple oldtup, HeapTuple newtup);
@@ -2785,7 +2785,7 @@ l2:
if (!relation->rd_istemp)
{
XLogRecPtr recptr = log_heap_update(relation, buffer, oldtup.t_self,
- newbuf, heaptup, false,
+ newbuf, heaptup,
all_visible_cleared,
all_visible_cleared_new);
@@ -3664,9 +3664,13 @@ recheck_xmax:
}
/*
- * Although xvac per se could only be set by VACUUM, it shares physical
- * storage space with cmax, and so could be wiped out by someone setting
- * xmax. Hence recheck after changing lock, same as for xmax itself.
+ * Although xvac per se could only be set by old-style VACUUM FULL, it
+ * shares physical storage space with cmax, and so could be wiped out by
+ * someone setting xmax. Hence recheck after changing lock, same as for
+ * xmax itself.
+ *
+ * Old-style VACUUM FULL is gone, but we have to keep this code as long
+ * as we support having MOVED_OFF/MOVED_IN tuples in the database.
*/
recheck_xvac:
if (tuple->t_infomask & HEAP_MOVED)
@@ -3785,8 +3789,7 @@ HeapTupleHeaderAdvanceLatestRemovedXid(HeapTupleHeader tuple,
TransactionId xmax = HeapTupleHeaderGetXmax(tuple);
TransactionId xvac = HeapTupleHeaderGetXvac(tuple);
- if (tuple->t_infomask & HEAP_MOVED_OFF ||
- tuple->t_infomask & HEAP_MOVED_IN)
+ if (tuple->t_infomask & HEAP_MOVED)
{
if (TransactionIdPrecedes(*latestRemovedXid, xvac))
*latestRemovedXid = xvac;
@@ -3844,7 +3847,7 @@ log_heap_clean(Relation reln, Buffer buffer,
OffsetNumber *redirected, int nredirected,
OffsetNumber *nowdead, int ndead,
OffsetNumber *nowunused, int nunused,
- TransactionId latestRemovedXid, bool redirect_move)
+ TransactionId latestRemovedXid)
{
xl_heap_clean xlrec;
uint8 info;
@@ -3915,7 +3918,7 @@ log_heap_clean(Relation reln, Buffer buffer,
rdata[3].buffer_std = true;
rdata[3].next = NULL;
- info = redirect_move ? XLOG_HEAP2_CLEAN_MOVE : XLOG_HEAP2_CLEAN;
+ info = XLOG_HEAP2_CLEAN;
recptr = XLogInsert(RM_HEAP2_ID, info, rdata);
return recptr;
@@ -3970,23 +3973,11 @@ log_heap_freeze(Relation reln, Buffer buffer,
*/
static XLogRecPtr
log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from,
- Buffer newbuf, HeapTuple newtup, bool move,
+ Buffer newbuf, HeapTuple newtup,
bool all_visible_cleared, bool new_all_visible_cleared)
{
- /*
- * Note: xlhdr is declared to have adequate size and correct alignment for
- * an xl_heap_header. However the two tids, if present at all, will be
- * packed in with no wasted space after the xl_heap_header; they aren't
- * necessarily aligned as implied by this struct declaration.
- */
- struct
- {
- xl_heap_header hdr;
- TransactionId tid1;
- TransactionId tid2;
- } xlhdr;
- int hsize = SizeOfHeapHeader;
xl_heap_update xlrec;
+ xl_heap_header xlhdr;
uint8 info;
XLogRecPtr recptr;
XLogRecData rdata[4];
@@ -3995,12 +3986,7 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from,
/* Caller should not call me on a temp relation */
Assert(!reln->rd_istemp);
- if (move)
- {
- Assert(!HeapTupleIsHeapOnly(newtup));
- info = XLOG_HEAP_MOVE;
- }
- else if (HeapTupleIsHeapOnly(newtup))
+ if (HeapTupleIsHeapOnly(newtup))
info = XLOG_HEAP_HOT_UPDATE;
else
info = XLOG_HEAP_UPDATE;
@@ -4022,30 +4008,16 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from,
rdata[1].buffer_std = true;
rdata[1].next = &(rdata[2]);
- xlhdr.hdr.t_infomask2 = newtup->t_data->t_infomask2;
- xlhdr.hdr.t_infomask = newtup->t_data->t_infomask;
- xlhdr.hdr.t_hoff = newtup->t_data->t_hoff;
- if (move) /* remember xmax & xmin */
- {
- TransactionId xid[2]; /* xmax, xmin */
-
- if (newtup->t_data->t_infomask & (HEAP_XMAX_INVALID | HEAP_IS_LOCKED))
- xid[0] = InvalidTransactionId;
- else
- xid[0] = HeapTupleHeaderGetXmax(newtup->t_data);
- xid[1] = HeapTupleHeaderGetXmin(newtup->t_data);
- memcpy((char *) &xlhdr + hsize,
- (char *) xid,
- 2 * sizeof(TransactionId));
- hsize += 2 * sizeof(TransactionId);
- }
+ xlhdr.t_infomask2 = newtup->t_data->t_infomask2;
+ xlhdr.t_infomask = newtup->t_data->t_infomask;
+ xlhdr.t_hoff = newtup->t_data->t_hoff;
/*
* As with insert records, we need not store the rdata[2] segment if we
* decide to store the whole buffer instead.
*/
rdata[2].data = (char *) &xlhdr;
- rdata[2].len = hsize;
+ rdata[2].len = SizeOfHeapHeader;
rdata[2].buffer = newbuf;
rdata[2].buffer_std = true;
rdata[2].next = &(rdata[3]);
@@ -4071,19 +4043,6 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from,
}
/*
- * Perform XLogInsert for a heap-move operation. Caller must already
- * have modified the buffers and marked them dirty.
- */
-XLogRecPtr
-log_heap_move(Relation reln, Buffer oldbuf, ItemPointerData from,
- Buffer newbuf, HeapTuple newtup,
- bool all_visible_cleared, bool new_all_visible_cleared)
-{
- return log_heap_update(reln, oldbuf, from, newbuf, newtup, true,
- all_visible_cleared, new_all_visible_cleared);
-}
-
-/*
* Perform XLogInsert of a HEAP_NEWPAGE record to WAL. Caller is responsible
* for writing the page to disk after calling this routine.
*
@@ -4149,10 +4108,10 @@ heap_xlog_cleanup_info(XLogRecPtr lsn, XLogRecord *record)
}
/*
- * Handles CLEAN and CLEAN_MOVE record types
+ * Handles HEAP_CLEAN record type
*/
static void
-heap_xlog_clean(XLogRecPtr lsn, XLogRecord *record, bool clean_move)
+heap_xlog_clean(XLogRecPtr lsn, XLogRecord *record)
{
xl_heap_clean *xlrec = (xl_heap_clean *) XLogRecGetData(record);
Buffer buffer;
@@ -4171,7 +4130,8 @@ heap_xlog_clean(XLogRecPtr lsn, XLogRecord *record, bool clean_move)
* no queries running for which the removed tuples are still visible.
*/
if (InHotStandby)
- ResolveRecoveryConflictWithSnapshot(xlrec->latestRemovedXid, xlrec->node);
+ ResolveRecoveryConflictWithSnapshot(xlrec->latestRemovedXid,
+ xlrec->node);
RestoreBkpBlocks(lsn, record, true);
@@ -4203,8 +4163,7 @@ heap_xlog_clean(XLogRecPtr lsn, XLogRecord *record, bool clean_move)
heap_page_prune_execute(buffer,
redirected, nredirected,
nowdead, ndead,
- nowunused, nunused,
- clean_move);
+ nowunused, nunused);
freespace = PageGetHeapFreeSpace(page); /* needed to update FSM below */
@@ -4489,10 +4448,10 @@ heap_xlog_insert(XLogRecPtr lsn, XLogRecord *record)
}
/*
- * Handles UPDATE, HOT_UPDATE & MOVE
+ * Handles UPDATE and HOT_UPDATE
*/
static void
-heap_xlog_update(XLogRecPtr lsn, XLogRecord *record, bool move, bool hot_update)
+heap_xlog_update(XLogRecPtr lsn, XLogRecord *record, bool hot_update)
{
xl_heap_update *xlrec = (xl_heap_update *) XLogRecGetData(record);
Buffer buffer;
@@ -4558,33 +4517,19 @@ heap_xlog_update(XLogRecPtr lsn, XLogRecord *record, bool move, bool hot_update)
htup = (HeapTupleHeader) PageGetItem(page, lp);
- if (move)
- {
- htup->t_infomask &= ~(HEAP_XMIN_COMMITTED |
- HEAP_XMIN_INVALID |
- HEAP_MOVED_IN);
- htup->t_infomask |= HEAP_MOVED_OFF;
- HeapTupleHeaderClearHotUpdated(htup);
- HeapTupleHeaderSetXvac(htup, record->xl_xid);
- /* Make sure there is no forward chain link in t_ctid */
- htup->t_ctid = xlrec->target.tid;
- }
+ htup->t_infomask &= ~(HEAP_XMAX_COMMITTED |
+ HEAP_XMAX_INVALID |
+ HEAP_XMAX_IS_MULTI |
+ HEAP_IS_LOCKED |
+ HEAP_MOVED);
+ if (hot_update)
+ HeapTupleHeaderSetHotUpdated(htup);
else
- {
- htup->t_infomask &= ~(HEAP_XMAX_COMMITTED |
- HEAP_XMAX_INVALID |
- HEAP_XMAX_IS_MULTI |
- HEAP_IS_LOCKED |
- HEAP_MOVED);
- if (hot_update)
- HeapTupleHeaderSetHotUpdated(htup);
- else
- HeapTupleHeaderClearHotUpdated(htup);
- HeapTupleHeaderSetXmax(htup, record->xl_xid);
- HeapTupleHeaderSetCmax(htup, FirstCommandId, false);
- /* Set forward chain link in t_ctid */
- htup->t_ctid = xlrec->newtid;
- }
+ HeapTupleHeaderClearHotUpdated(htup);
+ HeapTupleHeaderSetXmax(htup, record->xl_xid);
+ HeapTupleHeaderSetCmax(htup, FirstCommandId, false);
+ /* Set forward chain link in t_ctid */
+ htup->t_ctid = xlrec->newtid;
/* Mark the page as a candidate for pruning */
PageSetPrunable(page, record->xl_xid);
@@ -4655,8 +4600,6 @@ newsame:;
elog(PANIC, "heap_update_redo: invalid max offset number");
hsize = SizeOfHeapUpdate + SizeOfHeapHeader;
- if (move)
- hsize += (2 * sizeof(TransactionId));
newlen = record->xl_len - hsize;
Assert(newlen <= MaxHeapTupleSize);
@@ -4674,22 +4617,8 @@ newsame:;
htup->t_infomask = xlhdr.t_infomask;
htup->t_hoff = xlhdr.t_hoff;
- if (move)
- {
- TransactionId xid[2]; /* xmax, xmin */
-
- memcpy((char *) xid,
- (char *) xlrec + SizeOfHeapUpdate + SizeOfHeapHeader,
- 2 * sizeof(TransactionId));
- HeapTupleHeaderSetXmin(htup, xid[1]);
- HeapTupleHeaderSetXmax(htup, xid[0]);
- HeapTupleHeaderSetXvac(htup, record->xl_xid);
- }
- else
- {
- HeapTupleHeaderSetXmin(htup, record->xl_xid);
- HeapTupleHeaderSetCmin(htup, FirstCommandId);
- }
+ HeapTupleHeaderSetXmin(htup, record->xl_xid);
+ HeapTupleHeaderSetCmin(htup, FirstCommandId);
/* Make sure there is no forward chain link in t_ctid */
htup->t_ctid = xlrec->newtid;
@@ -4857,13 +4786,10 @@ heap_redo(XLogRecPtr lsn, XLogRecord *record)
heap_xlog_delete(lsn, record);
break;
case XLOG_HEAP_UPDATE:
- heap_xlog_update(lsn, record, false, false);
- break;
- case XLOG_HEAP_MOVE:
- heap_xlog_update(lsn, record, true, false);
+ heap_xlog_update(lsn, record, false);
break;
case XLOG_HEAP_HOT_UPDATE:
- heap_xlog_update(lsn, record, false, true);
+ heap_xlog_update(lsn, record, true);
break;
case XLOG_HEAP_NEWPAGE:
heap_xlog_newpage(lsn, record);
@@ -4895,10 +4821,7 @@ heap2_redo(XLogRecPtr lsn, XLogRecord *record)
heap_xlog_freeze(lsn, record);
break;
case XLOG_HEAP2_CLEAN:
- heap_xlog_clean(lsn, record, false);
- break;
- case XLOG_HEAP2_CLEAN_MOVE:
- heap_xlog_clean(lsn, record, true);
+ heap_xlog_clean(lsn, record);
break;
case XLOG_HEAP2_CLEANUP_INFO:
heap_xlog_cleanup_info(lsn, record);
@@ -4953,19 +4876,6 @@ heap_desc(StringInfo buf, uint8 xl_info, char *rec)
ItemPointerGetBlockNumber(&(xlrec->newtid)),
ItemPointerGetOffsetNumber(&(xlrec->newtid)));
}
- else if (info == XLOG_HEAP_MOVE)
- {
- xl_heap_update *xlrec = (xl_heap_update *) rec;
-
- if (xl_info & XLOG_HEAP_INIT_PAGE)
- appendStringInfo(buf, "move(init): ");
- else
- appendStringInfo(buf, "move: ");
- out_target(buf, &(xlrec->target));
- appendStringInfo(buf, "; new %u/%u",
- ItemPointerGetBlockNumber(&(xlrec->newtid)),
- ItemPointerGetOffsetNumber(&(xlrec->newtid)));
- }
else if (info == XLOG_HEAP_HOT_UPDATE)
{
xl_heap_update *xlrec = (xl_heap_update *) rec;
@@ -5037,15 +4947,6 @@ heap2_desc(StringInfo buf, uint8 xl_info, char *rec)
xlrec->node.relNode, xlrec->block,
xlrec->latestRemovedXid);
}
- else if (info == XLOG_HEAP2_CLEAN_MOVE)
- {
- xl_heap_clean *xlrec = (xl_heap_clean *) rec;
-
- appendStringInfo(buf, "clean_move: rel %u/%u/%u; blk %u remxid %u",
- xlrec->node.spcNode, xlrec->node.dbNode,
- xlrec->node.relNode, xlrec->block,
- xlrec->latestRemovedXid);
- }
else if (info == XLOG_HEAP2_CLEANUP_INFO)
{
xl_heap_cleanup_info *xlrec = (xl_heap_cleanup_info *) rec;