@@ -246,6 +246,7 @@ static int pgStatXactCommit = 0;
246
246
static int pgStatXactRollback = 0 ;
247
247
PgStat_Counter pgStatBlockReadTime = 0 ;
248
248
PgStat_Counter pgStatBlockWriteTime = 0 ;
249
+ static PgStat_Counter pgLastSessionReportTime = 0 ;
249
250
PgStat_Counter pgStatActiveTime = 0 ;
250
251
PgStat_Counter pgStatTransactionIdleTime = 0 ;
251
252
SessionEndType pgStatSessionEndCause = DISCONNECT_NORMAL ;
@@ -330,11 +331,12 @@ static bool pgstat_db_requested(Oid databaseid);
330
331
static PgStat_StatReplSlotEntry * pgstat_get_replslot_entry (NameData name , bool create_it );
331
332
static void pgstat_reset_replslot (PgStat_StatReplSlotEntry * slotstats , TimestampTz ts );
332
333
333
- static void pgstat_send_tabstat (PgStat_MsgTabstat * tsmsg );
334
+ static void pgstat_send_tabstat (PgStat_MsgTabstat * tsmsg , TimestampTz now );
334
335
static void pgstat_send_funcstats (void );
335
336
static void pgstat_send_slru (void );
336
337
static HTAB * pgstat_collect_oids (Oid catalogid , AttrNumber anum_oid );
337
- static void pgstat_send_connstats (bool disconnect , TimestampTz last_report );
338
+ static bool pgstat_should_report_connstat (void );
339
+ static void pgstat_report_disconnect (Oid dboid );
338
340
339
341
static PgStat_TableStatus * get_tabstat_entry (Oid rel_id , bool isshared );
340
342
@@ -366,7 +368,8 @@ static void pgstat_recv_funcpurge(PgStat_MsgFuncpurge *msg, int len);
366
368
static void pgstat_recv_recoveryconflict (PgStat_MsgRecoveryConflict * msg , int len );
367
369
static void pgstat_recv_deadlock (PgStat_MsgDeadlock * msg , int len );
368
370
static void pgstat_recv_checksum_failure (PgStat_MsgChecksumFailure * msg , int len );
369
- static void pgstat_recv_connstat (PgStat_MsgConn * msg , int len );
371
+ static void pgstat_recv_connect (PgStat_MsgConnect * msg , int len );
372
+ static void pgstat_recv_disconnect (PgStat_MsgDisconnect * msg , int len );
370
373
static void pgstat_recv_replslot (PgStat_MsgReplSlot * msg , int len );
371
374
static void pgstat_recv_tempfile (PgStat_MsgTempFile * msg , int len );
372
375
@@ -890,12 +893,11 @@ pgstat_report_stat(bool disconnect)
890
893
!TimestampDifferenceExceeds (last_report , now , PGSTAT_STAT_INTERVAL ))
891
894
return ;
892
895
893
- /* for backends, send connection statistics */
894
- if (MyBackendType == B_BACKEND )
895
- pgstat_send_connstats (disconnect , last_report );
896
-
897
896
last_report = now ;
898
897
898
+ if (disconnect )
899
+ pgstat_report_disconnect (MyDatabaseId );
900
+
899
901
/*
900
902
* Destroy pgStatTabHash before we start invalidating PgStat_TableEntry
901
903
* entries it points to. (Should we fail partway through the loop below,
@@ -947,7 +949,7 @@ pgstat_report_stat(bool disconnect)
947
949
sizeof (PgStat_TableCounts ));
948
950
if (++ this_msg -> m_nentries >= PGSTAT_NUM_TABENTRIES )
949
951
{
950
- pgstat_send_tabstat (this_msg );
952
+ pgstat_send_tabstat (this_msg , now );
951
953
this_msg -> m_nentries = 0 ;
952
954
}
953
955
}
@@ -959,13 +961,14 @@ pgstat_report_stat(bool disconnect)
959
961
960
962
/*
961
963
* Send partial messages. Make sure that any pending xact commit/abort
962
- * gets counted, even if there are no table stats to send.
964
+ * and connection stats get counted, even if there are no table stats to
965
+ * send.
963
966
*/
964
967
if (regular_msg .m_nentries > 0 ||
965
- pgStatXactCommit > 0 || pgStatXactRollback > 0 )
966
- pgstat_send_tabstat (& regular_msg );
968
+ pgStatXactCommit > 0 || pgStatXactRollback > 0 || disconnect )
969
+ pgstat_send_tabstat (& regular_msg , now );
967
970
if (shared_msg .m_nentries > 0 )
968
- pgstat_send_tabstat (& shared_msg );
971
+ pgstat_send_tabstat (& shared_msg , now );
969
972
970
973
/* Now, send function statistics */
971
974
pgstat_send_funcstats ();
@@ -981,7 +984,7 @@ pgstat_report_stat(bool disconnect)
981
984
* Subroutine for pgstat_report_stat: finish and send a tabstat message
982
985
*/
983
986
static void
984
- pgstat_send_tabstat (PgStat_MsgTabstat * tsmsg )
987
+ pgstat_send_tabstat (PgStat_MsgTabstat * tsmsg , TimestampTz now )
985
988
{
986
989
int n ;
987
990
int len ;
@@ -1000,17 +1003,44 @@ pgstat_send_tabstat(PgStat_MsgTabstat *tsmsg)
1000
1003
tsmsg -> m_xact_rollback = pgStatXactRollback ;
1001
1004
tsmsg -> m_block_read_time = pgStatBlockReadTime ;
1002
1005
tsmsg -> m_block_write_time = pgStatBlockWriteTime ;
1006
+
1007
+ if (pgstat_should_report_connstat ())
1008
+ {
1009
+ long secs ;
1010
+ int usecs ;
1011
+
1012
+ /*
1013
+ * pgLastSessionReportTime is initialized to MyStartTimestamp by
1014
+ * pgstat_report_connect().
1015
+ */
1016
+ TimestampDifference (pgLastSessionReportTime , now , & secs , & usecs );
1017
+ pgLastSessionReportTime = now ;
1018
+ tsmsg -> m_session_time = (PgStat_Counter ) secs * 1000000 + usecs ;
1019
+ tsmsg -> m_active_time = pgStatActiveTime ;
1020
+ tsmsg -> m_idle_in_xact_time = pgStatTransactionIdleTime ;
1021
+ }
1022
+ else
1023
+ {
1024
+ tsmsg -> m_session_time = 0 ;
1025
+ tsmsg -> m_active_time = 0 ;
1026
+ tsmsg -> m_idle_in_xact_time = 0 ;
1027
+ }
1003
1028
pgStatXactCommit = 0 ;
1004
1029
pgStatXactRollback = 0 ;
1005
1030
pgStatBlockReadTime = 0 ;
1006
1031
pgStatBlockWriteTime = 0 ;
1032
+ pgStatActiveTime = 0 ;
1033
+ pgStatTransactionIdleTime = 0 ;
1007
1034
}
1008
1035
else
1009
1036
{
1010
1037
tsmsg -> m_xact_commit = 0 ;
1011
1038
tsmsg -> m_xact_rollback = 0 ;
1012
1039
tsmsg -> m_block_read_time = 0 ;
1013
1040
tsmsg -> m_block_write_time = 0 ;
1041
+ tsmsg -> m_session_time = 0 ;
1042
+ tsmsg -> m_active_time = 0 ;
1043
+ tsmsg -> m_idle_in_xact_time = 0 ;
1014
1044
}
1015
1045
1016
1046
n = tsmsg -> m_nentries ;
@@ -1378,49 +1408,6 @@ pgstat_drop_relation(Oid relid)
1378
1408
}
1379
1409
#endif /* NOT_USED */
1380
1410
1381
-
1382
- /* ----------
1383
- * pgstat_send_connstats() -
1384
- *
1385
- * Tell the collector about session statistics.
1386
- * The parameter "disconnect" will be true when the backend exits.
1387
- * "last_report" is the last time we were called (0 if never).
1388
- * ----------
1389
- */
1390
- static void
1391
- pgstat_send_connstats (bool disconnect , TimestampTz last_report )
1392
- {
1393
- PgStat_MsgConn msg ;
1394
- long secs ;
1395
- int usecs ;
1396
-
1397
- if (pgStatSock == PGINVALID_SOCKET || !pgstat_track_counts )
1398
- return ;
1399
-
1400
- pgstat_setheader (& msg .m_hdr , PGSTAT_MTYPE_CONNECTION );
1401
- msg .m_databaseid = MyDatabaseId ;
1402
-
1403
- /* session time since the last report */
1404
- TimestampDifference (((last_report == 0 ) ? MyStartTimestamp : last_report ),
1405
- GetCurrentTimestamp (),
1406
- & secs , & usecs );
1407
- msg .m_session_time = secs * 1000000 + usecs ;
1408
-
1409
- msg .m_disconnect = disconnect ? pgStatSessionEndCause : DISCONNECT_NOT_YET ;
1410
-
1411
- msg .m_active_time = pgStatActiveTime ;
1412
- pgStatActiveTime = 0 ;
1413
-
1414
- msg .m_idle_in_xact_time = pgStatTransactionIdleTime ;
1415
- pgStatTransactionIdleTime = 0 ;
1416
-
1417
- /* report a new session only the first time */
1418
- msg .m_count = (last_report == 0 ) ? 1 : 0 ;
1419
-
1420
- pgstat_send (& msg , sizeof (PgStat_MsgConn ));
1421
- }
1422
-
1423
-
1424
1411
/* ----------
1425
1412
* pgstat_reset_counters() -
1426
1413
*
@@ -1759,6 +1746,63 @@ pgstat_report_tempfile(size_t filesize)
1759
1746
pgstat_send (& msg , sizeof (msg ));
1760
1747
}
1761
1748
1749
+ /* --------
1750
+ * pgstat_report_connect() -
1751
+ *
1752
+ * Tell the collector about a new connection.
1753
+ * --------
1754
+ */
1755
+ void
1756
+ pgstat_report_connect (Oid dboid )
1757
+ {
1758
+ PgStat_MsgConnect msg ;
1759
+
1760
+ if (!pgstat_should_report_connstat ())
1761
+ return ;
1762
+
1763
+ pgLastSessionReportTime = MyStartTimestamp ;
1764
+
1765
+ pgstat_setheader (& msg .m_hdr , PGSTAT_MTYPE_CONNECT );
1766
+ msg .m_databaseid = MyDatabaseId ;
1767
+ pgstat_send (& msg , sizeof (PgStat_MsgConnect ));
1768
+ }
1769
+
1770
+ /* --------
1771
+ * pgstat_report_disconnect() -
1772
+ *
1773
+ * Tell the collector about a disconnect.
1774
+ * --------
1775
+ */
1776
+ static void
1777
+ pgstat_report_disconnect (Oid dboid )
1778
+ {
1779
+ PgStat_MsgDisconnect msg ;
1780
+
1781
+ if (!pgstat_should_report_connstat ())
1782
+ return ;
1783
+
1784
+ pgstat_setheader (& msg .m_hdr , PGSTAT_MTYPE_DISCONNECT );
1785
+ msg .m_databaseid = MyDatabaseId ;
1786
+ msg .m_cause = pgStatSessionEndCause ;
1787
+ pgstat_send (& msg , sizeof (PgStat_MsgDisconnect ));
1788
+ }
1789
+
1790
+ /* --------
1791
+ * pgstat_should_report_connstats() -
1792
+ *
1793
+ * We report session statistics only for normal backend processes. Parallel
1794
+ * workers run in parallel, so they don't contribute to session times, even
1795
+ * though they use CPU time. Walsender processes could be considered here,
1796
+ * but they have different session characteristics from normal backends (for
1797
+ * example, they are always "active"), so they would skew session statistics.
1798
+ * ----------
1799
+ */
1800
+ static bool
1801
+ pgstat_should_report_connstat (void )
1802
+ {
1803
+ return MyBackendType == B_BACKEND ;
1804
+ }
1805
+
1762
1806
/* ----------
1763
1807
* pgstat_report_replslot() -
1764
1808
*
@@ -3465,8 +3509,12 @@ PgstatCollectorMain(int argc, char *argv[])
3465
3509
pgstat_recv_replslot (& msg .msg_replslot , len );
3466
3510
break ;
3467
3511
3468
- case PGSTAT_MTYPE_CONNECTION :
3469
- pgstat_recv_connstat (& msg .msg_conn , len );
3512
+ case PGSTAT_MTYPE_CONNECT :
3513
+ pgstat_recv_connect (& msg .msg_connect , len );
3514
+ break ;
3515
+
3516
+ case PGSTAT_MTYPE_DISCONNECT :
3517
+ pgstat_recv_disconnect (& msg .msg_disconnect , len );
3470
3518
break ;
3471
3519
3472
3520
default :
@@ -4904,6 +4952,10 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len)
4904
4952
dbentry -> n_block_read_time += msg -> m_block_read_time ;
4905
4953
dbentry -> n_block_write_time += msg -> m_block_write_time ;
4906
4954
4955
+ dbentry -> total_session_time += msg -> m_session_time ;
4956
+ dbentry -> total_active_time += msg -> m_active_time ;
4957
+ dbentry -> total_idle_in_xact_time += msg -> m_idle_in_xact_time ;
4958
+
4907
4959
/*
4908
4960
* Process all table entries in the message.
4909
4961
*/
@@ -5568,23 +5620,34 @@ pgstat_recv_replslot(PgStat_MsgReplSlot *msg, int len)
5568
5620
}
5569
5621
5570
5622
/* ----------
5571
- * pgstat_recv_connstat () -
5623
+ * pgstat_recv_connect () -
5572
5624
*
5573
- * Process connection information .
5625
+ * Process a CONNECT message .
5574
5626
* ----------
5575
5627
*/
5576
5628
static void
5577
- pgstat_recv_connstat ( PgStat_MsgConn * msg , int len )
5629
+ pgstat_recv_connect ( PgStat_MsgConnect * msg , int len )
5578
5630
{
5579
5631
PgStat_StatDBEntry * dbentry ;
5580
5632
5581
5633
dbentry = pgstat_get_db_entry (msg -> m_databaseid , true);
5634
+ dbentry -> n_sessions ++ ;
5635
+ }
5582
5636
5583
- dbentry -> n_sessions += msg -> m_count ;
5584
- dbentry -> total_session_time += msg -> m_session_time ;
5585
- dbentry -> total_active_time += msg -> m_active_time ;
5586
- dbentry -> total_idle_in_xact_time += msg -> m_idle_in_xact_time ;
5587
- switch (msg -> m_disconnect )
5637
+ /* ----------
5638
+ * pgstat_recv_disconnect() -
5639
+ *
5640
+ * Process a DISCONNECT message.
5641
+ * ----------
5642
+ */
5643
+ static void
5644
+ pgstat_recv_disconnect (PgStat_MsgDisconnect * msg , int len )
5645
+ {
5646
+ PgStat_StatDBEntry * dbentry ;
5647
+
5648
+ dbentry = pgstat_get_db_entry (msg -> m_databaseid , true);
5649
+
5650
+ switch (msg -> m_cause )
5588
5651
{
5589
5652
case DISCONNECT_NOT_YET :
5590
5653
case DISCONNECT_NORMAL :
0 commit comments