Commit 36ad1a87 authored by Bruce Momjian's avatar Bruce Momjian

Implement mxid_age() to compute multi-xid age

Report by Josh Berkus
parent 84aa8ba1
...@@ -640,7 +640,12 @@ HINT: Stop the postmaster and vacuum that database in single-user mode. ...@@ -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. possible multixact ID still appearing in any tuple of that table.
If this value is older than If this value is older than
<xref linkend="guc-vacuum-multixact-freeze-table-age">, a whole-table <xref linkend="guc-vacuum-multixact-freeze-table-age">, a whole-table
scan is forced. Whole-table <command>VACUUM</> scans, regardless of scan is forced. <function>mxid_age()</> can be used on
<structname>pg_class</>.<structfield>relminmxid</> to find its age.
</para>
<para>
Whole-table <command>VACUUM</> scans, regardless of
what causes them, enable advancing the value for that table. what causes them, enable advancing the value for that table.
Eventually, as all tables in all databases are scanned and their Eventually, as all tables in all databases are scanned and their
oldest multixact values are advanced, on-disk storage for older oldest multixact values are advanced, on-disk storage for older
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <limits.h> #include <limits.h>
#include "access/multixact.h"
#include "access/transam.h" #include "access/transam.h"
#include "access/xact.h" #include "access/xact.h"
#include "libpq/pqformat.h" #include "libpq/pqformat.h"
...@@ -102,6 +103,21 @@ xid_age(PG_FUNCTION_ARGS) ...@@ -102,6 +103,21 @@ xid_age(PG_FUNCTION_ARGS)
PG_RETURN_INT32((int32) (now - xid)); 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 * xidComparator
* qsort comparison function for XIDs * qsort comparison function for XIDs
......
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 201409091 #define CATALOG_VERSION_NO 201409101
#endif #endif
...@@ -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 ...@@ -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"); 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_ )); 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"); 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 = 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_ )); 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_ ));
......
...@@ -845,6 +845,7 @@ extern Datum xidrecv(PG_FUNCTION_ARGS); ...@@ -845,6 +845,7 @@ extern Datum xidrecv(PG_FUNCTION_ARGS);
extern Datum xidsend(PG_FUNCTION_ARGS); extern Datum xidsend(PG_FUNCTION_ARGS);
extern Datum xideq(PG_FUNCTION_ARGS); extern Datum xideq(PG_FUNCTION_ARGS);
extern Datum xid_age(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 int xidComparator(const void *arg1, const void *arg2);
extern Datum cidin(PG_FUNCTION_ARGS); extern Datum cidin(PG_FUNCTION_ARGS);
extern Datum cidout(PG_FUNCTION_ARGS); extern Datum cidout(PG_FUNCTION_ARGS);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment