Implement mxid_age() to compute multi-xid age
authorBruce Momjian
Wed, 10 Sep 2014 21:13:04 +0000 (17:13 -0400)
committerBruce Momjian
Wed, 10 Sep 2014 21:13:04 +0000 (17:13 -0400)
Report by Josh Berkus

doc/src/sgml/maintenance.sgml
src/backend/utils/adt/xid.c
src/include/catalog/catversion.h
src/include/catalog/pg_proc.h
src/include/utils/builtins.h

index cf174f071576faba23af85356b2b1a0c754b5117..d692308cf494f61266bbf95d69db8c2fd33f3b76 100644 (file)
@@ -640,7 +640,12 @@ HINT:  Stop the postmaster and vacuum that database in single-user mode.
      possible multixact ID still appearing in any tuple of that table.
      If this value is older than
      , a whole-table
-     scan is forced.  Whole-table VACUUM scans, regardless of
+     scan is forced.  mxid_age() can be used on
+     pg_class.relminmxid to find its age.
+    
+
+    
+     Whole-table VACUUM scans, regardless of
      what causes them, enable advancing the value for that table.
      Eventually, as all tables in all databases are scanned and their
      oldest multixact values are advanced, on-disk storage for older
index 602a9e5d6f4838d5a5d9ebe38194329873874d61..ecb3cf55dd1789c978435dc2a1c5223be988a8dc 100644 (file)
@@ -16,6 +16,7 @@
 
 #include 
 
+#include "access/multixact.h"
 #include "access/transam.h"
 #include "access/xact.h"
 #include "libpq/pqformat.h"
@@ -102,6 +103,21 @@ xid_age(PG_FUNCTION_ARGS)
    PG_RETURN_INT32((int32) (now - xid));
 }
 
+/*
+ *     mxid_age            - compute age of a multi XID (relative to latest stable mxid)
+ */
+Datum
+mxid_age(PG_FUNCTION_ARGS)
+{
+   TransactionId xid = PG_GETARG_TRANSACTIONID(0);
+   MultiXactId now = ReadNextMultiXactId();
+
+   if (!MultiXactIdIsValid(xid))
+       PG_RETURN_INT32(INT_MAX);
+
+   PG_RETURN_INT32((int32) (now - xid));
+}
+
 /*
  * xidComparator
  *     qsort comparison function for XIDs
index 5dc0455477ae44a09aa7f1ace75ae26fb29d5b67..74582e9bbb8393a1fd8306419bb981598883085c 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 201409091
+#define CATALOG_VERSION_NO 201409101
 
 #endif
index bd1b41723c01143b2deb4048ec9f277a910cc582..a56a6359ca861c86208c4bdc184f305f6eb6fb63 100644 (file)
@@ -1279,6 +1279,8 @@ DATA(insert OID = 1180 (  abstime        PGNSP PGUID 12 1 0 0 0 f f f f t f i 1 0 7
 DESCR("convert timestamp with time zone to abstime");
 DATA(insert OID = 1181 (  age             PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 23 "28" _null_ _null_ _null_ _null_ xid_age _null_ _null_ _null_ ));
 DESCR("age of a transaction ID, in transactions before current transaction");
+DATA(insert OID = 3939 (  mxid_age        PGNSP PGUID 12 1 0 0 0 f f f f t f s 1 0 23 "28" _null_ _null_ _null_ _null_ mxid_age _null_ _null_ _null_ ));
+DESCR("age of a multi-transaction ID, in multi-transactions before current multi-transaction");
 
 DATA(insert OID = 1188 (  timestamptz_mi   PGNSP PGUID 12 1 0 0 0 f f f f t f i 2 0 1186 "1184 1184" _null_ _null_ _null_ _null_ timestamp_mi _null_ _null_ _null_ ));
 DATA(insert OID = 1189 (  timestamptz_pl_interval PGNSP PGUID 12 1 0 0 0 f f f f t f s 2 0 1184 "1184 1186" _null_ _null_ _null_ _null_ timestamptz_pl_interval _null_ _null_ _null_ ));
index 78cc0a0bea38160c1c626ae638acf7cc750926a8..d88e7a3b265821566adf08c7ca69176dfc1ddbe2 100644 (file)
@@ -845,6 +845,7 @@ extern Datum xidrecv(PG_FUNCTION_ARGS);
 extern Datum xidsend(PG_FUNCTION_ARGS);
 extern Datum xideq(PG_FUNCTION_ARGS);
 extern Datum xid_age(PG_FUNCTION_ARGS);
+extern Datum mxid_age(PG_FUNCTION_ARGS);
 extern int xidComparator(const void *arg1, const void *arg2);
 extern Datum cidin(PG_FUNCTION_ARGS);
 extern Datum cidout(PG_FUNCTION_ARGS);