Optimize GetConflictingVirtualXIDs() in roughly the same manner we
optimize TransactionIdIsInProgress().

Views?

-- 
 Simon Riggs           www.2ndQuadrant.com
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 12de877..7f9b10e 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -1686,12 +1686,21 @@ GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0,
  * this array sufficiently often that we use malloc for the result.
  */
 VirtualTransactionId *
-GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
+GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid, int *return_count)
 {
 	static VirtualTransactionId *vxids;
 	ProcArrayStruct *arrayP = procArray;
 	int			count = 0;
 	int			index;
+	TransactionId globalxmin;
+
+	/*
+	 * Don't bother checking a valid TransactionId older than RecentGlobalXmin;
+	 * it could not possibly cause a conflict.
+	 */
+	if (TransactionIdPrecedes(limitXmin, RecentGlobalXmin) &&
+		TransactionIdIsValid(limitXmin))
+		return NULL;
 
 	/*
 	 * If not first time through, get workspace to remember main XIDs in. We
@@ -1717,19 +1726,28 @@ GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
 	if (!TransactionIdIsValid(limitXmin))
 		limitXmin = ShmemVariableCache->latestCompletedXid;
 
+	globalxmin = ShmemVariableCache->latestCompletedXid;
+
 	for (index = 0; index < arrayP->numProcs; index++)
 	{
 		volatile PGPROC *proc = arrayP->procs[index];
+		TransactionId pxmin;
 
 		/* Exclude prepared transactions */
 		if (proc->pid == 0)
 			continue;
 
+		/* Fetch xmin just once - can't change on us, but good coding */
+		pxmin = proc->xmin;
+
+		/* Update globalxmin to be the smallest valid xmin */
+		if (TransactionIdIsNormal(pxmin) &&
+			TransactionIdPrecedes(pxmin, globalxmin))
+			globalxmin = pxmin;
+
 		if (!OidIsValid(dbOid) ||
 			proc->databaseId == dbOid)
 		{
-			/* Fetch xmin just once - can't change on us, but good coding */
-			TransactionId pxmin = proc->xmin;
 
 			/*
 			 * We ignore an invalid pxmin because this means that backend
@@ -1748,6 +1766,10 @@ GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
 
 	LWLockRelease(ProcArrayLock);
 
+	RecentGlobalXmin = globalxmin;
+
+	*return_count = count;
+
 	/* add the terminator */
 	vxids[count].backendId = InvalidBackendId;
 	vxids[count].localTransactionId = InvalidLocalTransactionId;
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index c8fde2f..ea9c2e3 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -244,11 +244,12 @@ void
 ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileNode node)
 {
 	VirtualTransactionId *backends;
+	int	conflicts = 0;
 
 	backends = GetConflictingVirtualXIDs(latestRemovedXid,
-										 node.dbNode);
-
-	ResolveRecoveryConflictWithVirtualXIDs(backends,
+										 node.dbNode, &conflicts);
+	if (conflicts > 0)
+		ResolveRecoveryConflictWithVirtualXIDs(backends,
 										   PROCSIG_RECOVERY_CONFLICT_SNAPSHOT);
 }
 
@@ -256,6 +257,7 @@ void
 ResolveRecoveryConflictWithTablespace(Oid tsid)
 {
 	VirtualTransactionId *temp_file_users;
+	int	conflicts = 0;
 
 	/*
 	 * Standby users may be currently using this tablespace for
@@ -277,7 +279,7 @@ ResolveRecoveryConflictWithTablespace(Oid tsid)
 	 * non-transactional.
 	 */
 	temp_file_users = GetConflictingVirtualXIDs(InvalidTransactionId,
-												InvalidOid);
+												InvalidOid, &conflicts);
 	ResolveRecoveryConflictWithVirtualXIDs(temp_file_users,
 										   PROCSIG_RECOVERY_CONFLICT_TABLESPACE);
 }
@@ -333,8 +335,9 @@ ResolveRecoveryConflictWithLock(Oid dbOid, Oid relOid)
 			backends = GetLockConflicts(&locktag, AccessExclusiveLock);
 		else
 		{
+			int	conflicts = 0;
 			backends = GetConflictingVirtualXIDs(InvalidTransactionId,
-												 InvalidOid);
+												 InvalidOid, &conflicts);
 			report_memory_error = true;
 		}
 
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index 5a026e9..e01ad79 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -57,7 +57,8 @@ extern bool IsBackendPid(int pid);
 extern VirtualTransactionId *GetCurrentVirtualXIDs(TransactionId limitXmin,
 					  bool excludeXmin0, bool allDbs, int excludeVacuum,
 					  int *nvxids);
-extern VirtualTransactionId *GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid);
+extern VirtualTransactionId *GetConflictingVirtualXIDs(TransactionId limitXmin,
+					  Oid dbOid, int *return_count);
 extern pid_t CancelVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode);
 
 extern int	CountActiveBackends(void);
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to