oldest_multixact.patch.txt

text/plain

Filename: oldest_multixact.patch.txt
Type: text/plain
Part: 0
Message: Re: [Proposal] Expose internal MultiXact member count function for efficient monitoring
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index 6b3f38a2fd6..8b31b57140d 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -2863,17 +2863,16 @@ find_multixact_start(MultiXactId multi, MultiXactOffset *result)
  * exist.  Return false if unable to determine.
  */
 static bool
-ReadMultiXactCounts(uint32 *multixacts, MultiXactOffset *members)
+ReadMultiXactCounts(uint32 *multixacts, MultiXactOffset *members, MultiXactId *oldestMultiXactId)
 {
 	MultiXactOffset nextOffset;
 	MultiXactOffset oldestOffset;
-	MultiXactId oldestMultiXactId;
 	MultiXactId nextMultiXactId;
 	bool		oldestOffsetKnown;
 
 	LWLockAcquire(MultiXactGenLock, LW_SHARED);
 	nextOffset = MultiXactState->nextOffset;
-	oldestMultiXactId = MultiXactState->oldestMultiXactId;
+	*oldestMultiXactId = MultiXactState->oldestMultiXactId;
 	nextMultiXactId = MultiXactState->nextMXact;
 	oldestOffset = MultiXactState->oldestOffset;
 	oldestOffsetKnown = MultiXactState->oldestOffsetKnown;
@@ -2883,7 +2882,7 @@ ReadMultiXactCounts(uint32 *multixacts, MultiXactOffset *members)
 		return false;
 
 	*members = nextOffset - oldestOffset;
-	*multixacts = nextMultiXactId - oldestMultiXactId;
+	*multixacts = nextMultiXactId - *oldestMultiXactId;
 	return true;
 }
 
@@ -2922,9 +2921,10 @@ MultiXactMemberFreezeThreshold(void)
 	uint32		victim_multixacts;
 	double		fraction;
 	int			result;
+	MultiXactId oldestMultiXactId;
 
 	/* If we can't determine member space utilization, assume the worst. */
-	if (!ReadMultiXactCounts(&multixacts, &members))
+	if (!ReadMultiXactCounts(&multixacts, &members, &oldestMultiXactId))
 		return 0;
 
 	/* If member space utilization is low, no special action is required. */
@@ -3503,22 +3503,24 @@ Datum
 pg_get_multixact_count(PG_FUNCTION_ARGS)
 {
 	TupleDesc		tupdesc;
-	Datum			values[2];
-	bool			nulls[2] = {false, false};
+	Datum			values[3];
+	bool			nulls[3] = {false, false, false};
 	MultiXactOffset	members;
 	uint32			multixacts;
 	HeapTuple		tuple;
+	MultiXactId oldestMultiXactId;
 
 	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
 		ereport(ERROR,
 				(errmsg("return type must be a row type")));
 
-	if (!ReadMultiXactCounts(&multixacts, &members))
+	if (!ReadMultiXactCounts(&multixacts, &members, &oldestMultiXactId))
 		ereport(ERROR,
 				(errmsg("could not read multixact counts")));
 
 	values[0] = UInt32GetDatum(multixacts);
 	values[1] = UInt32GetDatum(members);
+	values[2] = UInt32GetDatum(oldestMultiXactId);
 
 	tuple = heap_form_tuple(tupdesc, values, nulls);
 	PG_RETURN_DATUM(HeapTupleGetDatum(tuple));
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 0e511dd3473..2be0cd35e12 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -12579,13 +12579,13 @@
 # Returns current counts of multixact members and multixact IDs
 {
   oid => '9001',
-  descr => 'get current multixact member and multixact ID counts',
+  descr => 'get current multixact member and multixact ID counts and oldest multixact',
   proname => 'pg_get_multixact_count',
   prorettype => 'record',
   proargtypes => '',
-  proallargtypes => '{int4,int8}',
-  proargmodes => '{o,o}',
-  proargnames => '{multixacts,members}',
+  proallargtypes => '{int4,int8,int4}',
+  proargmodes => '{o,o,o}',
+  proargnames => '{multixacts,members,oldestmultixact}',
   provolatile => 'v',
   proparallel => 's',
   prosrc => 'pg_get_multixact_count'