aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/storage/ipc/procarray.c7
-rw-r--r--src/backend/utils/adt/xid.c26
-rw-r--r--src/include/utils/builtins.h1
3 files changed, 33 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)
{
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 40fcb0ab6d7..4329925f1e3 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -88,6 +88,7 @@ extern void text_to_cstring_buffer(const text *src, char *dst, size_t dst_len);
/* xid.c */
extern int xidComparator(const void *arg1, const void *arg2);
+extern int xidLogicalComparator(const void *arg1, const void *arg2);
/* inet_cidr_ntop.c */
extern char *pg_inet_cidr_ntop(int af, const void *src, int bits,