Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 69e3a54

Browse files
committed
Better fix for deadlock hazard in CREATE INDEX CONCURRENTLY.
Commit 54eff53 did not account for the possibility that we'd have a transaction snapshot due to default_transaction_isolation being set high enough to require one. The transaction snapshot is enough to hold back our advertised xmin and thus risk deadlock anyway. The only way to get rid of that snap is to start a new transaction, so let's do that instead. Also throw in an assert checking that we really have gotten to a state where no xmin is being advertised. Back-patch to 9.4, like the previous commit. Discussion: https://postgr.es/m/CAMkU=1ztk3TpQdcUNbxq93pc80FrXUjpDWLGMeVBDx71GHNwZQ@mail.gmail.com
1 parent d90b290 commit 69e3a54

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

src/backend/commands/indexcmds.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -824,14 +824,25 @@ DefineIndex(Oid relationId,
824824
* doing CREATE INDEX CONCURRENTLY, which would see our snapshot as one
825825
* they must wait for. But first, save the snapshot's xmin to use as
826826
* limitXmin for GetCurrentVirtualXIDs().
827-
*
828-
* Our catalog snapshot could have the same effect, so drop that one too.
829827
*/
830828
limitXmin = snapshot->xmin;
831829

832830
PopActiveSnapshot();
833831
UnregisterSnapshot(snapshot);
834-
InvalidateCatalogSnapshot();
832+
833+
/*
834+
* The snapshot subsystem could still contain registered snapshots that
835+
* are holding back our process's advertised xmin; in particular, if
836+
* default_transaction_isolation = serializable, there is a transaction
837+
* snapshot that is still active. The CatalogSnapshot is likewise a
838+
* hazard. To ensure no deadlocks, we must commit and start yet another
839+
* transaction, and do our wait before any snapshot has been taken in it.
840+
*/
841+
CommitTransactionCommand();
842+
StartTransactionCommand();
843+
844+
/* We should now definitely not be advertising any xmin. */
845+
Assert(MyPgXact->xmin == InvalidTransactionId);
835846

836847
/*
837848
* The index is now valid in the sense that it contains all currently

0 commit comments

Comments
 (0)