Skip to content

Commit 5404377

Browse files
author
Commitfest Bot
committed
[CF 5947] v4 - Adding per backend commit and rollback counters
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/5947 The branch will be overwritten each time a new patch version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. Patch(es): https://www.postgresql.org/message-id/[email protected] Author(s): Bertrand Drouvot
2 parents 8f29467 + e8bdcb1 commit 5404377

File tree

12 files changed

+296
-2
lines changed

12 files changed

+296
-2
lines changed

doc/src/sgml/monitoring.sgml

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,20 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
320320
</entry>
321321
</row>
322322

323+
<row>
324+
<entry>
325+
<structname>pg_stat_backend_transaction</structname>
326+
<indexterm><primary>pg_stat_backend_transaction</primary></indexterm>
327+
</entry>
328+
<entry>
329+
One row per server process, showing statistics related to
330+
the current activity of that process, such as number of commits and
331+
rollbacks.
332+
See <link linkend="monitoring-pg-stat-backend-transaction-view">
333+
<structname>pg_stat_backend_transaction</structname></link> for details.
334+
</entry>
335+
</row>
336+
323337
<row>
324338
<entry><structname>pg_stat_replication</structname><indexterm><primary>pg_stat_replication</primary></indexterm></entry>
325339
<entry>One row per WAL sender process, showing statistics about
@@ -1172,6 +1186,91 @@ description | Waiting for a newly initialized WAL file to reach durable storage
11721186
</note>
11731187
</sect2>
11741188

1189+
<sect2 id="monitoring-pg-stat-backend-transaction-view">
1190+
<title><structname>pg_stat_backend_transaction</structname></title>
1191+
1192+
<indexterm>
1193+
<primary>pg_stat_backend_transaction</primary>
1194+
</indexterm>
1195+
1196+
<para>
1197+
The <structname>pg_stat_backend_transaction</structname> view will have one row
1198+
per server process, showing statistics related to
1199+
the current activity of that process.
1200+
</para>
1201+
1202+
<table id="pg-stat-backend-transaction-view" xreflabel="pg_stat_backend_transaction">
1203+
<title><structname>pg_stat_backend_transaction</structname> View</title>
1204+
<tgroup cols="1">
1205+
<thead>
1206+
<row>
1207+
<entry role="catalog_table_entry"><para role="column_definition">
1208+
Column Type
1209+
</para>
1210+
<para>
1211+
Description
1212+
</para></entry>
1213+
</row>
1214+
</thead>
1215+
1216+
<tbody>
1217+
<row>
1218+
<entry role="catalog_table_entry"><para role="column_definition">
1219+
<structfield>pid</structfield> <type>integer</type>
1220+
</para>
1221+
<para>
1222+
Process ID of this backend
1223+
</para></entry>
1224+
</row>
1225+
1226+
<row>
1227+
<entry role="catalog_table_entry"><para role="column_definition">
1228+
<structfield>xid_count</structfield> <type>bigint</type>
1229+
</para>
1230+
<para>
1231+
The number of XID that have been generated by the backend. It does not take
1232+
into account virtual transaction ID on purpose.
1233+
</para></entry>
1234+
</row>
1235+
1236+
<row>
1237+
<entry role="catalog_table_entry"><para role="column_definition">
1238+
<structfield>xact_commit</structfield> <type>bigint</type>
1239+
</para>
1240+
<para>
1241+
The number of transactions that have been committed.
1242+
</para></entry>
1243+
</row>
1244+
1245+
<row>
1246+
<entry role="catalog_table_entry"><para role="column_definition">
1247+
<structfield>xact_rollback</structfield> <type>bigint</type>
1248+
</para>
1249+
<para>
1250+
The number of transactions that have been rolled back.
1251+
</para></entry>
1252+
</row>
1253+
1254+
<row>
1255+
<entry role="catalog_table_entry"><para role="column_definition">
1256+
<structfield>stats_reset</structfield> <type>timestamp with time zone</type>
1257+
</para>
1258+
<para>
1259+
Time at which these statistics were last reset
1260+
</para></entry>
1261+
</row>
1262+
</tbody>
1263+
</tgroup>
1264+
</table>
1265+
1266+
<note>
1267+
<para>
1268+
The view does not return statistics for the checkpointer,
1269+
the background writer, the startup process and the autovacuum launcher.
1270+
</para>
1271+
</note>
1272+
</sect2>
1273+
11751274
<sect2 id="monitoring-pg-stat-replication-view">
11761275
<title><structname>pg_stat_replication</structname></title>
11771276

@@ -4990,6 +5089,22 @@ description | Waiting for a newly initialized WAL file to reach durable storage
49905089
</para></entry>
49915090
</row>
49925091

5092+
<row>
5093+
<entry role="func_table_entry"><para role="func_signature">
5094+
<indexterm>
5095+
<primary>pg_stat_get_backend_transactions</primary>
5096+
</indexterm>
5097+
<function>pg_stat_get_backend_transactions</function> ( <type>integer</type> )
5098+
<returnvalue>setof record</returnvalue>
5099+
</para>
5100+
<para>
5101+
Returns a record of transaction statistics about the backend with the
5102+
specified process ID, or one record for each active backend in the system
5103+
if <literal>NULL</literal> is specified. The fields returned are a
5104+
subset of those in the <structname>pg_stat_backend_transaction</structname> view.
5105+
</para></entry>
5106+
</row>
5107+
49935108
<row>
49945109
<entry id="pg-stat-get-backend-wal" role="func_table_entry"><para role="func_signature">
49955110
<indexterm>

src/backend/access/transam/varsup.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "storage/pmsignal.h"
2525
#include "storage/proc.h"
2626
#include "utils/lsyscache.h"
27+
#include "utils/pgstat_internal.h"
2728
#include "utils/syscache.h"
2829

2930

@@ -257,6 +258,9 @@ GetNewTransactionId(bool isSubXact)
257258
/* LWLockRelease acts as barrier */
258259
MyProc->xid = xid;
259260
ProcGlobal->xids[MyProc->pgxactoff] = xid;
261+
PendingBackendStats.pending_xid_count++;
262+
backend_has_xactstats = true;
263+
pgstat_report_fixed = true;
260264
}
261265
else
262266
{

src/backend/catalog/system_views.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,15 @@ CREATE VIEW pg_stat_activity AS
925925
LEFT JOIN pg_database AS D ON (S.datid = D.oid)
926926
LEFT JOIN pg_authid AS U ON (S.usesysid = U.oid);
927927

928+
CREATE VIEW pg_stat_backend_transaction AS
929+
SELECT
930+
S.pid,
931+
S.xid_count,
932+
S.xact_commit,
933+
S.xact_rollback,
934+
S.stats_reset
935+
FROM pg_stat_get_backend_transactions(NULL) AS S;
936+
928937
CREATE VIEW pg_stat_replication AS
929938
SELECT
930939
S.pid,

src/backend/utils/activity/pgstat_backend.c

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* reported within critical sections so we use static memory in order to avoid
3838
* memory allocation.
3939
*/
40-
static PgStat_BackendPending PendingBackendStats;
40+
PgStat_BackendPending PendingBackendStats;
4141
static bool backend_has_iostats = false;
4242

4343
/*
@@ -48,6 +48,11 @@ static bool backend_has_iostats = false;
4848
*/
4949
static WalUsage prevBackendWalUsage;
5050

51+
/*
52+
* For backend commit and rollback statistics.
53+
*/
54+
bool backend_has_xactstats = false;
55+
5156
/*
5257
* Utility routines to report I/O stats for backends, kept here to avoid
5358
* exposing PendingBackendStats to the outside world.
@@ -261,6 +266,36 @@ pgstat_flush_backend_entry_wal(PgStat_EntryRef *entry_ref)
261266
prevBackendWalUsage = pgWalUsage;
262267
}
263268

269+
/*
270+
* Flush out locally pending backend transaction statistics. Locking is managed
271+
* by the caller.
272+
*/
273+
static void
274+
pgstat_flush_backend_entry_xact(PgStat_EntryRef *entry_ref)
275+
{
276+
PgStatShared_Backend *shbackendent;
277+
278+
/*
279+
* This function can be called even if nothing at all has happened for
280+
* transaction statistics. In this case, avoid unnecessarily modifying
281+
* the stats entry.
282+
*/
283+
if (!backend_has_xactstats)
284+
return;
285+
286+
shbackendent = (PgStatShared_Backend *) entry_ref->shared_stats;
287+
288+
shbackendent->stats.xact_commit += PendingBackendStats.pending_xact_commit;
289+
shbackendent->stats.xact_rollback += PendingBackendStats.pending_xact_rollback;
290+
shbackendent->stats.xid_count += PendingBackendStats.pending_xid_count;
291+
292+
PendingBackendStats.pending_xact_commit = 0;
293+
PendingBackendStats.pending_xact_rollback = 0;
294+
PendingBackendStats.pending_xid_count = 0;
295+
296+
backend_has_xactstats = false;
297+
}
298+
264299
/*
265300
* Flush out locally pending backend statistics
266301
*
@@ -285,6 +320,10 @@ pgstat_flush_backend(bool nowait, bits32 flags)
285320
pgstat_backend_wal_have_pending())
286321
has_pending_data = true;
287322

323+
/* Some transaction data pending? */
324+
if ((flags & PGSTAT_BACKEND_FLUSH_XACT) && backend_has_xactstats)
325+
has_pending_data = true;
326+
288327
if (!has_pending_data)
289328
return false;
290329

@@ -300,6 +339,9 @@ pgstat_flush_backend(bool nowait, bits32 flags)
300339
if (flags & PGSTAT_BACKEND_FLUSH_WAL)
301340
pgstat_flush_backend_entry_wal(entry_ref);
302341

342+
if (flags & PGSTAT_BACKEND_FLUSH_XACT)
343+
pgstat_flush_backend_entry_xact(entry_ref);
344+
303345
pgstat_unlock_entry(entry_ref);
304346

305347
return false;

src/backend/utils/activity/pgstat_database.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,13 @@ pgstat_update_dbstats(TimestampTz ts)
342342
dbentry->blk_read_time += pgStatBlockReadTime;
343343
dbentry->blk_write_time += pgStatBlockWriteTime;
344344

345+
/* Do the same for backend stats */
346+
PendingBackendStats.pending_xact_commit += pgStatXactCommit;
347+
PendingBackendStats.pending_xact_rollback += pgStatXactRollback;
348+
349+
backend_has_xactstats = true;
350+
pgstat_report_fixed = true;
351+
345352
if (pgstat_should_report_connstat())
346353
{
347354
long secs;

src/backend/utils/adt/pgstatfuncs.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,63 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
706706
return (Datum) 0;
707707
}
708708

709+
/*
710+
* Returns statistics of PG backends.
711+
*/
712+
Datum
713+
pg_stat_get_backend_transactions(PG_FUNCTION_ARGS)
714+
{
715+
#define PG_STAT_GET_BACKEND_STATS_COLS 5
716+
int num_backends = pgstat_fetch_stat_numbackends();
717+
int curr_backend;
718+
int pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0);
719+
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
720+
721+
InitMaterializedSRF(fcinfo, 0);
722+
723+
/* 1-based index */
724+
for (curr_backend = 1; curr_backend <= num_backends; curr_backend++)
725+
{
726+
/* for each row */
727+
Datum values[PG_STAT_GET_BACKEND_STATS_COLS] = {0};
728+
bool nulls[PG_STAT_GET_BACKEND_STATS_COLS] = {0};
729+
LocalPgBackendStatus *local_beentry;
730+
PgBackendStatus *beentry;
731+
PgStat_Backend *backend_stats;
732+
733+
/* Get the next one in the list */
734+
local_beentry = pgstat_get_local_beentry_by_index(curr_backend);
735+
beentry = &local_beentry->backendStatus;
736+
737+
/* If looking for specific PID, ignore all the others */
738+
if (pid != -1 && beentry->st_procpid != pid)
739+
continue;
740+
741+
backend_stats = pgstat_fetch_stat_backend_by_pid(beentry->st_procpid, NULL);
742+
743+
values[0] = Int32GetDatum(beentry->st_procpid);
744+
745+
if (!backend_stats)
746+
continue;
747+
748+
values[1] = Int64GetDatum(backend_stats->xid_count);
749+
values[2] = Int64GetDatum(backend_stats->xact_commit);
750+
values[3] = Int64GetDatum(backend_stats->xact_rollback);
751+
752+
if (backend_stats->stat_reset_timestamp != 0)
753+
values[4] = TimestampTzGetDatum(backend_stats->stat_reset_timestamp);
754+
else
755+
nulls[4] = true;
756+
757+
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
758+
759+
/* If only a single backend was requested, and we found it, break. */
760+
if (pid != -1)
761+
break;
762+
}
763+
764+
return (Datum) 0;
765+
}
709766

710767
Datum
711768
pg_backend_pid(PG_FUNCTION_ARGS)

src/include/catalog/pg_proc.dat

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5657,6 +5657,15 @@
56575657
proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
56585658
proargnames => '{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,backend_type,ssl,sslversion,sslcipher,sslbits,ssl_client_dn,ssl_client_serial,ssl_issuer_dn,gss_auth,gss_princ,gss_enc,gss_delegation,leader_pid,query_id}',
56595659
prosrc => 'pg_stat_get_activity' },
5660+
{ oid => '9555',
5661+
descr => 'statistics: statistics about currently active backends',
5662+
proname => 'pg_stat_get_backend_transactions', prorows => '100', proisstrict => 'f',
5663+
proretset => 't', provolatile => 's', proparallel => 'r',
5664+
prorettype => 'record', proargtypes => 'int4',
5665+
proallargtypes => '{int4,int4,int8,int8,int8,timestamptz}',
5666+
proargmodes => '{i,o,o,o,o,o}',
5667+
proargnames => '{pid,pid,xid_count,xact_commit,xact_rollback,stats_reset}',
5668+
prosrc => 'pg_stat_get_backend_transactions' },
56605669
{ oid => '6318', descr => 'describe wait events',
56615670
proname => 'pg_get_wait_events', procost => '10', prorows => '250',
56625671
proretset => 't', provolatile => 'v', prorettype => 'record',

src/include/pgstat.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,9 @@ typedef struct PgStat_Backend
496496
TimestampTz stat_reset_timestamp;
497497
PgStat_BktypeIO io_stats;
498498
PgStat_WalCounters wal_counters;
499+
PgStat_Counter xact_commit;
500+
PgStat_Counter xact_rollback;
501+
PgStat_Counter xid_count;
499502
} PgStat_Backend;
500503

501504
/* ---------
@@ -508,6 +511,13 @@ typedef struct PgStat_BackendPending
508511
* Backend statistics store the same amount of IO data as PGSTAT_KIND_IO.
509512
*/
510513
PgStat_PendingIO pending_io;
514+
515+
/*
516+
* Transaction statistics pending flush.
517+
*/
518+
PgStat_Counter pending_xact_commit;
519+
PgStat_Counter pending_xact_rollback;
520+
PgStat_Counter pending_xid_count;
511521
} PgStat_BackendPending;
512522

513523
/*
@@ -807,6 +817,13 @@ extern PGDLLIMPORT int pgstat_track_functions;
807817
extern PGDLLIMPORT int pgstat_fetch_consistency;
808818

809819

820+
/*
821+
* Variables in pgstat_backend.c
822+
*/
823+
824+
extern PGDLLIMPORT PgStat_BackendPending PendingBackendStats;
825+
extern PGDLLIMPORT bool backend_has_xactstats;
826+
810827
/*
811828
* Variables in pgstat_bgwriter.c
812829
*/

src/include/utils/pgstat_internal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,8 @@ extern void pgstat_archiver_snapshot_cb(void);
647647
/* flags for pgstat_flush_backend() */
648648
#define PGSTAT_BACKEND_FLUSH_IO (1 << 0) /* Flush I/O statistics */
649649
#define PGSTAT_BACKEND_FLUSH_WAL (1 << 1) /* Flush WAL statistics */
650-
#define PGSTAT_BACKEND_FLUSH_ALL (PGSTAT_BACKEND_FLUSH_IO | PGSTAT_BACKEND_FLUSH_WAL)
650+
#define PGSTAT_BACKEND_FLUSH_XACT (1 << 2) /* Flush xact statistics */
651+
#define PGSTAT_BACKEND_FLUSH_ALL (PGSTAT_BACKEND_FLUSH_IO | PGSTAT_BACKEND_FLUSH_WAL | PGSTAT_BACKEND_FLUSH_XACT)
651652

652653
extern bool pgstat_flush_backend(bool nowait, bits32 flags);
653654
extern bool pgstat_backend_flush_cb(bool nowait);

0 commit comments

Comments
 (0)