From 0affc29e1e8686a0d44165f11cd7818891bcfb46 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 13 Aug 2002 20:11:03 +0000 Subject: [PATCH] Make sure that t_ctid is reset to equal t_self in heap_delete and heap_mark4update; this avoids situations where a deleted tuple might look like it is chained to something else. Also, cause all the WAL redo routines to set t_ctid to equal t_self, rather than leaving it undefined as before. Make heap_xlog_clean set the page's LSN and SUI correctly. All per past discussions in pghackers, ranging back to last December. --- src/backend/access/heap/heapam.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index e9f6947628..325dff88db 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.144 2002/08/06 02:36:33 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.145 2002/08/13 20:11:03 tgl Exp $ * * * INTERFACE ROUTINES @@ -1150,6 +1150,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid) /* NO ELOG(ERROR) from here till changes are logged */ START_CRIT_SECTION(); + RelationPutHeapTuple(relation, buffer, tup); pgstat_count_heap_insert(&relation->pgstat_info); @@ -1336,6 +1337,8 @@ l1: HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE); HeapTupleHeaderSetXmax(tp.t_data, GetCurrentTransactionId()); HeapTupleHeaderSetCmax(tp.t_data, cid); + /* Make sure there is no forward chain link in t_ctid */ + tp.t_data->t_ctid = tp.t_self; /* XLOG stuff */ if (!relation->rd_istemp) @@ -1844,6 +1847,8 @@ l3: tuple->t_data->t_infomask |= HEAP_MARKED_FOR_UPDATE; HeapTupleHeaderSetXmax(tuple->t_data, GetCurrentTransactionId()); HeapTupleHeaderSetCmax(tuple->t_data, cid); + /* Make sure there is no forward chain link in t_ctid */ + tuple->t_data->t_ctid = *tid; LockBuffer(*buffer, BUFFER_LOCK_UNLOCK); @@ -2126,6 +2131,9 @@ heap_xlog_clean(bool redo, XLogRecPtr lsn, XLogRecord *record) } PageRepairFragmentation(page, NULL); + + PageSetLSN(page, lsn); + PageSetSUI(page, ThisStartUpID); /* prev sui */ UnlockAndWriteBuffer(buffer); } @@ -2133,7 +2141,7 @@ static void heap_xlog_delete(bool redo, XLogRecPtr lsn, XLogRecord *record) { xl_heap_delete *xlrec = (xl_heap_delete *) XLogRecGetData(record); - Relation reln = XLogOpenRelation(redo, RM_HEAP_ID, xlrec->target.node); + Relation reln; Buffer buffer; Page page; OffsetNumber offnum; @@ -2143,6 +2151,8 @@ heap_xlog_delete(bool redo, XLogRecPtr lsn, XLogRecord *record) if (redo && (record->xl_info & XLR_BKP_BLOCK_1)) return; + reln = XLogOpenRelation(redo, RM_HEAP_ID, xlrec->target.node); + if (!RelationIsValid(reln)) return; @@ -2186,6 +2196,8 @@ heap_xlog_delete(bool redo, XLogRecPtr lsn, XLogRecord *record) HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE); HeapTupleHeaderSetXmax(htup, record->xl_xid); HeapTupleHeaderSetCmax(htup, FirstCommandId); + /* Make sure there is no forward chain link in t_ctid */ + htup->t_ctid = xlrec->target.tid; PageSetLSN(page, lsn); PageSetSUI(page, ThisStartUpID); UnlockAndWriteBuffer(buffer); @@ -2199,7 +2211,7 @@ static void heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record) { xl_heap_insert *xlrec = (xl_heap_insert *) XLogRecGetData(record); - Relation reln = XLogOpenRelation(redo, RM_HEAP_ID, xlrec->target.node); + Relation reln; Buffer buffer; Page page; OffsetNumber offnum; @@ -2207,6 +2219,8 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record) if (redo && (record->xl_info & XLR_BKP_BLOCK_1)) return; + reln = XLogOpenRelation(redo, RM_HEAP_ID, xlrec->target.node); + if (!RelationIsValid(reln)) return; @@ -2263,6 +2277,7 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record) HeapTupleHeaderSetCmin(htup, FirstCommandId); HeapTupleHeaderSetXmaxInvalid(htup); HeapTupleHeaderSetCmax(htup, FirstCommandId); + htup->t_ctid = xlrec->target.tid; if (reln->rd_rel->relhasoids) { AssertTupleDescHasOid(reln->rd_att); @@ -2352,6 +2367,8 @@ heap_xlog_update(bool redo, XLogRecPtr lsn, XLogRecord *record, bool move) ~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_IN); htup->t_infomask |= HEAP_MOVED_OFF; HeapTupleHeaderSetXvac(htup, record->xl_xid); + /* Make sure there is no forward chain link in t_ctid */ + htup->t_ctid = xlrec->target.tid; } else { @@ -2363,6 +2380,8 @@ heap_xlog_update(bool redo, XLogRecPtr lsn, XLogRecord *record, bool move) HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE); HeapTupleHeaderSetXmax(htup, record->xl_xid); HeapTupleHeaderSetCmax(htup, FirstCommandId); + /* Set forward chain link in t_ctid */ + htup->t_ctid = xlrec->newtid; } if (samepage) goto newsame; @@ -2465,6 +2484,8 @@ newsame:; HeapTupleHeaderSetXmaxInvalid(htup); HeapTupleHeaderSetCmax(htup, FirstCommandId); } + /* Make sure there is no forward chain link in t_ctid */ + htup->t_ctid = xlrec->newtid; offnum = PageAddItem(page, (Item) htup, newlen, offnum, LP_USED | OverwritePageMode);