aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/storage/ipc/procarray.c7
-rw-r--r--src/backend/utils/adt/xid.c26
2 files changed, 32 insertions, 1 deletions
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 9a8429169fc..f047f9a242c 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -1164,8 +1164,13 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running)
/*
* Sort the array so that we can add them safely into
* KnownAssignedXids.
+ *
+ * We have to sort them logically, because in KnownAssignedXidsAdd we
+ * call TransactionIdFollowsOrEquals and so on. But we know these XIDs
+ * come from RUNNING_XACTS, which means there are only normal XIDs from
+ * the same epoch, so this is safe.
*/
- qsort(xids, nxids, sizeof(TransactionId), xidComparator);
+ qsort(xids, nxids, sizeof(TransactionId), xidLogicalComparator);
/*
* Add the sorted snapshot into KnownAssignedXids. The running-xacts
diff --git a/src/backend/utils/adt/xid.c b/src/backend/utils/adt/xid.c
index 24c1c937326..faa7737508c 100644
--- a/src/backend/utils/adt/xid.c
+++ b/src/backend/utils/adt/xid.c
@@ -145,6 +145,32 @@ xidComparator(const void *arg1, const void *arg2)
return 0;
}
+/*
+ * xidLogicalComparator
+ * qsort comparison function for XIDs
+ *
+ * This is used to compare only XIDs from the same epoch (e.g. for backends
+ * running at the same time). So there must be only normal XIDs, so there's
+ * no issue with triangle inequality.
+ */
+int
+xidLogicalComparator(const void *arg1, const void *arg2)
+{
+ TransactionId xid1 = *(const TransactionId *) arg1;
+ TransactionId xid2 = *(const TransactionId *) arg2;
+
+ Assert(TransactionIdIsNormal(xid1));
+ Assert(TransactionIdIsNormal(xid2));
+
+ if (TransactionIdPrecedes(xid1, xid2))
+ return -1;
+
+ if (TransactionIdPrecedes(xid2, xid1))
+ return 1;
+
+ return 0;
+}
+
Datum
xid8toxid(PG_FUNCTION_ARGS)
{