Jim Nasby wrote:
> On 6/14/15 9:50 AM, Alvaro Herrera wrote:
> >+    values[0] = MultiXactState->oldestMultiXactId;
> 
> What about oldestOffset and offsetStopLimit? Seems those would be useful
> too. Looks good other than that.

Yeah, that's what I was trying to say.  How about this?

I realized that pg_get_multixact_members() was not documented, so I
added a blurb about it too.  I guess I could backpatch that part to 9.3
because it's been present all along.

-- 
Álvaro Herrera                http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 9a2a1f6..1925c6c 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -14874,6 +14874,57 @@ SELECT collation for ('foo' COLLATE "de_DE");
     For example <literal>10:20:10,14,15</literal> means
     <literal>xmin=10, xmax=20, xip_list=10, 14, 15</literal>.
    </para>
+
+   <indexterm>
+    <primary>pg_get_multixact_members</primary>
+   </indexterm>
+
+   <indexterm>
+    <primary>pg_get_multixact_range</primary>
+   </indexterm>
+
+   <para>
+    The functions shown in <xref linkend="functions-info-multixact-table">
+    obtain information relative to multixacts in the system.
+   </para>
+
+   <table id="functions-info-multixact-table">
+    <title>Multixact Functions</title>
+    <tgroup cols="3">
+     <thead>
+      <row><entry>Name</entry> <entry>Return Type</entry> <entry>Description</entry></row>
+     </thead>
+
+     <tbody>
+      <row>
+       <entry><literal><function>pg_get_multixact_range()</function></literal></entry>
+       <entry>
+        <parameter>oldestmulti</parameter><type>xid</type>,
+        <parameter>nextmulti</parameter><type>xid</type>,
+        <parameter>stopmulti</parameter><type>xid</type>,
+        <parameter>oldestmember</parameter><type>xid</type>,
+        <parameter>nextmember</parameter><type>xid</type>,
+        <parameter>stopmember</parameter><type>xid</type>
+       </entry>
+       <entry>
+        get current oldest, next and stop limits for multixact IDs,
+        and oldest, next and stop limit for multixact members
+       </entry>
+      </row>
+
+      <row>
+       <entry><literal><function>pg_get_multixact_members(<type>xid</type>)</function></literal></entry>
+       <entry>
+        <parameter>xid</parameter><type>xid</type>,
+        <parameter>mode</parameter><type>text</type>
+       </entry>
+       <entry>
+        get Xid and mode of the members of the given multixact
+       </entry>
+      </row>
+     </tbody>
+    </tgroup>
+   </table>
   </sect1>
 
   <sect1 id="functions-admin">
diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml
index 4383862..db4d457 100644
--- a/doc/src/sgml/maintenance.sgml
+++ b/doc/src/sgml/maintenance.sgml
@@ -662,6 +662,14 @@ HINT:  Stop the postmaster and use a standalone backend to VACUUM in "mydb".
      Both of these kinds of whole-table scans will occur even if autovacuum is
      nominally disabled.
     </para>
+
+    <para>
+     To know the limits of the live range of both the multixact ID counter and
+     of the members storage area, and the limits which would cause further
+     multixact creation to be rejected, see
+     <xref linkend="functions-info-multixact-table">.
+    </para>
+
    </sect3>
   </sect2>
 
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index 5c25c2f..296c85b 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -66,6 +66,7 @@
  */
 #include "postgres.h"
 
+#include "access/htup_details.h"
 #include "access/multixact.h"
 #include "access/slru.h"
 #include "access/transam.h"
@@ -3308,3 +3309,38 @@ pg_get_multixact_members(PG_FUNCTION_ARGS)
 
 	SRF_RETURN_DONE(funccxt);
 }
+
+Datum
+pg_get_multixact_range(PG_FUNCTION_ARGS)
+{
+	TupleDesc		tupdesc;
+	HeapTuple		htup;
+	Datum			values[6];
+	bool			nulls[6];
+
+	/* Build a tuple descriptor for our result type */
+	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+		elog(ERROR, "return type must be a row type");
+	tupdesc = BlessTupleDesc(tupdesc);
+
+	MemSet(nulls, 0, sizeof(nulls));
+
+	LWLockAcquire(MultiXactGenLock, LW_SHARED);
+	values[0] = MultiXactState->oldestMultiXactId;
+	values[1] = MultiXactState->nextMXact;
+	values[2] = MultiXactState->multiStopLimit;
+	if (MultiXactState->oldestOffsetKnown)
+		values[3] = MultiXactState->oldestOffset;
+	else
+		nulls[3] = true;
+	values[4] = MultiXactState->nextOffset;
+	if (MultiXactState->offsetStopLimitKnown)
+		values[5] = MultiXactState->offsetStopLimit;
+	else
+		nulls[5] = true;
+	LWLockRelease(MultiXactGenLock);
+
+	htup = heap_form_tuple(tupdesc, values, nulls);
+
+	PG_RETURN_DATUM(HeapTupleGetDatum(htup));
+}
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 92af36d..8241732 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -2911,6 +2911,8 @@ DATA(insert OID = 1065 (  pg_prepared_xact PGNSP PGUID 12 1 1000 0 0 f f f f t t
 DESCR("view two-phase transactions");
 DATA(insert OID = 3819 (  pg_get_multixact_members PGNSP PGUID 12 1 1000 0 0 f f f f t t v 1 0 2249 "28" "{28,28,25}" "{i,o,o}" "{multixid,xid,mode}" _null_ pg_get_multixact_members _null_ _null_ _null_ ));
 DESCR("view members of a multixactid");
+DATA(insert OID = 3846 (  pg_get_multixact_range   PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 2249 "" "{28,28,28,28,28,28}" "{o,o,o,o,o,o}" "{oldestmulti,nextmulti,stopmulti,oldestmember,nextmember,stopmember}" _null_ pg_get_multixact_range _null_ _null_ _null_ ));
+DESCR("get range and limits of multixacts");
 
 DATA(insert OID = 3537 (  pg_describe_object		PGNSP PGUID 12 1 0 0 0 f f f f t f s 3 0 25 "26 26 23" _null_ _null_ _null_ _null_ pg_describe_object _null_ _null_ _null_ ));
 DESCR("get identification of SQL object");
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 929a728..2fd612c 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -1143,6 +1143,7 @@ extern Datum pg_prepared_xact(PG_FUNCTION_ARGS);
 
 /* access/transam/multixact.c */
 extern Datum pg_get_multixact_members(PG_FUNCTION_ARGS);
+extern Datum pg_get_multixact_range(PG_FUNCTION_ARGS);
 
 /* catalogs/dependency.c */
 extern Datum pg_describe_object(PG_FUNCTION_ARGS);
-- 
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