aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2018-04-18 12:07:37 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2018-04-18 12:07:37 -0400
commit1dec82068b3b59b621e6b04040c150241f5060f3 (patch)
tree7da7321200b2b8baaaf0025d1cc9350da42a7837 /src
parentfe7fc52645678ecb661fde47fe5937b48093f79e (diff)
downloadpostgresql-1dec82068b3b59b621e6b04040c150241f5060f3.tar.gz
postgresql-1dec82068b3b59b621e6b04040c150241f5060f3.zip
Better fix for deadlock hazard in CREATE INDEX CONCURRENTLY.
Commit 54eff5311 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
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/indexcmds.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f2dcc1c51fb..dda0dcb8aa8 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -1197,14 +1197,25 @@ DefineIndex(Oid relationId,
* doing CREATE INDEX CONCURRENTLY, which would see our snapshot as one
* they must wait for. But first, save the snapshot's xmin to use as
* limitXmin for GetCurrentVirtualXIDs().
- *
- * Our catalog snapshot could have the same effect, so drop that one too.
*/
limitXmin = snapshot->xmin;
PopActiveSnapshot();
UnregisterSnapshot(snapshot);
- InvalidateCatalogSnapshot();
+
+ /*
+ * The snapshot subsystem could still contain registered snapshots that
+ * are holding back our process's advertised xmin; in particular, if
+ * default_transaction_isolation = serializable, there is a transaction
+ * snapshot that is still active. The CatalogSnapshot is likewise a
+ * hazard. To ensure no deadlocks, we must commit and start yet another
+ * transaction, and do our wait before any snapshot has been taken in it.
+ */
+ CommitTransactionCommand();
+ StartTransactionCommand();
+
+ /* We should now definitely not be advertising any xmin. */
+ Assert(MyPgXact->xmin == InvalidTransactionId);
/*
* The index is now valid in the sense that it contains all currently