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

Commitc6764eb

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 parentd8c435e commitc6764eb

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
@@ -2074,7 +2074,8 @@ heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer,
20742074
* broken.
20752075
*/
20762076
if (TransactionIdIsValid(prev_xmax)&&
2077-
!HeapTupleUpdateXmaxMatchesXmin(prev_xmax,heapTuple->t_data))
2077+
!TransactionIdEquals(prev_xmax,
2078+
HeapTupleHeaderGetXmin(heapTuple->t_data)))
20782079
break;
20792080

20802081
/*
@@ -2260,7 +2261,7 @@ heap_get_latest_tid(Relation relation,
22602261
* tuple. Check for XMIN match.
22612262
*/
22622263
if (TransactionIdIsValid(priorXmax)&&
2263-
!HeapTupleUpdateXmaxMatchesXmin(priorXmax,tp.t_data))
2264+
!TransactionIdEquals(priorXmax,HeapTupleHeaderGetXmin(tp.t_data)))
22642265
{
22652266
UnlockReleaseBuffer(buffer);
22662267
break;
@@ -2292,50 +2293,6 @@ heap_get_latest_tid(Relation relation,
22922293
}/* end of loop */
22932294
}
22942295

2295-
/*
2296-
* HeapTupleUpdateXmaxMatchesXmin - verify update chain xmax/xmin lineage
2297-
*
2298-
* Given the new version of a tuple after some update, verify whether the
2299-
* given Xmax (corresponding to the previous version) matches the tuple's
2300-
* Xmin, taking into account that the Xmin might have been frozen after the
2301-
* update.
2302-
*/
2303-
bool
2304-
HeapTupleUpdateXmaxMatchesXmin(TransactionIdxmax,HeapTupleHeaderhtup)
2305-
{
2306-
TransactionIdxmin=HeapTupleHeaderGetXmin(htup);
2307-
2308-
/*
2309-
* If the xmax of the old tuple is identical to the xmin of the new one,
2310-
* it's a match.
2311-
*/
2312-
if (TransactionIdEquals(xmax,xmin))
2313-
return true;
2314-
2315-
/*
2316-
* If the Xmin that was in effect prior to a freeze matches the Xmax,
2317-
* it's good too.
2318-
*/
2319-
if (HeapTupleHeaderXminFrozen(htup)&&
2320-
TransactionIdEquals(HeapTupleHeaderGetRawXmin(htup),xmax))
2321-
return true;
2322-
2323-
/*
2324-
* When a tuple is frozen, the original Xmin is lost, but we know it's a
2325-
* committed transaction. So unless the Xmax is InvalidXid, we don't know
2326-
* for certain that there is a match, but there may be one; and we must
2327-
* return true so that a HOT chain that is half-frozen can be walked
2328-
* correctly.
2329-
*
2330-
* We no longer freeze tuples this way, but we must keep this in order to
2331-
* interpret pre-pg_upgrade pages correctly.
2332-
*/
2333-
if (TransactionIdEquals(xmin,FrozenTransactionId)&&
2334-
TransactionIdIsValid(xmax))
2335-
return true;
2336-
2337-
return false;
2338-
}
23392296

23402297
/*
23412298
* UpdateXmaxHintBits - update tuple hint bits after xmax transaction ends
@@ -5755,7 +5712,8 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid,
57555712
* end of the chain, we're done, so return success.
57565713
*/
57575714
if (TransactionIdIsValid(priorXmax)&&
5758-
!HeapTupleUpdateXmaxMatchesXmin(priorXmax,mytup.t_data))
5715+
!TransactionIdEquals(HeapTupleHeaderGetXmin(mytup.t_data),
5716+
priorXmax))
57595717
{
57605718
result=HeapTupleMayBeUpdated;
57615719
gotoout_locked;
@@ -6449,23 +6407,14 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
64496407
Assert(TransactionIdIsValid(xid));
64506408

64516409
/*
6452-
* The updating transaction cannot possibly be still running, but
6453-
* verify whether it has committed, and request to set the
6454-
* COMMITTED flag if so. (We normally don't see any tuples in
6455-
* this state, because they are removed by page pruning before we
6456-
* try to freeze the page; but this can happen if the updating
6457-
* transaction commits after the page is pruned but before
6458-
* HeapTupleSatisfiesVacuum).
6410+
* If the xid is older than the cutoff, it has to have aborted,
6411+
* otherwise the tuple would have gotten pruned away.
64596412
*/
64606413
if (TransactionIdPrecedes(xid,cutoff_xid))
64616414
{
6462-
if (TransactionIdDidCommit(xid))
6463-
*flags=FRM_MARK_COMMITTED |FRM_RETURN_IS_XID;
6464-
else
6465-
{
6466-
*flags |=FRM_INVALIDATE_XMAX;
6467-
xid=InvalidTransactionId;/* not strictly necessary */
6468-
}
6415+
Assert(!TransactionIdDidCommit(xid));
6416+
*flags |=FRM_INVALIDATE_XMAX;
6417+
xid=InvalidTransactionId;/* not strictly necessary */
64696418
}
64706419
else
64716420
{
@@ -6538,16 +6487,13 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
65386487
/*
65396488
* It's an update; should we keep it? If the transaction is known
65406489
* aborted or crashed then it's okay to ignore it, otherwise not.
6490+
* Note that an updater older than cutoff_xid cannot possibly be
6491+
* committed, because HeapTupleSatisfiesVacuum would have returned
6492+
* HEAPTUPLE_DEAD and we would not be trying to freeze the tuple.
65416493
*
65426494
* As with all tuple visibility routines, it's critical to test
65436495
* TransactionIdIsInProgress before TransactionIdDidCommit,
65446496
* because of race conditions explained in detail in tqual.c.
6545-
*
6546-
* We normally don't see committed updating transactions earlier
6547-
* than the cutoff xid, because they are removed by page pruning
6548-
* before we try to freeze the page; but it can happen if the
6549-
* updating transaction commits after the page is pruned but
6550-
* before HeapTupleSatisfiesVacuum.
65516497
*/
65526498
if (TransactionIdIsCurrentTransactionId(xid)||
65536499
TransactionIdIsInProgress(xid))
@@ -6572,6 +6518,13 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
65726518
* we can ignore it.
65736519
*/
65746520

6521+
/*
6522+
* Since the tuple wasn't marked HEAPTUPLE_DEAD by vacuum, the
6523+
* update Xid cannot possibly be older than the xid cutoff.
6524+
*/
6525+
Assert(!TransactionIdIsValid(update_xid)||
6526+
!TransactionIdPrecedes(update_xid,cutoff_xid));
6527+
65756528
/*
65766529
* If we determined that it's an Xid corresponding to an update
65776530
* that must be retained, additionally add it to the list of
@@ -6650,10 +6603,7 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
66506603
*
66516604
* It is assumed that the caller has checked the tuple with
66526605
* HeapTupleSatisfiesVacuum() and determined that it is not HEAPTUPLE_DEAD
6653-
* (else we should be removing the tuple, not freezing it). However, note
6654-
* that we don't remove HOT tuples even if they are dead, and it'd be incorrect
6655-
* to freeze them (because that would make them visible), so we mark them as
6656-
* update-committed, and needing further freezing later on.
6606+
* (else we should be removing the tuple, not freezing it).
66576607
*
66586608
* NB: cutoff_xid *must* be <= the current global xmin, to ensure that any
66596609
* XID older than it could neither be running nor seen as running by any
@@ -6764,22 +6714,7 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, TransactionId cutoff_xid,
67646714
elseif (TransactionIdIsNormal(xid))
67656715
{
67666716
if (TransactionIdPrecedes(xid,cutoff_xid))
6767-
{
6768-
/*
6769-
* Must freeze regular XIDs older than the cutoff. We must not
6770-
* freeze a HOT-updated tuple, though; doing so would bring it
6771-
* back to life.
6772-
*/
6773-
if (HeapTupleHeaderIsHotUpdated(tuple))
6774-
{
6775-
frz->t_infomask |=HEAP_XMAX_COMMITTED;
6776-
totally_frozen= false;
6777-
changed= true;
6778-
/* must not freeze */
6779-
}
6780-
else
6781-
freeze_xmax= true;
6782-
}
6717+
freeze_xmax= true;
67836718
else
67846719
totally_frozen= false;
67856720
}

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

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

479479
/*
@@ -813,7 +813,7 @@ heap_get_root_tuples(Page page, OffsetNumber *root_offsets)
813813
htup= (HeapTupleHeader)PageGetItem(page,lp);
814814

815815
if (TransactionIdIsValid(priorXmax)&&
816-
!HeapTupleUpdateXmaxMatchesXmin(priorXmax,htup))
816+
!TransactionIdEquals(priorXmax,HeapTupleHeaderGetXmin(htup)))
817817
break;
818818

819819
/* 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
@@ -2029,17 +2029,17 @@ lazy_record_dead_tuple(LVRelStats *vacrelstats,
20292029
ItemPointeritemptr)
20302030
{
20312031
/*
2032-
* The arraymust neveroverflow, since we rely on all deletable tuples
2033-
*being removed; inability to remove atuple might cause an old XID to
2034-
*persist beyondthefreeze limit, which could be disastrous later on.
2032+
* The arrayshouldn'toverflow under normal behavior, but perhaps it
2033+
*could if we are given areally small maintenance_work_mem. In that
2034+
*case, just forgetthelast few tuples (we'll get 'em next time).
20352035
*/
2036-
if (vacrelstats->num_dead_tuples>=vacrelstats->max_dead_tuples)
2037-
elog(ERROR,"dead tuple array overflow");
2038-
2039-
vacrelstats->dead_tuples[vacrelstats->num_dead_tuples]=*itemptr;
2040-
vacrelstats->num_dead_tuples++;
2041-
pgstat_progress_update_param(PROGRESS_VACUUM_NUM_DEAD_TUPLES,
2042-
vacrelstats->num_dead_tuples);
2036+
if (vacrelstats->num_dead_tuples<vacrelstats->max_dead_tuples)
2037+
{
2038+
vacrelstats->dead_tuples[vacrelstats->num_dead_tuples]=*itemptr;
2039+
vacrelstats->num_dead_tuples++;
2040+
pgstat_progress_update_param(PROGRESS_VACUUM_NUM_DEAD_TUPLES,
2041+
vacrelstats->num_dead_tuples);
2042+
}
20432043
}
20442044

20452045
/*

‎src/backend/executor/execMain.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2595,7 +2595,8 @@ EvalPlanQualFetch(EState *estate, Relation relation, int lockmode,
25952595
* atomic, and Xmin never changes in an existing tuple, except to
25962596
* invalid or frozen, and neither of those can match priorXmax.)
25972597
*/
2598-
if (!HeapTupleUpdateXmaxMatchesXmin(priorXmax,tuple.t_data))
2598+
if (!TransactionIdEquals(HeapTupleHeaderGetXmin(tuple.t_data),
2599+
priorXmax))
25992600
{
26002601
ReleaseBuffer(buffer);
26012602
returnNULL;
@@ -2742,7 +2743,8 @@ EvalPlanQualFetch(EState *estate, Relation relation, int lockmode,
27422743
/*
27432744
* As above, if xmin isn't what we're expecting, do nothing.
27442745
*/
2745-
if (!HeapTupleUpdateXmaxMatchesXmin(priorXmax,tuple.t_data))
2746+
if (!TransactionIdEquals(HeapTupleHeaderGetXmin(tuple.t_data),
2747+
priorXmax))
27462748
{
27472749
ReleaseBuffer(buffer);
27482750
returnNULL;

‎src/include/access/heapam.h

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

149-
externboolHeapTupleUpdateXmaxMatchesXmin(TransactionIdxmax,
150-
HeapTupleHeaderhtup);
151-
152149
externBulkInsertStateGetBulkInsertState(void);
153150
externvoidFreeBulkInsertState(BulkInsertState);
154151
externvoidReleaseBulkInsertStatePin(BulkInsertStatebistate);

‎src/test/isolation/isolation_schedule

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ test: update-locked-tuple
4444
test: propagate-lock-delete
4545
test: tuplelock-conflict
4646
test: tuplelock-update
47-
test: freeze-the-dead
4847
test: nowait
4948
test: nowait-2
5049
test: nowait-3

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp