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

Commit7a95966

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 parent769756f commit7a95966

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
@@ -2060,7 +2060,8 @@ heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer,
20602060
* broken.
20612061
*/
20622062
if (TransactionIdIsValid(prev_xmax)&&
2063-
!HeapTupleUpdateXmaxMatchesXmin(prev_xmax,heapTuple->t_data))
2063+
!TransactionIdEquals(prev_xmax,
2064+
HeapTupleHeaderGetXmin(heapTuple->t_data)))
20642065
break;
20652066

20662067
/*
@@ -2243,7 +2244,7 @@ heap_get_latest_tid(Relation relation,
22432244
* tuple. Check for XMIN match.
22442245
*/
22452246
if (TransactionIdIsValid(priorXmax)&&
2246-
!HeapTupleUpdateXmaxMatchesXmin(priorXmax,tp.t_data))
2247+
!TransactionIdEquals(priorXmax,HeapTupleHeaderGetXmin(tp.t_data)))
22472248
{
22482249
UnlockReleaseBuffer(buffer);
22492250
break;
@@ -2275,50 +2276,6 @@ heap_get_latest_tid(Relation relation,
22752276
}/* end of loop */
22762277
}
22772278

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

23232280
/*
23242281
* UpdateXmaxHintBits - update tuple hint bits after xmax transaction ends
@@ -5736,7 +5693,8 @@ heap_lock_updated_tuple_rec(Relation rel, ItemPointer tid, TransactionId xid,
57365693
* end of the chain, we're done, so return success.
57375694
*/
57385695
if (TransactionIdIsValid(priorXmax)&&
5739-
!HeapTupleUpdateXmaxMatchesXmin(priorXmax,mytup.t_data))
5696+
!TransactionIdEquals(HeapTupleHeaderGetXmin(mytup.t_data),
5697+
priorXmax))
57405698
{
57415699
result=HeapTupleMayBeUpdated;
57425700
gotoout_locked;
@@ -6430,23 +6388,14 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
64306388
Assert(TransactionIdIsValid(xid));
64316389

64326390
/*
6433-
* The updating transaction cannot possibly be still running, but
6434-
* verify whether it has committed, and request to set the
6435-
* COMMITTED flag if so. (We normally don't see any tuples in
6436-
* this state, because they are removed by page pruning before we
6437-
* try to freeze the page; but this can happen if the updating
6438-
* transaction commits after the page is pruned but before
6439-
* HeapTupleSatisfiesVacuum).
6391+
* If the xid is older than the cutoff, it has to have aborted,
6392+
* otherwise the tuple would have gotten pruned away.
64406393
*/
64416394
if (TransactionIdPrecedes(xid,cutoff_xid))
64426395
{
6443-
if (TransactionIdDidCommit(xid))
6444-
*flags=FRM_MARK_COMMITTED |FRM_RETURN_IS_XID;
6445-
else
6446-
{
6447-
*flags |=FRM_INVALIDATE_XMAX;
6448-
xid=InvalidTransactionId;/* not strictly necessary */
6449-
}
6396+
Assert(!TransactionIdDidCommit(xid));
6397+
*flags |=FRM_INVALIDATE_XMAX;
6398+
xid=InvalidTransactionId;/* not strictly necessary */
64506399
}
64516400
else
64526401
{
@@ -6519,16 +6468,13 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
65196468
/*
65206469
* It's an update; should we keep it? If the transaction is known
65216470
* aborted or crashed then it's okay to ignore it, otherwise not.
6471+
* Note that an updater older than cutoff_xid cannot possibly be
6472+
* committed, because HeapTupleSatisfiesVacuum would have returned
6473+
* HEAPTUPLE_DEAD and we would not be trying to freeze the tuple.
65226474
*
65236475
* As with all tuple visibility routines, it's critical to test
65246476
* TransactionIdIsInProgress before TransactionIdDidCommit,
65256477
* because of race conditions explained in detail in tqual.c.
6526-
*
6527-
* We normally don't see committed updating transactions earlier
6528-
* than the cutoff xid, because they are removed by page pruning
6529-
* before we try to freeze the page; but it can happen if the
6530-
* updating transaction commits after the page is pruned but
6531-
* before HeapTupleSatisfiesVacuum.
65326478
*/
65336479
if (TransactionIdIsCurrentTransactionId(xid)||
65346480
TransactionIdIsInProgress(xid))
@@ -6553,6 +6499,13 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
65536499
* we can ignore it.
65546500
*/
65556501

6502+
/*
6503+
* Since the tuple wasn't marked HEAPTUPLE_DEAD by vacuum, the
6504+
* update Xid cannot possibly be older than the xid cutoff.
6505+
*/
6506+
Assert(!TransactionIdIsValid(update_xid)||
6507+
!TransactionIdPrecedes(update_xid,cutoff_xid));
6508+
65566509
/*
65576510
* If we determined that it's an Xid corresponding to an update
65586511
* that must be retained, additionally add it to the list of
@@ -6631,10 +6584,7 @@ FreezeMultiXactId(MultiXactId multi, uint16 t_infomask,
66316584
*
66326585
* It is assumed that the caller has checked the tuple with
66336586
* HeapTupleSatisfiesVacuum() and determined that it is not HEAPTUPLE_DEAD
6634-
* (else we should be removing the tuple, not freezing it). However, note
6635-
* that we don't remove HOT tuples even if they are dead, and it'd be incorrect
6636-
* to freeze them (because that would make them visible), so we mark them as
6637-
* update-committed, and needing further freezing later on.
6587+
* (else we should be removing the tuple, not freezing it).
66386588
*
66396589
* NB: cutoff_xid *must* be <= the current global xmin, to ensure that any
66406590
* XID older than it could neither be running nor seen as running by any
@@ -6745,22 +6695,7 @@ heap_prepare_freeze_tuple(HeapTupleHeader tuple, TransactionId cutoff_xid,
67456695
elseif (TransactionIdIsNormal(xid))
67466696
{
67476697
if (TransactionIdPrecedes(xid,cutoff_xid))
6748-
{
6749-
/*
6750-
* Must freeze regular XIDs older than the cutoff. We must not
6751-
* freeze a HOT-updated tuple, though; doing so would bring it
6752-
* back to life.
6753-
*/
6754-
if (HeapTupleHeaderIsHotUpdated(tuple))
6755-
{
6756-
frz->t_infomask |=HEAP_XMAX_COMMITTED;
6757-
totally_frozen= false;
6758-
changed= true;
6759-
/* must not freeze */
6760-
}
6761-
else
6762-
freeze_xmax= true;
6763-
}
6698+
freeze_xmax= true;
67646699
else
67656700
totally_frozen= false;
67666701
}

‎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
@@ -2018,17 +2018,17 @@ lazy_record_dead_tuple(LVRelStats *vacrelstats,
20182018
ItemPointeritemptr)
20192019
{
20202020
/*
2021-
* The arraymust neveroverflow, since we rely on all deletable tuples
2022-
*being removed; inability to remove atuple might cause an old XID to
2023-
*persist beyondthefreeze limit, which could be disastrous later on.
2021+
* The arrayshouldn'toverflow under normal behavior, but perhaps it
2022+
*could if we are given areally small maintenance_work_mem. In that
2023+
*case, just forgetthelast few tuples (we'll get 'em next time).
20242024
*/
2025-
if (vacrelstats->num_dead_tuples>=vacrelstats->max_dead_tuples)
2026-
elog(ERROR,"dead tuple array overflow");
2027-
2028-
vacrelstats->dead_tuples[vacrelstats->num_dead_tuples]=*itemptr;
2029-
vacrelstats->num_dead_tuples++;
2030-
pgstat_progress_update_param(PROGRESS_VACUUM_NUM_DEAD_TUPLES,
2031-
vacrelstats->num_dead_tuples);
2025+
if (vacrelstats->num_dead_tuples<vacrelstats->max_dead_tuples)
2026+
{
2027+
vacrelstats->dead_tuples[vacrelstats->num_dead_tuples]=*itemptr;
2028+
vacrelstats->num_dead_tuples++;
2029+
pgstat_progress_update_param(PROGRESS_VACUUM_NUM_DEAD_TUPLES,
2030+
vacrelstats->num_dead_tuples);
2031+
}
20322032
}
20332033

20342034
/*

‎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