Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit08ba67d

Browse files
committed
Revert bogus fixes of HOT-freezing bug
It turns out we misdiagnosed what the real problem was. Revert theprevious changes, because they may have worse consequences goingforward. A better fix is forthcoming.The simplistic test case is kept, though disabled.Discussion:https://postgr.es/m/20171102112019.33wb7g5wp4zpjelu@alap3.anarazel.de
1 parent1cf96d6 commit08ba67d

File tree

6 files changed

+38
-105
lines changed

6 files changed

+38
-105
lines changed

‎src/backend/access/heap/heapam.c

Lines changed: 22 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -2046,7 +2046,8 @@ heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer,
20462046
* broken.
20472047
*/
20482048
if (TransactionIdIsValid(prev_xmax)&&
2049-
!HeapTupleUpdateXmaxMatchesXmin(prev_xmax,heapTuple->t_data))
2049+
!TransactionIdEquals(prev_xmax,
2050+
HeapTupleHeaderGetXmin(heapTuple->t_data)))
20502051
break;
20512052

20522053
/*
@@ -2229,7 +2230,7 @@ heap_get_latest_tid(Relation relation,
22292230
* tuple. Check for XMIN match.
22302231
*/
22312232
if (TransactionIdIsValid(priorXmax)&&
2232-
!HeapTupleUpdateXmaxMatchesXmin(priorXmax,tp.t_data))
2233+
!TransactionIdEquals(priorXmax,HeapTupleHeaderGetXmin(tp.t_data)))
22332234
{
22342235
UnlockReleaseBuffer(buffer);
22352236
break;
@@ -2261,50 +2262,6 @@ heap_get_latest_tid(Relation relation,
22612262
}/* end of loop */
22622263
}
22632264

2264-
/*
2265-
* HeapTupleUpdateXmaxMatchesXmin - verify update chain xmax/xmin lineage
2266-
*
2267-
* Given the new version of a tuple after some update, verify whether the
2268-
* given Xmax (corresponding to the previous version) matches the tuple's
2269-
* Xmin, taking into account that the Xmin might have been frozen after the
2270-
* update.
2271-
*/
2272-
bool
2273-
HeapTupleUpdateXmaxMatchesXmin(TransactionIdxmax,HeapTupleHeaderhtup)
2274-
{
2275-
TransactionIdxmin=HeapTupleHeaderGetXmin(htup);
2276-
2277-
/*
2278-
* If the xmax of the old tuple is identical to the xmin of the new one,
2279-
* it's a match.
2280-
*/
2281-
if (TransactionIdEquals(xmax,xmin))
2282-
return true;
2283-
2284-
/*
2285-
* If the Xmin that was in effect prior to a freeze matches the Xmax,
2286-
* it's good too.
2287-
*/
2288-
if (HeapTupleHeaderXminFrozen(htup)&&
2289-
TransactionIdEquals(HeapTupleHeaderGetRawXmin(htup),xmax))
2290-
return true;
2291-
2292-
/*
2293-
* When a tuple is frozen, the original Xmin is lost, but we know it's a
2294-
* committed transaction. So unless the Xmax is InvalidXid, we don't know
2295-
* for certain that there is a match, but there may be one; and we must
2296-
* return true so that a HOT chain that is half-frozen can be walked
2297-
* correctly.
2298-
*
2299-
* We no longer freeze tuples this way, but we must keep this in order to
2300-
* interpret pre-pg_upgrade pages correctly.
2301-
*/
2302-
if (TransactionIdEquals(xmin,FrozenTransactionId)&&
2303-
TransactionIdIsValid(xmax))
2304-
return true;
2305-
2306-
return false;
2307-
}
23082265

23092266
/*
23102267
* UpdateXmaxHintBits - update tuple hint bits after xmax transaction ends
@@ -5762,7 +5719,8 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid,
57625719
* end of the chain, we're done, so return success.
57635720
*/
57645721
if (TransactionIdIsValid(priorXmax)&&
5765-
!HeapTupleUpdateXmaxMatchesXmin(priorXmax,mytup.t_data))
5722+
!TransactionIdEquals(HeapTupleHeaderGetXmin(mytup.t_data),
5723+
priorXmax))
57665724
{
57675725
result=HeapTupleMayBeUpdated;
57685726
gotoout_locked;
@@ -6456,23 +6414,14 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
64566414
Assert(TransactionIdIsValid(xid));
64576415

64586416
/*
6459-
* The updating transaction cannot possibly be still running, but
6460-
* verify whether it has committed, and request to set the
6461-
* COMMITTED flag if so. (We normally don't see any tuples in
6462-
* this state, because they are removed by page pruning before we
6463-
* try to freeze the page; but this can happen if the updating
6464-
* transaction commits after the page is pruned but before
6465-
* HeapTupleSatisfiesVacuum).
6417+
* If the xid is older than the cutoff, it has to have aborted,
6418+
* otherwise the tuple would have gotten pruned away.
64666419
*/
64676420
if (TransactionIdPrecedes(xid,cutoff_xid))
64686421
{
6469-
if (TransactionIdDidCommit(xid))
6470-
*flags=FRM_MARK_COMMITTED |FRM_RETURN_IS_XID;
6471-
else
6472-
{
6473-
*flags |=FRM_INVALIDATE_XMAX;
6474-
xid=InvalidTransactionId;/* not strictly necessary */
6475-
}
6422+
Assert(!TransactionIdDidCommit(xid));
6423+
*flags |=FRM_INVALIDATE_XMAX;
6424+
xid=InvalidTransactionId;/* not strictly necessary */
64766425
}
64776426
else
64786427
{
@@ -6545,16 +6494,13 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
65456494
/*
65466495
* It's an update; should we keep it? If the transaction is known
65476496
* aborted or crashed then it's okay to ignore it, otherwise not.
6497+
* Note that an updater older than cutoff_xid cannot possibly be
6498+
* committed, because HeapTupleSatisfiesVacuum would have returned
6499+
* HEAPTUPLE_DEAD and we would not be trying to freeze the tuple.
65486500
*
65496501
* As with all tuple visibility routines, it's critical to test
65506502
* TransactionIdIsInProgress before TransactionIdDidCommit,
65516503
* because of race conditions explained in detail in tqual.c.
6552-
*
6553-
* We normally don't see committed updating transactions earlier
6554-
* than the cutoff xid, because they are removed by page pruning
6555-
* before we try to freeze the page; but it can happen if the
6556-
* updating transaction commits after the page is pruned but
6557-
* before HeapTupleSatisfiesVacuum.
65586504
*/
65596505
if (TransactionIdIsCurrentTransactionId(xid)||
65606506
TransactionIdIsInProgress(xid))
@@ -6579,6 +6525,13 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
65796525
* we can ignore it.
65806526
*/
65816527

6528+
/*
6529+
* Since the tuple wasn't marked HEAPTUPLE_DEAD by vacuum, the
6530+
* update Xid cannot possibly be older than the xid cutoff.
6531+
*/
6532+
Assert(!TransactionIdIsValid(update_xid)||
6533+
!TransactionIdPrecedes(update_xid,cutoff_xid));
6534+
65826535
/*
65836536
* If we determined that it's an Xid corresponding to an update
65846537
* that must be retained, additionally add it to the list of
@@ -6657,10 +6610,7 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
66576610
*
66586611
* It is assumed that the caller has checked the tuple with
66596612
* HeapTupleSatisfiesVacuum() and determined that it is not HEAPTUPLE_DEAD
6660-
* (else we should be removing the tuple, not freezing it). However, note
6661-
* that we don't remove HOT tuples even if they are dead, and it'd be incorrect
6662-
* to freeze them (because that would make them visible), so we mark them as
6663-
* update-committed, and needing further freezing later on.
6613+
* (else we should be removing the tuple, not freezing it).
66646614
*
66656615
* NB: cutoff_xid *must* be <= the current global xmin, to ensure that any
66666616
* XID older than it could neither be running nor seen as running by any
@@ -6771,22 +6721,7 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, TransactionId cutoff_xid,
67716721
elseif (TransactionIdIsNormal(xid))
67726722
{
67736723
if (TransactionIdPrecedes(xid,cutoff_xid))
6774-
{
6775-
/*
6776-
* Must freeze regular XIDs older than the cutoff. We must not
6777-
* freeze a HOT-updated tuple, though; doing so would bring it
6778-
* back to life.
6779-
*/
6780-
if (HeapTupleHeaderIsHotUpdated(tuple))
6781-
{
6782-
frz->t_infomask |=HEAP_XMAX_COMMITTED;
6783-
totally_frozen= false;
6784-
changed= true;
6785-
/* must not freeze */
6786-
}
6787-
else
6788-
freeze_xmax= true;
6789-
}
6724+
freeze_xmax= true;
67906725
else
67916726
totally_frozen= false;
67926727
}

‎src/backend/access/heap/pruneheap.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ heap_prune_chain(Relation relation, Buffer buffer, OffsetNumber rootoffnum,
474474
* Check the tuple XMIN against prior XMAX, if any
475475
*/
476476
if (TransactionIdIsValid(priorXmax)&&
477-
!HeapTupleUpdateXmaxMatchesXmin(priorXmax,htup))
477+
!TransactionIdEquals(HeapTupleHeaderGetXmin(htup),priorXmax))
478478
break;
479479

480480
/*
@@ -814,7 +814,7 @@ heap_get_root_tuples(Page page, OffsetNumber *root_offsets)
814814
htup= (HeapTupleHeader)PageGetItem(page,lp);
815815

816816
if (TransactionIdIsValid(priorXmax)&&
817-
!HeapTupleUpdateXmaxMatchesXmin(priorXmax,htup))
817+
!TransactionIdEquals(priorXmax,HeapTupleHeaderGetXmin(htup)))
818818
break;
819819

820820
/* Remember the root line pointer for this item */

‎src/backend/commands/vacuumlazy.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,17 +1984,17 @@ lazy_record_dead_tuple(LVRelStats *vacrelstats,
19841984
ItemPointeritemptr)
19851985
{
19861986
/*
1987-
* The arraymust neveroverflow, since we rely on all deletable tuples
1988-
*being removed; inability to remove atuple might cause an old XID to
1989-
*persist beyondthefreeze limit, which could be disastrous later on.
1987+
* The arrayshouldn'toverflow under normal behavior, but perhaps it
1988+
*could if we are given areally small maintenance_work_mem. In that
1989+
*case, just forgetthelast few tuples (we'll get 'em next time).
19901990
*/
1991-
if (vacrelstats->num_dead_tuples>=vacrelstats->max_dead_tuples)
1992-
elog(ERROR,"dead tuple array overflow");
1993-
1994-
vacrelstats->dead_tuples[vacrelstats->num_dead_tuples]=*itemptr;
1995-
vacrelstats->num_dead_tuples++;
1996-
pgstat_progress_update_param(PROGRESS_VACUUM_NUM_DEAD_TUPLES,
1997-
vacrelstats->num_dead_tuples);
1991+
if (vacrelstats->num_dead_tuples<vacrelstats->max_dead_tuples)
1992+
{
1993+
vacrelstats->dead_tuples[vacrelstats->num_dead_tuples]=*itemptr;
1994+
vacrelstats->num_dead_tuples++;
1995+
pgstat_progress_update_param(PROGRESS_VACUUM_NUM_DEAD_TUPLES,
1996+
vacrelstats->num_dead_tuples);
1997+
}
19981998
}
19991999

20002000
/*

‎src/backend/executor/execMain.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2275,7 +2275,8 @@ EvalPlanQualFetch(EState *estate, Relation relation, int lockmode,
22752275
* atomic, and Xmin never changes in an existing tuple, except to
22762276
* invalid or frozen, and neither of those can match priorXmax.)
22772277
*/
2278-
if (!HeapTupleUpdateXmaxMatchesXmin(priorXmax,tuple.t_data))
2278+
if (!TransactionIdEquals(HeapTupleHeaderGetXmin(tuple.t_data),
2279+
priorXmax))
22792280
{
22802281
ReleaseBuffer(buffer);
22812282
returnNULL;
@@ -2422,7 +2423,8 @@ EvalPlanQualFetch(EState *estate, Relation relation, int lockmode,
24222423
/*
24232424
* As above, if xmin isn't what we're expecting, do nothing.
24242425
*/
2425-
if (!HeapTupleUpdateXmaxMatchesXmin(priorXmax,tuple.t_data))
2426+
if (!TransactionIdEquals(HeapTupleHeaderGetXmin(tuple.t_data),
2427+
priorXmax))
24262428
{
24272429
ReleaseBuffer(buffer);
24282430
returnNULL;

‎src/include/access/heapam.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,6 @@ extern void heap_get_latest_tid(Relation relation, Snapshot snapshot,
145145
ItemPointertid);
146146
externvoidsetLastTid(constItemPointertid);
147147

148-
externboolHeapTupleUpdateXmaxMatchesXmin(TransactionIdxmax,
149-
HeapTupleHeaderhtup);
150-
151148
externBulkInsertStateGetBulkInsertState(void);
152149
externvoidFreeBulkInsertState(BulkInsertState);
153150

‎src/test/isolation/isolation_schedule

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ test: update-locked-tuple
4141
test: propagate-lock-delete
4242
test: tuplelock-conflict
4343
test: tuplelock-update
44-
test: freeze-the-dead
4544
test: nowait
4645
test: nowait-2
4746
test: nowait-3

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp