aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/indexcmds.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-08-27 19:14:34 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-08-27 19:14:34 +0000
commite06fda0a8b6fa50ebd6183bfce4e8394dd8d7124 (patch)
treee1b270da82cc9fc60229195a53f5e93302c6d8a2 /src/backend/commands/indexcmds.c
parentca1fd0ea5b10e133a3ed00594fa908d5b647fa3d (diff)
downloadpostgresql-e06fda0a8b6fa50ebd6183bfce4e8394dd8d7124.tar.gz
postgresql-e06fda0a8b6fa50ebd6183bfce4e8394dd8d7124.zip
Add a function GetLockConflicts() to lock.c to report xacts holding
locks that would conflict with a specified lock request, without actually trying to get that lock. Use this instead of the former ad hoc method of doing the first wait step in CREATE INDEX CONCURRENTLY. Fixes problem with undetected deadlock and in many cases will allow the index creation to proceed sooner than it otherwise could've. Per discussion with Greg Stark.
Diffstat (limited to 'src/backend/commands/indexcmds.c')
-rw-r--r--src/backend/commands/indexcmds.c42
1 files changed, 19 insertions, 23 deletions
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index e96235c6f53..81246768bc9 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.147 2006/08/25 04:06:48 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.148 2006/08/27 19:14:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -119,8 +119,11 @@ DefineIndex(RangeVar *heapRelation,
Datum reloptions;
IndexInfo *indexInfo;
int numberOfAttributes;
+ List *old_xact_list;
+ ListCell *lc;
uint32 ixcnt;
LockRelId heaprelid;
+ LOCKTAG heaplocktag;
Snapshot snapshot;
Relation pg_index;
HeapTuple indexTuple;
@@ -466,33 +469,26 @@ DefineIndex(RangeVar *heapRelation,
CommitTransactionCommand();
StartTransactionCommand();
- /* Establish transaction snapshot ... else GetLatestSnapshot complains */
- (void) GetTransactionSnapshot();
-
/*
* Now we must wait until no running transaction could have the table open
- * with the old list of indexes. If we can take an exclusive lock then
- * there are none now and anybody who opens it later will get the new
- * index in their relcache entry. Alternatively, if our Xmin reaches our
- * own (new) transaction then we know no transactions that started before
- * the index was visible are left anyway.
+ * with the old list of indexes. To do this, inquire which xacts currently
+ * would conflict with ShareLock on the table -- ie, which ones have
+ * a lock that permits writing the table. Then wait for each of these
+ * xacts to commit or abort. Note we do not need to worry about xacts
+ * that open the table for writing after this point; they will see the
+ * new index when they open it.
+ *
+ * Note: GetLockConflicts() never reports our own xid,
+ * hence we need not check for that.
*/
- for (;;)
- {
- CHECK_FOR_INTERRUPTS();
+ SET_LOCKTAG_RELATION(heaplocktag, heaprelid.dbId, heaprelid.relId);
+ old_xact_list = GetLockConflicts(&heaplocktag, ShareLock);
- if (ConditionalLockRelationOid(relationId, ExclusiveLock))
- {
- /* Release the lock right away to avoid blocking anyone */
- UnlockRelationOid(relationId, ExclusiveLock);
- break;
- }
-
- if (TransactionIdEquals(GetLatestSnapshot()->xmin,
- GetTopTransactionId()))
- break;
+ foreach(lc, old_xact_list)
+ {
+ TransactionId xid = lfirst_xid(lc);
- pg_usleep(1000000L); /* 1 sec */
+ XactLockTableWait(xid);
}
/*