TransactionIdIsInProgress() must check KnownAssignedXids.
authorSimon Riggs <[email protected]>
Thu, 1 Oct 2009 16:39:28 +0000 (17:39 +0100)
committerSimon Riggs <[email protected]>
Thu, 1 Oct 2009 16:39:28 +0000 (17:39 +0100)
src/backend/storage/ipc/procarray.c
src/include/storage/procarray.h

index cc552d81b583f1e3d4960f6f78ec3e730d06d049..4cb0bc9a2cb18e797c0cf9a28626c5a182d36702 100644 (file)
@@ -137,6 +137,7 @@ static void KnownAssignedXidsAdd(TransactionId xid, int nsubxids,
                                                                                        TransactionId *subxid);
 static void KnownAssignedXidsRemove(TransactionId xid, bool report_error);
 static void KnownAssignedXidsRemoveMany(TransactionId xid);
+static bool KnownAssignedXidsFind(TransactionId xid);
 static void KnownAssignedXidsDisplay(int trace_level);
 
 /*
@@ -608,6 +609,7 @@ TransactionIdIsInProgress(TransactionId xid)
        TransactionId topxid;
        int                     i,
                                j;
+       bool found;
 
        /*
         * Don't bother checking a transaction older than RecentXmin; it could not
@@ -729,6 +731,22 @@ TransactionIdIsInProgress(TransactionId xid)
                        xids[nxids++] = pxid;
        }
 
+       /*
+        * Check if the transaction id known assigned or whether it is
+        * completed.
+        */
+       if (RecoveryInProgress())
+       {
+               found = FindKnownAssignedTransactionId(xid);
+
+               if (found)
+               {
+                       LWLockRelease(ProcArrayLock);
+                       xc_by_main_xid_inc();   /* we don't know whether its child or main */
+                       return true;
+               }
+       }
+
        LWLockRelease(ProcArrayLock);
 
        /*
@@ -760,17 +778,33 @@ TransactionIdIsInProgress(TransactionId xid)
         * held ProcArrayLock).
         */
        topxid = SubTransGetTopmostTransaction(xid);
-       Assert(TransactionIdIsValid(topxid));
-       if (!TransactionIdEquals(topxid, xid))
+       if (!RecoveryInProgress())
        {
-               for (i = 0; i < nxids; i++)
+               Assert(TransactionIdIsValid(topxid));
+               if (!TransactionIdEquals(topxid, xid))
                {
-                       if (TransactionIdEquals(xids[i], topxid))
-                               return true;
+                       for (i = 0; i < nxids; i++)
+                       {
+                               if (TransactionIdEquals(xids[i], topxid))
+                                       return true;
+                       }
                }
+
+               return false;
        }
+       else
+       {
+               /*
+                * We weren't sure which xids were top-level or not, so 
+                * we don't have space to record them in the work area.
+                * So we must re-acquire lock and re-check KnownAssignedXids.
+                */
+               LWLockAcquire(ProcArrayLock, LW_SHARED);
+               found = FindKnownAssignedTransactionId(xid);
+               LWLockRelease(ProcArrayLock);
 
-       return false;
+               return found;
+       }
 }
 
 /*
@@ -2303,6 +2337,12 @@ ExpireOldKnownAssignedTransactionIds(TransactionId xid)
        LWLockRelease(ProcArrayLock);
 }
 
+bool
+FindKnownAssignedTransactionId(TransactionId xid)
+{
+       return KnownAssignedXidsFind(xid);
+}
+
 /*
  * Get an array of KnownAssignedXids, not necessarily in sorted order.
  * 
@@ -2492,6 +2532,16 @@ KnownAssignedXidsRemoveMany(TransactionId xid)
        }
 }
 
+static bool
+KnownAssignedXidsFind(TransactionId xid)
+{
+       bool found;
+
+       (void) hash_search(KnownAssignedXidsHash, &xid, HASH_FIND, &found);
+
+       return found;
+}
+
 /*
  * xidComparator
  *            qsort comparison function for XIDs
index 36d5d52ae73a6a17b91f728ad353cb1190ee7190..302090398ec6746df589f68135f74ca5a97a7020 100644 (file)
@@ -37,6 +37,7 @@ extern void ExpireOldKnownAssignedTransactionIds(TransactionId xid);
 extern int  GetKnownAssignedTransactions(TransactionId *xarray, 
                                                                                TransactionId *xmin, TransactionId xmax,
                                                                                bool *overflow);
+extern bool FindKnownAssignedTransactionId(TransactionId xid);
 
 extern bool IsRunningXactDataValid(void);
 extern void GetRunningTransactionData(void);