On Mon, 15 Jul 2002 16:46:44 -0400, Tom Lane <[EMAIL PROTECTED]> wrote: >regression=# update foo set f1 = 'qq'; >server closed the connection unexpectedly
Same with DELETE FROM foo; >I am not sure if this is a bug introduced by the patch, or if it's >exposed a previously lurking bug. I suspect the former :-( >It seems that the HEAP_MOVED bits >should be cleared before re-using cmax for something else, but I have >not dug through the old logic to see how it was done before. AFAICS from a quick look at tqual it didn't matter before. Once the vacuum transaction had committed, on the next access to the tuple MOVED_IN caused XMIN_COMMITTED to be set, and after that the MOVED bits were never looked at again. MOVED_OFF is not an issue. I'll take a closer look at tqual and the vacuum source code tomorrow. For now the attached patch cures both symptoms (UPDATE and DELETE) and passes all regression tests. A regression test for this case will follow. Servus Manfred
diff -ruN ../base/src/backend/access/heap/heapam.c src/backend/access/heap/heapam.c --- ../base/src/backend/access/heap/heapam.c 2002-07-15 22:22:28.000000000 +0200 +++ src/backend/access/heap/heapam.c 2002-07-16 00:16:59.000000000 +0200 @@ -1123,11 +1123,11 @@ CheckMaxObjectId(HeapTupleGetOid(tup)); } + tup->t_data->t_infomask &= ~(HEAP_XACT_MASK); HeapTupleHeaderSetXmin(tup->t_data, GetCurrentTransactionId()); HeapTupleHeaderSetCmin(tup->t_data, cid); HeapTupleHeaderSetXmaxInvalid(tup->t_data); - HeapTupleHeaderSetCmax(tup->t_data, FirstCommandId); - tup->t_data->t_infomask &= ~(HEAP_XACT_MASK); + /* HeapTupleHeaderSetCmax(tup->t_data, FirstCommandId); */ tup->t_data->t_infomask |= HEAP_XMAX_INVALID; tup->t_tableOid = relation->rd_id; @@ -1321,7 +1321,7 @@ START_CRIT_SECTION(); /* store transaction information of xact deleting the tuple */ - tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | + tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_MOVED | HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE); HeapTupleHeaderSetXmax(tp.t_data, GetCurrentTransactionId()); HeapTupleHeaderSetCmax(tp.t_data, cid); @@ -1554,7 +1554,7 @@ _locked_tuple_.tid = oldtup.t_self; XactPushRollback(_heap_unlock_tuple, (void *) &_locked_tuple_); - oldtup.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | + oldtup.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_MOVED | HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE); oldtup.t_data->t_infomask |= HEAP_XMAX_UNLOGGED; @@ -1645,7 +1645,7 @@ } else { - oldtup.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | + oldtup.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_MOVED | HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE); HeapTupleHeaderSetXmax(oldtup.t_data, GetCurrentTransactionId()); @@ -1816,7 +1816,7 @@ ((PageHeader) BufferGetPage(*buffer))->pd_sui = ThisStartUpID; /* store transaction information of xact marking the tuple */ - tuple->t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID); + tuple->t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_XMAX_INVALID | +HEAP_MOVED); tuple->t_data->t_infomask |= HEAP_MARKED_FOR_UPDATE; HeapTupleHeaderSetXmax(tuple->t_data, GetCurrentTransactionId()); HeapTupleHeaderSetCmax(tuple->t_data, cid); @@ -2147,7 +2147,7 @@ if (redo) { - htup->t_infomask &= ~(HEAP_XMAX_COMMITTED | + htup->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_MOVED | HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE); HeapTupleHeaderSetXmax(htup, record->xl_xid); HeapTupleHeaderSetCmax(htup, FirstCommandId); @@ -2320,7 +2320,7 @@ } else { - htup->t_infomask &= ~(HEAP_XMAX_COMMITTED | + htup->t_infomask &= ~(HEAP_XMAX_COMMITTED | HEAP_MOVED | HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE); HeapTupleHeaderSetXmax(htup, record->xl_xid); HeapTupleHeaderSetCmax(htup, FirstCommandId);
---------------------------(end of broadcast)--------------------------- TIP 6: Have you searched our list archives? http://archives.postgresql.org