Skip to content

Commit 10ea0f9

Browse files
committed
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
1 parent 7122f9d commit 10ea0f9

File tree

8 files changed

+90
-7
lines changed

8 files changed

+90
-7
lines changed

doc/src/sgml/monitoring.sgml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5671,6 +5671,24 @@ FROM pg_stat_get_backend_idset() AS backendid;
56715671
</para></entry>
56725672
</row>
56735673

5674+
<row>
5675+
<entry role="func_table_entry"><para role="func_signature">
5676+
<indexterm>
5677+
<primary>pg_stat_get_backend_subxact</primary>
5678+
</indexterm>
5679+
<function>pg_stat_get_backend_subxact</function> ( <type>integer</type> )
5680+
<returnvalue>record</returnvalue>
5681+
</para>
5682+
<para>
5683+
Returns a record of information about the subtransactions of the
5684+
backend with the specified ID.
5685+
The fields returned are <parameter>subxact_count</parameter>, which
5686+
is the number of subtransactions in the backend's subtransaction cache,
5687+
and <parameter>subxact_overflow</parameter>, which indicates whether
5688+
the backend's subtransaction cache is overflowed or not.
5689+
</para></entry>
5690+
</row>
5691+
56745692
<row>
56755693
<entry role="func_table_entry"><para role="func_signature">
56765694
<indexterm>

src/backend/storage/ipc/sinvaladt.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -404,17 +404,20 @@ BackendIdGetProc(int backendID)
404404

405405
/*
406406
* BackendIdGetTransactionIds
407-
* Get the xid and xmin of the backend. The result may be out of date
408-
* arbitrarily quickly, so the caller must be careful about how this
409-
* information is used.
407+
* Get the xid, xmin, nsubxid and overflow status of the backend. The
408+
* result may be out of date arbitrarily quickly, so the caller must be
409+
* careful about how this information is used.
410410
*/
411411
void
412-
BackendIdGetTransactionIds(int backendID, TransactionId *xid, TransactionId *xmin)
412+
BackendIdGetTransactionIds(int backendID, TransactionId *xid,
413+
TransactionId *xmin, int *nsubxid, bool *overflowed)
413414
{
414415
SISeg *segP = shmInvalBuffer;
415416

416417
*xid = InvalidTransactionId;
417418
*xmin = InvalidTransactionId;
419+
*nsubxid = 0;
420+
*overflowed = false;
418421

419422
/* Need to lock out additions/removals of backends */
420423
LWLockAcquire(SInvalWriteLock, LW_SHARED);
@@ -428,6 +431,8 @@ BackendIdGetTransactionIds(int backendID, TransactionId *xid, TransactionId *xmi
428431
{
429432
*xid = proc->xid;
430433
*xmin = proc->xmin;
434+
*nsubxid = proc->subxidStatus.count;
435+
*overflowed = proc->subxidStatus.overflowed;
431436
}
432437
}
433438

src/backend/utils/activity/backend_status.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -855,7 +855,9 @@ pgstat_read_current_status(void)
855855
localentry->backend_id = i;
856856
BackendIdGetTransactionIds(i,
857857
&localentry->backend_xid,
858-
&localentry->backend_xmin);
858+
&localentry->backend_xmin,
859+
&localentry->backend_subxact_count,
860+
&localentry->backend_subxact_overflowed);
859861

860862
localentry++;
861863
localappname += NAMEDATALEN;

src/backend/utils/adt/pgstatfuncs.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,44 @@ pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
687687
PG_RETURN_OID(beentry->st_userid);
688688
}
689689

690+
Datum
691+
pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
692+
{
693+
#define PG_STAT_GET_SUBXACT_COLS 2
694+
TupleDesc tupdesc;
695+
Datum values[PG_STAT_GET_SUBXACT_COLS];
696+
bool nulls[PG_STAT_GET_SUBXACT_COLS];
697+
int32 beid = PG_GETARG_INT32(0);
698+
LocalPgBackendStatus *local_beentry;
699+
700+
/* Initialise values and NULL flags arrays */
701+
MemSet(values, 0, sizeof(values));
702+
MemSet(nulls, 0, sizeof(nulls));
703+
704+
/* Initialise attributes information in the tuple descriptor */
705+
tupdesc = CreateTemplateTupleDesc(PG_STAT_GET_SUBXACT_COLS);
706+
TupleDescInitEntry(tupdesc, (AttrNumber) 1, "subxact_count",
707+
INT4OID, -1, 0);
708+
TupleDescInitEntry(tupdesc, (AttrNumber) 2, "subxact_overflow",
709+
BOOLOID, -1, 0);
710+
711+
BlessTupleDesc(tupdesc);
712+
713+
if ((local_beentry = pgstat_fetch_stat_local_beentry(beid)) != NULL)
714+
{
715+
/* Fill values and NULLs */
716+
values[0] = Int32GetDatum(local_beentry->backend_subxact_count);
717+
values[1] = BoolGetDatum(local_beentry->backend_subxact_overflowed);
718+
}
719+
else
720+
{
721+
nulls[0] = true;
722+
nulls[1] = true;
723+
}
724+
725+
/* Returns the record as Datum */
726+
PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
727+
}
690728

691729
Datum
692730
pg_stat_get_backend_activity(PG_FUNCTION_ARGS)

src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@
5757
*/
5858

5959
/* yyyymmddN */
60-
#define CATALOG_VERSION_NO 202212131
60+
#define CATALOG_VERSION_NO 202212191
6161

6262
#endif

src/include/catalog/pg_proc.dat

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5441,6 +5441,13 @@
54415441
proname => 'pg_stat_get_backend_dbid', provolatile => 's', proparallel => 'r',
54425442
prorettype => 'oid', proargtypes => 'int4',
54435443
prosrc => 'pg_stat_get_backend_dbid' },
5444+
{ oid => '6107', descr => 'statistics: get subtransaction status of backend',
5445+
proname => 'pg_stat_get_backend_subxact', provolatile => 's', proparallel => 'r',
5446+
prorettype => 'record', proargtypes => 'int4',
5447+
proallargtypes => '{int4,int4,bool}',
5448+
proargmodes => '{i,o,o}',
5449+
proargnames => '{bid,subxact_count,subxact_overflowed}',
5450+
prosrc => 'pg_stat_get_backend_subxact' },
54445451
{ oid => '1939', descr => 'statistics: user ID of backend',
54455452
proname => 'pg_stat_get_backend_userid', provolatile => 's',
54465453
proparallel => 'r', prorettype => 'oid', proargtypes => 'int4',

src/include/storage/sinvaladt.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ extern Size SInvalShmemSize(void);
3232
extern void CreateSharedInvalidationState(void);
3333
extern void SharedInvalBackendInit(bool sendOnly);
3434
extern PGPROC *BackendIdGetProc(int backendID);
35-
extern void BackendIdGetTransactionIds(int backendID, TransactionId *xid, TransactionId *xmin);
35+
extern void BackendIdGetTransactionIds(int backendID, TransactionId *xid,
36+
TransactionId *xmin, int *nsubxid,
37+
bool *overflowed);
3638

3739
extern void SIInsertDataEntries(const SharedInvalidationMessage *data, int n);
3840
extern int SIGetDataEntries(SharedInvalidationMessage *data, int datasize);

src/include/utils/backend_status.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,17 @@ typedef struct LocalPgBackendStatus
266266
* not.
267267
*/
268268
TransactionId backend_xmin;
269+
270+
/*
271+
* Number of cached subtransactions in the current session.
272+
*/
273+
int backend_subxact_count;
274+
275+
/*
276+
* The number of subtransactions in the current session exceeded the cached
277+
* subtransaction limit.
278+
*/
279+
bool backend_subxact_overflowed;
269280
} LocalPgBackendStatus;
270281

271282

0 commit comments

Comments
 (0)