OSDN Git Service

Allow CREATE INDEX CONCURRENTLY to disregard transactions in other
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 7 Sep 2007 00:58:57 +0000 (00:58 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 7 Sep 2007 00:58:57 +0000 (00:58 +0000)
databases, per gripe from hubert depesz lubaczewski.  Patch from
Simon Riggs.

doc/src/sgml/ref/create_index.sgml
src/backend/commands/indexcmds.c
src/backend/storage/ipc/procarray.c
src/include/storage/procarray.h

index ed2b8e2..0fe40c7 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.63 2007/06/03 17:05:53 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.64 2007/09/07 00:58:56 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -308,7 +308,7 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] <replaceable class="parameter">name</re
     table. Other transactions can still read the table, but if they try to
     insert, update, or delete rows in the table they will block until the
     index build is finished. This could have a severe effect if the system is
-    a live production database. Large tables can take many hours to be
+    a live production database.  Very large tables can take many hours to be
     indexed, and even for smaller tables, an index build can lock out writers
     for periods that are unacceptably long for a production system.
    </para>
@@ -319,7 +319,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] <replaceable class="parameter">name</re
     <literal>CONCURRENTLY</> option of <command>CREATE INDEX</>.
     When this option is used,
     <productname>PostgreSQL</> must perform two scans of the table, and in
-    addition it must wait for all existing transactions to terminate.  Thus
+    addition it must wait for all existing transactions that could potentially
+    use the index to terminate.  Thus
     this method requires more total work than a standard index build and takes
     significantly longer to complete.  However, since it allows normal
     operations to continue while the index is built, this method is useful for
index ac56b58..5c418f8 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.163 2007/09/05 18:10:47 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.164 2007/09/07 00:58:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -535,10 +535,12 @@ DefineIndex(RangeVar *heapRelation,
         *
         * We can exclude any running transactions that have xmin >= the xmax of
         * our reference snapshot, since they are clearly not interested in any
-        * missing older tuples.  Also, GetCurrentVirtualXIDs never reports our
-        * own vxid, so we need not check for that.
+        * missing older tuples.  Transactions in other DBs aren't a problem
+        * either, since they'll never even be able to see this index.
+        * Also, GetCurrentVirtualXIDs never reports our own vxid, so we
+        * need not check for that.
         */
-       old_snapshots = GetCurrentVirtualXIDs(ActiveSnapshot->xmax);
+       old_snapshots = GetCurrentVirtualXIDs(ActiveSnapshot->xmax, false);
 
        while (VirtualTransactionIdIsValid(*old_snapshots))
        {
index a467df9..15701b9 100644 (file)
@@ -23,7 +23,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.30 2007/09/05 21:11:19 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.31 2007/09/07 00:58:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -891,10 +891,11 @@ IsBackendPid(int pid)
  * The array is palloc'd and is terminated with an invalid VXID.
  *
  * If limitXmin is not InvalidTransactionId, we skip any backends
- * with xmin >= limitXmin.  Also, our own process is always skipped.
+ * with xmin >= limitXmin.  If allDbs is false, we skip backends attached
+ * to other databases.  Also, our own process is always skipped.
  */
 VirtualTransactionId *
-GetCurrentVirtualXIDs(TransactionId limitXmin)
+GetCurrentVirtualXIDs(TransactionId limitXmin, bool allDbs)
 {
        VirtualTransactionId *vxids;
        ProcArrayStruct *arrayP = procArray;
@@ -910,24 +911,28 @@ GetCurrentVirtualXIDs(TransactionId limitXmin)
        for (index = 0; index < arrayP->numProcs; index++)
        {
                volatile PGPROC    *proc = arrayP->procs[index];
-               /* Fetch xmin just once - might change on us? */
-               TransactionId pxmin = proc->xmin;
 
                if (proc == MyProc)
                        continue;
 
-               /*
-                * Note that InvalidTransactionId precedes all other XIDs, so a
-                * proc that hasn't set xmin yet will always be included.
-                */
-               if (!TransactionIdIsValid(limitXmin) ||
-                       TransactionIdPrecedes(pxmin, limitXmin))
+               if (allDbs || proc->databaseId == MyDatabaseId)
                {
-                       VirtualTransactionId vxid;
+                       /* Fetch xmin just once - might change on us? */
+                       TransactionId pxmin = proc->xmin;
+
+                       /*
+                        * Note that InvalidTransactionId precedes all other XIDs, so a
+                        * proc that hasn't set xmin yet will always be included.
+                        */
+                       if (!TransactionIdIsValid(limitXmin) ||
+                               TransactionIdPrecedes(pxmin, limitXmin))
+                       {
+                               VirtualTransactionId vxid;
 
-                       GET_VXID_FROM_PGPROC(vxid, *proc);
-                       if (VirtualTransactionIdIsValid(vxid))
-                               vxids[count++] = vxid;
+                               GET_VXID_FROM_PGPROC(vxid, *proc);
+                               if (VirtualTransactionIdIsValid(vxid))
+                                       vxids[count++] = vxid;
+                       }
                }
        }
 
index 5247105..21e0c83 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/storage/procarray.h,v 1.15 2007/09/05 18:10:48 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/storage/procarray.h,v 1.16 2007/09/07 00:58:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -33,7 +33,8 @@ extern PGPROC *BackendPidGetProc(int pid);
 extern int     BackendXidGetPid(TransactionId xid);
 extern bool IsBackendPid(int pid);
 
-extern VirtualTransactionId *GetCurrentVirtualXIDs(TransactionId limitXmin);
+extern VirtualTransactionId *GetCurrentVirtualXIDs(TransactionId limitXmin,
+                                                                                                  bool allDbs);
 extern int     CountActiveBackends(void);
 extern int     CountDBBackends(Oid databaseid);
 extern int     CountUserBackends(Oid roleid);