@@ -244,6 +244,7 @@ static intpgStatXactCommit = 0;
244
244
static int pgStatXactRollback = 0 ;
245
245
PgStat_Counter pgStatBlockReadTime = 0 ;
246
246
PgStat_Counter pgStatBlockWriteTime = 0 ;
247
+ static PgStat_Counter pgLastSessionReportTime = 0 ;
247
248
PgStat_Counter pgStatActiveTime = 0 ;
248
249
PgStat_Counter pgStatTransactionIdleTime = 0 ;
249
250
SessionEndType pgStatSessionEndCause = DISCONNECT_NORMAL ;
@@ -319,11 +320,12 @@ static bool pgstat_db_requested(Oid databaseid);
319
320
static PgStat_StatReplSlotEntry * pgstat_get_replslot_entry (NameData name ,bool create_it );
320
321
static void pgstat_reset_replslot (PgStat_StatReplSlotEntry * slotstats ,TimestampTz ts );
321
322
322
- static void pgstat_send_tabstat (PgStat_MsgTabstat * tsmsg );
323
+ static void pgstat_send_tabstat (PgStat_MsgTabstat * tsmsg , TimestampTz now );
323
324
static void pgstat_send_funcstats (void );
324
325
static void pgstat_send_slru (void );
325
326
static HTAB * pgstat_collect_oids (Oid catalogid ,AttrNumber anum_oid );
326
- static void pgstat_send_connstats (bool disconnect ,TimestampTz last_report );
327
+ static bool pgstat_should_report_connstat (void );
328
+ static void pgstat_report_disconnect (Oid dboid );
327
329
328
330
static PgStat_TableStatus * get_tabstat_entry (Oid rel_id ,bool isshared );
329
331
@@ -353,7 +355,8 @@ static void pgstat_recv_funcpurge(PgStat_MsgFuncpurge *msg, int len);
353
355
static void pgstat_recv_recoveryconflict (PgStat_MsgRecoveryConflict * msg ,int len );
354
356
static void pgstat_recv_deadlock (PgStat_MsgDeadlock * msg ,int len );
355
357
static void pgstat_recv_checksum_failure (PgStat_MsgChecksumFailure * msg ,int len );
356
- static void pgstat_recv_connstat (PgStat_MsgConn * msg ,int len );
358
+ static void pgstat_recv_connect (PgStat_MsgConnect * msg ,int len );
359
+ static void pgstat_recv_disconnect (PgStat_MsgDisconnect * msg ,int len );
357
360
static void pgstat_recv_replslot (PgStat_MsgReplSlot * msg ,int len );
358
361
static void pgstat_recv_tempfile (PgStat_MsgTempFile * msg ,int len );
359
362
@@ -875,12 +878,11 @@ pgstat_report_stat(bool disconnect)
875
878
!TimestampDifferenceExceeds (last_report ,now ,PGSTAT_STAT_INTERVAL ))
876
879
return ;
877
880
878
- /* for backends, send connection statistics */
879
- if (MyBackendType == B_BACKEND )
880
- pgstat_send_connstats (disconnect ,last_report );
881
-
882
881
last_report = now ;
883
882
883
+ if (disconnect )
884
+ pgstat_report_disconnect (MyDatabaseId );
885
+
884
886
/*
885
887
* Destroy pgStatTabHash before we start invalidating PgStat_TableEntry
886
888
* entries it points to. (Should we fail partway through the loop below,
@@ -932,7 +934,7 @@ pgstat_report_stat(bool disconnect)
932
934
sizeof (PgStat_TableCounts ));
933
935
if (++ this_msg -> m_nentries >=PGSTAT_NUM_TABENTRIES )
934
936
{
935
- pgstat_send_tabstat (this_msg );
937
+ pgstat_send_tabstat (this_msg , now );
936
938
this_msg -> m_nentries = 0 ;
937
939
}
938
940
}
@@ -944,13 +946,14 @@ pgstat_report_stat(bool disconnect)
944
946
945
947
/*
946
948
* Send partial messages. Make sure that any pending xact commit/abort
947
- * gets counted, even if there are no table stats to send.
949
+ * and connection stats get counted, even if there are no table stats to
950
+ * send.
948
951
*/
949
952
if (regular_msg .m_nentries > 0 ||
950
- pgStatXactCommit > 0 || pgStatXactRollback > 0 )
951
- pgstat_send_tabstat (& regular_msg );
953
+ pgStatXactCommit > 0 || pgStatXactRollback > 0 || disconnect )
954
+ pgstat_send_tabstat (& regular_msg , now );
952
955
if (shared_msg .m_nentries > 0 )
953
- pgstat_send_tabstat (& shared_msg );
956
+ pgstat_send_tabstat (& shared_msg , now );
954
957
955
958
/* Now, send function statistics */
956
959
pgstat_send_funcstats ();
@@ -966,7 +969,7 @@ pgstat_report_stat(bool disconnect)
966
969
* Subroutine for pgstat_report_stat: finish and send a tabstat message
967
970
*/
968
971
static void
969
- pgstat_send_tabstat (PgStat_MsgTabstat * tsmsg )
972
+ pgstat_send_tabstat (PgStat_MsgTabstat * tsmsg , TimestampTz now )
970
973
{
971
974
int n ;
972
975
int len ;
@@ -985,17 +988,44 @@ pgstat_send_tabstat(PgStat_MsgTabstat *tsmsg)
985
988
tsmsg -> m_xact_rollback = pgStatXactRollback ;
986
989
tsmsg -> m_block_read_time = pgStatBlockReadTime ;
987
990
tsmsg -> m_block_write_time = pgStatBlockWriteTime ;
991
+
992
+ if (pgstat_should_report_connstat ())
993
+ {
994
+ long secs ;
995
+ int usecs ;
996
+
997
+ /*
998
+ * pgLastSessionReportTime is initialized to MyStartTimestamp by
999
+ * pgstat_report_connect().
1000
+ */
1001
+ TimestampDifference (pgLastSessionReportTime ,now ,& secs ,& usecs );
1002
+ pgLastSessionReportTime = now ;
1003
+ tsmsg -> m_session_time = (PgStat_Counter )secs * 1000000 + usecs ;
1004
+ tsmsg -> m_active_time = pgStatActiveTime ;
1005
+ tsmsg -> m_idle_in_xact_time = pgStatTransactionIdleTime ;
1006
+ }
1007
+ else
1008
+ {
1009
+ tsmsg -> m_session_time = 0 ;
1010
+ tsmsg -> m_active_time = 0 ;
1011
+ tsmsg -> m_idle_in_xact_time = 0 ;
1012
+ }
988
1013
pgStatXactCommit = 0 ;
989
1014
pgStatXactRollback = 0 ;
990
1015
pgStatBlockReadTime = 0 ;
991
1016
pgStatBlockWriteTime = 0 ;
1017
+ pgStatActiveTime = 0 ;
1018
+ pgStatTransactionIdleTime = 0 ;
992
1019
}
993
1020
else
994
1021
{
995
1022
tsmsg -> m_xact_commit = 0 ;
996
1023
tsmsg -> m_xact_rollback = 0 ;
997
1024
tsmsg -> m_block_read_time = 0 ;
998
1025
tsmsg -> m_block_write_time = 0 ;
1026
+ tsmsg -> m_session_time = 0 ;
1027
+ tsmsg -> m_active_time = 0 ;
1028
+ tsmsg -> m_idle_in_xact_time = 0 ;
999
1029
}
1000
1030
1001
1031
n = tsmsg -> m_nentries ;
@@ -1363,49 +1393,6 @@ pgstat_drop_relation(Oid relid)
1363
1393
}
1364
1394
#endif /* NOT_USED */
1365
1395
1366
-
1367
- /* ----------
1368
- * pgstat_send_connstats() -
1369
- *
1370
- *Tell the collector about session statistics.
1371
- *The parameter "disconnect" will be true when the backend exits.
1372
- *"last_report" is the last time we were called (0 if never).
1373
- * ----------
1374
- */
1375
- static void
1376
- pgstat_send_connstats (bool disconnect ,TimestampTz last_report )
1377
- {
1378
- PgStat_MsgConn msg ;
1379
- long secs ;
1380
- int usecs ;
1381
-
1382
- if (pgStatSock == PGINVALID_SOCKET || !pgstat_track_counts )
1383
- return ;
1384
-
1385
- pgstat_setheader (& msg .m_hdr ,PGSTAT_MTYPE_CONNECTION );
1386
- msg .m_databaseid = MyDatabaseId ;
1387
-
1388
- /* session time since the last report */
1389
- TimestampDifference (((last_report == 0 ) ?MyStartTimestamp :last_report ),
1390
- GetCurrentTimestamp (),
1391
- & secs ,& usecs );
1392
- msg .m_session_time = secs * 1000000 + usecs ;
1393
-
1394
- msg .m_disconnect = disconnect ?pgStatSessionEndCause :DISCONNECT_NOT_YET ;
1395
-
1396
- msg .m_active_time = pgStatActiveTime ;
1397
- pgStatActiveTime = 0 ;
1398
-
1399
- msg .m_idle_in_xact_time = pgStatTransactionIdleTime ;
1400
- pgStatTransactionIdleTime = 0 ;
1401
-
1402
- /* report a new session only the first time */
1403
- msg .m_count = (last_report == 0 ) ?1 :0 ;
1404
-
1405
- pgstat_send (& msg ,sizeof (PgStat_MsgConn ));
1406
- }
1407
-
1408
-
1409
1396
/* ----------
1410
1397
* pgstat_reset_counters() -
1411
1398
*
@@ -1744,6 +1731,63 @@ pgstat_report_tempfile(size_t filesize)
1744
1731
pgstat_send (& msg ,sizeof (msg ));
1745
1732
}
1746
1733
1734
+ /* --------
1735
+ * pgstat_report_connect() -
1736
+ *
1737
+ *Tell the collector about a new connection.
1738
+ * --------
1739
+ */
1740
+ void
1741
+ pgstat_report_connect (Oid dboid )
1742
+ {
1743
+ PgStat_MsgConnect msg ;
1744
+
1745
+ if (!pgstat_should_report_connstat ())
1746
+ return ;
1747
+
1748
+ pgLastSessionReportTime = MyStartTimestamp ;
1749
+
1750
+ pgstat_setheader (& msg .m_hdr ,PGSTAT_MTYPE_CONNECT );
1751
+ msg .m_databaseid = MyDatabaseId ;
1752
+ pgstat_send (& msg ,sizeof (PgStat_MsgConnect ));
1753
+ }
1754
+
1755
+ /* --------
1756
+ * pgstat_report_disconnect() -
1757
+ *
1758
+ *Tell the collector about a disconnect.
1759
+ * --------
1760
+ */
1761
+ static void
1762
+ pgstat_report_disconnect (Oid dboid )
1763
+ {
1764
+ PgStat_MsgDisconnect msg ;
1765
+
1766
+ if (!pgstat_should_report_connstat ())
1767
+ return ;
1768
+
1769
+ pgstat_setheader (& msg .m_hdr ,PGSTAT_MTYPE_DISCONNECT );
1770
+ msg .m_databaseid = MyDatabaseId ;
1771
+ msg .m_cause = pgStatSessionEndCause ;
1772
+ pgstat_send (& msg ,sizeof (PgStat_MsgDisconnect ));
1773
+ }
1774
+
1775
+ /* --------
1776
+ * pgstat_should_report_connstats() -
1777
+ *
1778
+ *We report session statistics only for normal backend processes. Parallel
1779
+ *workers run in parallel, so they don't contribute to session times, even
1780
+ *though they use CPU time. Walsender processes could be considered here,
1781
+ *but they have different session characteristics from normal backends (for
1782
+ *example, they are always "active"), so they would skew session statistics.
1783
+ * ----------
1784
+ */
1785
+ static bool
1786
+ pgstat_should_report_connstat (void )
1787
+ {
1788
+ return MyBackendType == B_BACKEND ;
1789
+ }
1790
+
1747
1791
/* ----------
1748
1792
* pgstat_report_replslot() -
1749
1793
*
@@ -3363,8 +3407,12 @@ PgstatCollectorMain(int argc, char *argv[])
3363
3407
pgstat_recv_replslot (& msg .msg_replslot ,len );
3364
3408
break ;
3365
3409
3366
- case PGSTAT_MTYPE_CONNECTION :
3367
- pgstat_recv_connstat (& msg .msg_conn ,len );
3410
+ case PGSTAT_MTYPE_CONNECT :
3411
+ pgstat_recv_connect (& msg .msg_connect ,len );
3412
+ break ;
3413
+
3414
+ case PGSTAT_MTYPE_DISCONNECT :
3415
+ pgstat_recv_disconnect (& msg .msg_disconnect ,len );
3368
3416
break ;
3369
3417
3370
3418
default :
@@ -4785,6 +4833,10 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len)
4785
4833
dbentry -> n_block_read_time += msg -> m_block_read_time ;
4786
4834
dbentry -> n_block_write_time += msg -> m_block_write_time ;
4787
4835
4836
+ dbentry -> total_session_time += msg -> m_session_time ;
4837
+ dbentry -> total_active_time += msg -> m_active_time ;
4838
+ dbentry -> total_idle_in_xact_time += msg -> m_idle_in_xact_time ;
4839
+
4788
4840
/*
4789
4841
* Process all table entries in the message.
4790
4842
*/
@@ -5434,23 +5486,34 @@ pgstat_recv_replslot(PgStat_MsgReplSlot *msg, int len)
5434
5486
}
5435
5487
5436
5488
/* ----------
5437
- *pgstat_recv_connstat () -
5489
+ *pgstat_recv_connect () -
5438
5490
*
5439
- * Processconnection information .
5491
+ * Processa CONNECT message .
5440
5492
* ----------
5441
5493
*/
5442
5494
static void
5443
- pgstat_recv_connstat ( PgStat_MsgConn * msg ,int len )
5495
+ pgstat_recv_connect ( PgStat_MsgConnect * msg ,int len )
5444
5496
{
5445
5497
PgStat_StatDBEntry * dbentry ;
5446
5498
5447
5499
dbentry = pgstat_get_db_entry (msg -> m_databaseid , true);
5500
+ dbentry -> n_sessions ++ ;
5501
+ }
5448
5502
5449
- dbentry -> n_sessions += msg -> m_count ;
5450
- dbentry -> total_session_time += msg -> m_session_time ;
5451
- dbentry -> total_active_time += msg -> m_active_time ;
5452
- dbentry -> total_idle_in_xact_time += msg -> m_idle_in_xact_time ;
5453
- switch (msg -> m_disconnect )
5503
+ /* ----------
5504
+ * pgstat_recv_disconnect() -
5505
+ *
5506
+ *Process a DISCONNECT message.
5507
+ * ----------
5508
+ */
5509
+ static void
5510
+ pgstat_recv_disconnect (PgStat_MsgDisconnect * msg ,int len )
5511
+ {
5512
+ PgStat_StatDBEntry * dbentry ;
5513
+
5514
+ dbentry = pgstat_get_db_entry (msg -> m_databaseid , true);
5515
+
5516
+ switch (msg -> m_cause )
5454
5517
{
5455
5518
case DISCONNECT_NOT_YET :
5456
5519
case DISCONNECT_NORMAL :