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

Commit621a99a

Browse files
committed
Fix longstanding bug in HeapTupleSatisfiesVacuum().
HeapTupleSatisfiesVacuum() didn't properly discern betweenDELETE_IN_PROGRESS and INSERT_IN_PROGRESS for rows that have beeninserted in the current transaction and deleted in a abortedsubtransaction of the current backend. At the very least that causedproblems for CLUSTER and CREATE INDEX in transactions that hadaborting subtransactions producing rows, leading to warnings like:WARNING: concurrent delete in progress within table "..."possibly in an endless, uninterruptible, loop.Instead of treating *InProgress xmins the same as *IsCurrent ones,treat them as being distinct like the other visibility routines. Asimplemented this separatation can cause a behaviour change for rowsthat have been inserted and deleted in another, still running,transaction. HTSV will now return INSERT_IN_PROGRESS instead ofDELETE_IN_PROGRESS for those. That's both, more in line with the othervisibility routines and arguably more correct. The latter because aINSERT_IN_PROGRESS will make callers look at/wait for xmin, instead ofxmax.The only current caller where that's possibly worse than the oldbehaviour is heap_prune_chain() which now won't mark the page asprunable if a row has concurrently been inserted and deleted. That'sharmless enough.As a cautionary measure also insert a interrupt check before the gotosin IndexBuildHeapScan() that lead to the uninterruptible loop. Thereare other possible causes, like a row that several sessions try toupdate and all fail, for repeated loops and the cost of doing so inthe retry case is low.As this bug goes back all the way to the introduction ofsubtransactions in573a71a backpatch to all supported releases.Reported-By: Sandro Santilli
1 parentc8c9c1f commit621a99a

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

‎src/backend/catalog/index.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2298,6 +2298,7 @@ IndexBuildHeapScan(Relation heapRelation,
22982298
XactLockTableWait(xwait,heapRelation,
22992299
&heapTuple->t_data->t_ctid,
23002300
XLTW_InsertIndexUnique);
2301+
CHECK_FOR_INTERRUPTS();
23012302
gotorecheck;
23022303
}
23032304
}
@@ -2346,6 +2347,7 @@ IndexBuildHeapScan(Relation heapRelation,
23462347
XactLockTableWait(xwait,heapRelation,
23472348
&heapTuple->t_data->t_ctid,
23482349
XLTW_InsertIndexUnique);
2350+
CHECK_FOR_INTERRUPTS();
23492351
gotorecheck;
23502352
}
23512353

‎src/backend/utils/time/tqual.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,7 +1166,7 @@ HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin,
11661166
returnHEAPTUPLE_DEAD;
11671167
}
11681168
}
1169-
elseif (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple)))
1169+
elseif (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmin(tuple)))
11701170
{
11711171
if (tuple->t_infomask&HEAP_XMAX_INVALID)/* xid invalid */
11721172
returnHEAPTUPLE_INSERT_IN_PROGRESS;
@@ -1175,7 +1175,22 @@ HeapTupleSatisfiesVacuum(HeapTuple htup, TransactionId OldestXmin,
11751175
HeapTupleHeaderIsOnlyLocked(tuple))
11761176
returnHEAPTUPLE_INSERT_IN_PROGRESS;
11771177
/* inserted and then deleted by same xact */
1178-
returnHEAPTUPLE_DELETE_IN_PROGRESS;
1178+
if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetUpdateXid(tuple)))
1179+
returnHEAPTUPLE_DELETE_IN_PROGRESS;
1180+
/* deleting subtransaction must have aborted */
1181+
returnHEAPTUPLE_INSERT_IN_PROGRESS;
1182+
}
1183+
elseif (TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple)))
1184+
{
1185+
/*
1186+
* It'd be possible to discern between INSERT/DELETE in progress
1187+
* here by looking at xmax - but that doesn't seem beneficial for
1188+
* the majority of callers and even detrimental for some. We'd
1189+
* rather have callers look at/wait for xmin than xmax. It's
1190+
* always correct to return INSERT_IN_PROGRESS because that's
1191+
* what's happening from the view of other backends.
1192+
*/
1193+
returnHEAPTUPLE_INSERT_IN_PROGRESS;
11791194
}
11801195
elseif (TransactionIdDidCommit(HeapTupleHeaderGetRawXmin(tuple)))
11811196
SetHintBits(tuple,buffer,HEAP_XMIN_COMMITTED,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp