aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2022-12-19 14:43:09 -0500
committerRobert Haas <rhaas@postgresql.org>2022-12-19 14:43:09 -0500
commit10ea0f924a2788f9e701d6213745aaa5ca3efb8a (patch)
tree7b59764577d935ade39514b0c500237acb38a527
parent7122f9d5437789312cb0a7e26e853bb8d2e57add (diff)
downloadpostgresql-10ea0f924a2788f9e701d6213745aaa5ca3efb8a.tar.gz
postgresql-10ea0f924a2788f9e701d6213745aaa5ca3efb8a.zip
Expose some information about backend subxact status.
A new function pg_stat_get_backend_subxact() can be used to get information about the number of subtransactions in the cache of a particular backend and whether that cache has overflowed. This can be useful for tracking down performance problems that can result from overflowed snapshots. Dilip Kumar, reviewed by Zhihong Yu, Nikolay Samokhvalov, Justin Pryzby, Nathan Bossart, Ashutosh Sharma, Julien Rouhaud. Additional design comments from Andres Freund, Tom Lane, Bruce Momjian, and David G. Johnston. Discussion: http://postgr.es/m/CAFiTN-ut0uwkRJDQJeDPXpVyTWD46m3gt3JDToE02hTfONEN=Q@mail.gmail.com
-rw-r--r--doc/src/sgml/monitoring.sgml18
-rw-r--r--src/backend/storage/ipc/sinvaladt.c13
-rw-r--r--src/backend/utils/activity/backend_status.c4
-rw-r--r--src/backend/utils/adt/pgstatfuncs.c38
-rw-r--r--src/include/catalog/catversion.h2
-rw-r--r--src/include/catalog/pg_proc.dat7
-rw-r--r--src/include/storage/sinvaladt.h4
-rw-r--r--src/include/utils/backend_status.h11
8 files changed, 90 insertions, 7 deletions
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 11a8ebe5ec7..363b183e5f0 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -5674,6 +5674,24 @@ FROM pg_stat_get_backend_idset() AS backendid;
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
+ <primary>pg_stat_get_backend_subxact</primary>
+ </indexterm>
+ <function>pg_stat_get_backend_subxact</function> ( <type>integer</type> )
+ <returnvalue>record</returnvalue>
+ </para>
+ <para>
+ Returns a record of information about the subtransactions of the
+ backend with the specified ID.
+ The fields returned are <parameter>subxact_count</parameter>, which
+ is the number of subtransactions in the backend's subtransaction cache,
+ and <parameter>subxact_overflow</parameter>, which indicates whether
+ the backend's subtransaction cache is overflowed or not.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
<primary>pg_stat_get_backend_userid</primary>
</indexterm>
<function>pg_stat_get_backend_userid</function> ( <type>integer</type> )
diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c
index 59310b708fb..4a20fe7ebee 100644
--- a/src/backend/storage/ipc/sinvaladt.c
+++ b/src/backend/storage/ipc/sinvaladt.c
@@ -404,17 +404,20 @@ BackendIdGetProc(int backendID)
/*
* BackendIdGetTransactionIds
- * Get the xid and xmin of the backend. The result may be out of date
- * arbitrarily quickly, so the caller must be careful about how this
- * information is used.
+ * Get the xid, xmin, nsubxid and overflow status of the backend. The
+ * result may be out of date arbitrarily quickly, so the caller must be
+ * careful about how this information is used.
*/
void
-BackendIdGetTransactionIds(int backendID, TransactionId *xid, TransactionId *xmin)
+BackendIdGetTransactionIds(int backendID, TransactionId *xid,
+ TransactionId *xmin, int *nsubxid, bool *overflowed)
{
SISeg *segP = shmInvalBuffer;
*xid = InvalidTransactionId;
*xmin = InvalidTransactionId;
+ *nsubxid = 0;
+ *overflowed = false;
/* Need to lock out additions/removals of backends */
LWLockAcquire(SInvalWriteLock, LW_SHARED);
@@ -428,6 +431,8 @@ BackendIdGetTransactionIds(int backendID, TransactionId *xid, TransactionId *xmi
{
*xid = proc->xid;
*xmin = proc->xmin;
+ *nsubxid = proc->subxidStatus.count;
+ *overflowed = proc->subxidStatus.overflowed;
}
}
diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c
index 1146a6c33cd..7ecf467b8cd 100644
--- a/src/backend/utils/activity/backend_status.c
+++ b/src/backend/utils/activity/backend_status.c
@@ -855,7 +855,9 @@ pgstat_read_current_status(void)
localentry->backend_id = i;
BackendIdGetTransactionIds(i,
&localentry->backend_xid,
- &localentry->backend_xmin);
+ &localentry->backend_xmin,
+ &localentry->backend_subxact_count,
+ &localentry->backend_subxact_overflowed);
localentry++;
localappname += NAMEDATALEN;
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 04a5a990025..46f98fd67f5 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -687,6 +687,44 @@ pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
PG_RETURN_OID(beentry->st_userid);
}
+Datum
+pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
+{
+#define PG_STAT_GET_SUBXACT_COLS 2
+ TupleDesc tupdesc;
+ Datum values[PG_STAT_GET_SUBXACT_COLS];
+ bool nulls[PG_STAT_GET_SUBXACT_COLS];
+ int32 beid = PG_GETARG_INT32(0);
+ LocalPgBackendStatus *local_beentry;
+
+ /* Initialise values and NULL flags arrays */
+ MemSet(values, 0, sizeof(values));
+ MemSet(nulls, 0, sizeof(nulls));
+
+ /* Initialise attributes information in the tuple descriptor */
+ tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_SUBXACT_COLS);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 1, "subxact_count",
+ INT4OID, -1, 0);
+ TupleDescInitEntry(tupdesc, (AttrNumber) 2, "subxact_overflow",
+ BOOLOID, -1, 0);
+
+ BlessTupleDesc(tupdesc);
+
+ if ((local_beentry = pgstat_fetch_stat_local_beentry(beid)) != NULL)
+ {
+ /* Fill values and NULLs */
+ values[0] = Int32GetDatum(local_beentry->backend_subxact_count);
+ values[1] = BoolGetDatum(local_beentry->backend_subxact_overflowed);
+ }
+ else
+ {
+ nulls[0] = true;
+ nulls[1] = true;
+ }
+
+ /* Returns the record as Datum */
+ PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
+}
Datum
pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 5cb12437a67..094f59f82db 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -57,6 +57,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 202212131
+#define CATALOG_VERSION_NO 202212191
#endif
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 719599649a9..d763419c0de 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5441,6 +5441,13 @@
proname => 'pg_stat_get_backend_dbid', provolatile => 's', proparallel => 'r',
prorettype => 'oid', proargtypes => 'int4',
prosrc => 'pg_stat_get_backend_dbid' },
+{ oid => '6107', descr => 'statistics: get subtransaction status of backend',
+ proname => 'pg_stat_get_backend_subxact', provolatile => 's', proparallel => 'r',
+ prorettype => 'record', proargtypes => 'int4',
+ proallargtypes => '{int4,int4,bool}',
+ proargmodes => '{i,o,o}',
+ proargnames => '{bid,subxact_count,subxact_overflowed}',
+ prosrc => 'pg_stat_get_backend_subxact' },
{ oid => '1939', descr => 'statistics: user ID of backend',
proname => 'pg_stat_get_backend_userid', provolatile => 's',
proparallel => 'r', prorettype => 'oid', proargtypes => 'int4',
diff --git a/src/include/storage/sinvaladt.h b/src/include/storage/sinvaladt.h
index 91e24189a7a..bf739ebdba7 100644
--- a/src/include/storage/sinvaladt.h
+++ b/src/include/storage/sinvaladt.h
@@ -32,7 +32,9 @@ extern Size SInvalShmemSize(void);
extern void CreateSharedInvalidationState(void);
extern void SharedInvalBackendInit(bool sendOnly);
extern PGPROC *BackendIdGetProc(int backendID);
-extern void BackendIdGetTransactionIds(int backendID, TransactionId *xid, TransactionId *xmin);
+extern void BackendIdGetTransactionIds(int backendID, TransactionId *xid,
+ TransactionId *xmin, int *nsubxid,
+ bool *overflowed);
extern void SIInsertDataEntries(const SharedInvalidationMessage *data, int n);
extern int SIGetDataEntries(SharedInvalidationMessage *data, int datasize);
diff --git a/src/include/utils/backend_status.h b/src/include/utils/backend_status.h
index b582b46e9f9..e076adcaa82 100644
--- a/src/include/utils/backend_status.h
+++ b/src/include/utils/backend_status.h
@@ -266,6 +266,17 @@ typedef struct LocalPgBackendStatus
* not.
*/
TransactionId backend_xmin;
+
+ /*
+ * Number of cached subtransactions in the current session.
+ */
+ int backend_subxact_count;
+
+ /*
+ * The number of subtransactions in the current session exceeded the cached
+ * subtransaction limit.
+ */
+ bool backend_subxact_overflowed;
} LocalPgBackendStatus;