mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-27 23:01:55 +02:00
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.
This commit is contained in:
parent
1e4c4f9eb7
commit
0affc29e1e
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* INTERFACE ROUTINES
|
||||||
@ -1150,6 +1150,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid)
|
|||||||
|
|
||||||
/* NO ELOG(ERROR) from here till changes are logged */
|
/* NO ELOG(ERROR) from here till changes are logged */
|
||||||
START_CRIT_SECTION();
|
START_CRIT_SECTION();
|
||||||
|
|
||||||
RelationPutHeapTuple(relation, buffer, tup);
|
RelationPutHeapTuple(relation, buffer, tup);
|
||||||
|
|
||||||
pgstat_count_heap_insert(&relation->pgstat_info);
|
pgstat_count_heap_insert(&relation->pgstat_info);
|
||||||
@ -1336,6 +1337,8 @@ l1:
|
|||||||
HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
|
HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
|
||||||
HeapTupleHeaderSetXmax(tp.t_data, GetCurrentTransactionId());
|
HeapTupleHeaderSetXmax(tp.t_data, GetCurrentTransactionId());
|
||||||
HeapTupleHeaderSetCmax(tp.t_data, cid);
|
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 */
|
/* XLOG stuff */
|
||||||
if (!relation->rd_istemp)
|
if (!relation->rd_istemp)
|
||||||
@ -1844,6 +1847,8 @@ l3:
|
|||||||
tuple->t_data->t_infomask |= HEAP_MARKED_FOR_UPDATE;
|
tuple->t_data->t_infomask |= HEAP_MARKED_FOR_UPDATE;
|
||||||
HeapTupleHeaderSetXmax(tuple->t_data, GetCurrentTransactionId());
|
HeapTupleHeaderSetXmax(tuple->t_data, GetCurrentTransactionId());
|
||||||
HeapTupleHeaderSetCmax(tuple->t_data, cid);
|
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);
|
LockBuffer(*buffer, BUFFER_LOCK_UNLOCK);
|
||||||
|
|
||||||
@ -2126,6 +2131,9 @@ heap_xlog_clean(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
|||||||
}
|
}
|
||||||
|
|
||||||
PageRepairFragmentation(page, NULL);
|
PageRepairFragmentation(page, NULL);
|
||||||
|
|
||||||
|
PageSetLSN(page, lsn);
|
||||||
|
PageSetSUI(page, ThisStartUpID); /* prev sui */
|
||||||
UnlockAndWriteBuffer(buffer);
|
UnlockAndWriteBuffer(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2133,7 +2141,7 @@ static void
|
|||||||
heap_xlog_delete(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
heap_xlog_delete(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
||||||
{
|
{
|
||||||
xl_heap_delete *xlrec = (xl_heap_delete *) XLogRecGetData(record);
|
xl_heap_delete *xlrec = (xl_heap_delete *) XLogRecGetData(record);
|
||||||
Relation reln = XLogOpenRelation(redo, RM_HEAP_ID, xlrec->target.node);
|
Relation reln;
|
||||||
Buffer buffer;
|
Buffer buffer;
|
||||||
Page page;
|
Page page;
|
||||||
OffsetNumber offnum;
|
OffsetNumber offnum;
|
||||||
@ -2143,6 +2151,8 @@ heap_xlog_delete(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
|||||||
if (redo && (record->xl_info & XLR_BKP_BLOCK_1))
|
if (redo && (record->xl_info & XLR_BKP_BLOCK_1))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
reln = XLogOpenRelation(redo, RM_HEAP_ID, xlrec->target.node);
|
||||||
|
|
||||||
if (!RelationIsValid(reln))
|
if (!RelationIsValid(reln))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -2186,6 +2196,8 @@ heap_xlog_delete(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
|||||||
HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
|
HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
|
||||||
HeapTupleHeaderSetXmax(htup, record->xl_xid);
|
HeapTupleHeaderSetXmax(htup, record->xl_xid);
|
||||||
HeapTupleHeaderSetCmax(htup, FirstCommandId);
|
HeapTupleHeaderSetCmax(htup, FirstCommandId);
|
||||||
|
/* Make sure there is no forward chain link in t_ctid */
|
||||||
|
htup->t_ctid = xlrec->target.tid;
|
||||||
PageSetLSN(page, lsn);
|
PageSetLSN(page, lsn);
|
||||||
PageSetSUI(page, ThisStartUpID);
|
PageSetSUI(page, ThisStartUpID);
|
||||||
UnlockAndWriteBuffer(buffer);
|
UnlockAndWriteBuffer(buffer);
|
||||||
@ -2199,7 +2211,7 @@ static void
|
|||||||
heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
||||||
{
|
{
|
||||||
xl_heap_insert *xlrec = (xl_heap_insert *) XLogRecGetData(record);
|
xl_heap_insert *xlrec = (xl_heap_insert *) XLogRecGetData(record);
|
||||||
Relation reln = XLogOpenRelation(redo, RM_HEAP_ID, xlrec->target.node);
|
Relation reln;
|
||||||
Buffer buffer;
|
Buffer buffer;
|
||||||
Page page;
|
Page page;
|
||||||
OffsetNumber offnum;
|
OffsetNumber offnum;
|
||||||
@ -2207,6 +2219,8 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
|||||||
if (redo && (record->xl_info & XLR_BKP_BLOCK_1))
|
if (redo && (record->xl_info & XLR_BKP_BLOCK_1))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
reln = XLogOpenRelation(redo, RM_HEAP_ID, xlrec->target.node);
|
||||||
|
|
||||||
if (!RelationIsValid(reln))
|
if (!RelationIsValid(reln))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -2263,6 +2277,7 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
|
|||||||
HeapTupleHeaderSetCmin(htup, FirstCommandId);
|
HeapTupleHeaderSetCmin(htup, FirstCommandId);
|
||||||
HeapTupleHeaderSetXmaxInvalid(htup);
|
HeapTupleHeaderSetXmaxInvalid(htup);
|
||||||
HeapTupleHeaderSetCmax(htup, FirstCommandId);
|
HeapTupleHeaderSetCmax(htup, FirstCommandId);
|
||||||
|
htup->t_ctid = xlrec->target.tid;
|
||||||
if (reln->rd_rel->relhasoids)
|
if (reln->rd_rel->relhasoids)
|
||||||
{
|
{
|
||||||
AssertTupleDescHasOid(reln->rd_att);
|
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);
|
~(HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID | HEAP_MOVED_IN);
|
||||||
htup->t_infomask |= HEAP_MOVED_OFF;
|
htup->t_infomask |= HEAP_MOVED_OFF;
|
||||||
HeapTupleHeaderSetXvac(htup, record->xl_xid);
|
HeapTupleHeaderSetXvac(htup, record->xl_xid);
|
||||||
|
/* Make sure there is no forward chain link in t_ctid */
|
||||||
|
htup->t_ctid = xlrec->target.tid;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2363,6 +2380,8 @@ heap_xlog_update(bool redo, XLogRecPtr lsn, XLogRecord *record, bool move)
|
|||||||
HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
|
HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
|
||||||
HeapTupleHeaderSetXmax(htup, record->xl_xid);
|
HeapTupleHeaderSetXmax(htup, record->xl_xid);
|
||||||
HeapTupleHeaderSetCmax(htup, FirstCommandId);
|
HeapTupleHeaderSetCmax(htup, FirstCommandId);
|
||||||
|
/* Set forward chain link in t_ctid */
|
||||||
|
htup->t_ctid = xlrec->newtid;
|
||||||
}
|
}
|
||||||
if (samepage)
|
if (samepage)
|
||||||
goto newsame;
|
goto newsame;
|
||||||
@ -2465,6 +2484,8 @@ newsame:;
|
|||||||
HeapTupleHeaderSetXmaxInvalid(htup);
|
HeapTupleHeaderSetXmaxInvalid(htup);
|
||||||
HeapTupleHeaderSetCmax(htup, FirstCommandId);
|
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,
|
offnum = PageAddItem(page, (Item) htup, newlen, offnum,
|
||||||
LP_USED | OverwritePageMode);
|
LP_USED | OverwritePageMode);
|
||||||
|
Loading…
Reference in New Issue
Block a user