summaryrefslogtreecommitdiff
path: root/src/backend/postmaster/pgstat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/postmaster/pgstat.c')
-rw-r--r--src/backend/postmaster/pgstat.c195
1 files changed, 129 insertions, 66 deletions
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 3450a10129b..ab9c37c64f0 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -246,6 +246,7 @@ static int pgStatXactCommit = 0;
static int pgStatXactRollback = 0;
PgStat_Counter pgStatBlockReadTime = 0;
PgStat_Counter pgStatBlockWriteTime = 0;
+static PgStat_Counter pgLastSessionReportTime = 0;
PgStat_Counter pgStatActiveTime = 0;
PgStat_Counter pgStatTransactionIdleTime = 0;
SessionEndType pgStatSessionEndCause = DISCONNECT_NORMAL;
@@ -330,11 +331,12 @@ static bool pgstat_db_requested(Oid databaseid);
static PgStat_StatReplSlotEntry *pgstat_get_replslot_entry(NameData name, bool create_it);
static void pgstat_reset_replslot(PgStat_StatReplSlotEntry *slotstats, TimestampTz ts);
-static void pgstat_send_tabstat(PgStat_MsgTabstat *tsmsg);
+static void pgstat_send_tabstat(PgStat_MsgTabstat *tsmsg, TimestampTz now);
static void pgstat_send_funcstats(void);
static void pgstat_send_slru(void);
static HTAB *pgstat_collect_oids(Oid catalogid, AttrNumber anum_oid);
-static void pgstat_send_connstats(bool disconnect, TimestampTz last_report);
+static bool pgstat_should_report_connstat(void);
+static void pgstat_report_disconnect(Oid dboid);
static PgStat_TableStatus *get_tabstat_entry(Oid rel_id, bool isshared);
@@ -366,7 +368,8 @@ static void pgstat_recv_funcpurge(PgStat_MsgFuncpurge *msg, int len);
static void pgstat_recv_recoveryconflict(PgStat_MsgRecoveryConflict *msg, int len);
static void pgstat_recv_deadlock(PgStat_MsgDeadlock *msg, int len);
static void pgstat_recv_checksum_failure(PgStat_MsgChecksumFailure *msg, int len);
-static void pgstat_recv_connstat(PgStat_MsgConn *msg, int len);
+static void pgstat_recv_connect(PgStat_MsgConnect *msg, int len);
+static void pgstat_recv_disconnect(PgStat_MsgDisconnect *msg, int len);
static void pgstat_recv_replslot(PgStat_MsgReplSlot *msg, int len);
static void pgstat_recv_tempfile(PgStat_MsgTempFile *msg, int len);
@@ -890,12 +893,11 @@ pgstat_report_stat(bool disconnect)
!TimestampDifferenceExceeds(last_report, now, PGSTAT_STAT_INTERVAL))
return;
- /* for backends, send connection statistics */
- if (MyBackendType == B_BACKEND)
- pgstat_send_connstats(disconnect, last_report);
-
last_report = now;
+ if (disconnect)
+ pgstat_report_disconnect(MyDatabaseId);
+
/*
* Destroy pgStatTabHash before we start invalidating PgStat_TableEntry
* entries it points to. (Should we fail partway through the loop below,
@@ -947,7 +949,7 @@ pgstat_report_stat(bool disconnect)
sizeof(PgStat_TableCounts));
if (++this_msg->m_nentries >= PGSTAT_NUM_TABENTRIES)
{
- pgstat_send_tabstat(this_msg);
+ pgstat_send_tabstat(this_msg, now);
this_msg->m_nentries = 0;
}
}
@@ -959,13 +961,14 @@ pgstat_report_stat(bool disconnect)
/*
* Send partial messages. Make sure that any pending xact commit/abort
- * gets counted, even if there are no table stats to send.
+ * and connection stats get counted, even if there are no table stats to
+ * send.
*/
if (regular_msg.m_nentries > 0 ||
- pgStatXactCommit > 0 || pgStatXactRollback > 0)
- pgstat_send_tabstat(&regular_msg);
+ pgStatXactCommit > 0 || pgStatXactRollback > 0 || disconnect)
+ pgstat_send_tabstat(&regular_msg, now);
if (shared_msg.m_nentries > 0)
- pgstat_send_tabstat(&shared_msg);
+ pgstat_send_tabstat(&shared_msg, now);
/* Now, send function statistics */
pgstat_send_funcstats();
@@ -981,7 +984,7 @@ pgstat_report_stat(bool disconnect)
* Subroutine for pgstat_report_stat: finish and send a tabstat message
*/
static void
-pgstat_send_tabstat(PgStat_MsgTabstat *tsmsg)
+pgstat_send_tabstat(PgStat_MsgTabstat *tsmsg, TimestampTz now)
{
int n;
int len;
@@ -1000,10 +1003,34 @@ pgstat_send_tabstat(PgStat_MsgTabstat *tsmsg)
tsmsg->m_xact_rollback = pgStatXactRollback;
tsmsg->m_block_read_time = pgStatBlockReadTime;
tsmsg->m_block_write_time = pgStatBlockWriteTime;
+
+ if (pgstat_should_report_connstat())
+ {
+ long secs;
+ int usecs;
+
+ /*
+ * pgLastSessionReportTime is initialized to MyStartTimestamp by
+ * pgstat_report_connect().
+ */
+ TimestampDifference(pgLastSessionReportTime, now, &secs, &usecs);
+ pgLastSessionReportTime = now;
+ tsmsg->m_session_time = (PgStat_Counter) secs * 1000000 + usecs;
+ tsmsg->m_active_time = pgStatActiveTime;
+ tsmsg->m_idle_in_xact_time = pgStatTransactionIdleTime;
+ }
+ else
+ {
+ tsmsg->m_session_time = 0;
+ tsmsg->m_active_time = 0;
+ tsmsg->m_idle_in_xact_time = 0;
+ }
pgStatXactCommit = 0;
pgStatXactRollback = 0;
pgStatBlockReadTime = 0;
pgStatBlockWriteTime = 0;
+ pgStatActiveTime = 0;
+ pgStatTransactionIdleTime = 0;
}
else
{
@@ -1011,6 +1038,9 @@ pgstat_send_tabstat(PgStat_MsgTabstat *tsmsg)
tsmsg->m_xact_rollback = 0;
tsmsg->m_block_read_time = 0;
tsmsg->m_block_write_time = 0;
+ tsmsg->m_session_time = 0;
+ tsmsg->m_active_time = 0;
+ tsmsg->m_idle_in_xact_time = 0;
}
n = tsmsg->m_nentries;
@@ -1378,49 +1408,6 @@ pgstat_drop_relation(Oid relid)
}
#endif /* NOT_USED */
-
-/* ----------
- * pgstat_send_connstats() -
- *
- * Tell the collector about session statistics.
- * The parameter "disconnect" will be true when the backend exits.
- * "last_report" is the last time we were called (0 if never).
- * ----------
- */
-static void
-pgstat_send_connstats(bool disconnect, TimestampTz last_report)
-{
- PgStat_MsgConn msg;
- long secs;
- int usecs;
-
- if (pgStatSock == PGINVALID_SOCKET || !pgstat_track_counts)
- return;
-
- pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_CONNECTION);
- msg.m_databaseid = MyDatabaseId;
-
- /* session time since the last report */
- TimestampDifference(((last_report == 0) ? MyStartTimestamp : last_report),
- GetCurrentTimestamp(),
- &secs, &usecs);
- msg.m_session_time = secs * 1000000 + usecs;
-
- msg.m_disconnect = disconnect ? pgStatSessionEndCause : DISCONNECT_NOT_YET;
-
- msg.m_active_time = pgStatActiveTime;
- pgStatActiveTime = 0;
-
- msg.m_idle_in_xact_time = pgStatTransactionIdleTime;
- pgStatTransactionIdleTime = 0;
-
- /* report a new session only the first time */
- msg.m_count = (last_report == 0) ? 1 : 0;
-
- pgstat_send(&msg, sizeof(PgStat_MsgConn));
-}
-
-
/* ----------
* pgstat_reset_counters() -
*
@@ -1759,6 +1746,63 @@ pgstat_report_tempfile(size_t filesize)
pgstat_send(&msg, sizeof(msg));
}
+/* --------
+ * pgstat_report_connect() -
+ *
+ * Tell the collector about a new connection.
+ * --------
+ */
+void
+pgstat_report_connect(Oid dboid)
+{
+ PgStat_MsgConnect msg;
+
+ if (!pgstat_should_report_connstat())
+ return;
+
+ pgLastSessionReportTime = MyStartTimestamp;
+
+ pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_CONNECT);
+ msg.m_databaseid = MyDatabaseId;
+ pgstat_send(&msg, sizeof(PgStat_MsgConnect));
+}
+
+/* --------
+ * pgstat_report_disconnect() -
+ *
+ * Tell the collector about a disconnect.
+ * --------
+ */
+static void
+pgstat_report_disconnect(Oid dboid)
+{
+ PgStat_MsgDisconnect msg;
+
+ if (!pgstat_should_report_connstat())
+ return;
+
+ pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_DISCONNECT);
+ msg.m_databaseid = MyDatabaseId;
+ msg.m_cause = pgStatSessionEndCause;
+ pgstat_send(&msg, sizeof(PgStat_MsgDisconnect));
+}
+
+/* --------
+ * pgstat_should_report_connstats() -
+ *
+ * We report session statistics only for normal backend processes. Parallel
+ * workers run in parallel, so they don't contribute to session times, even
+ * though they use CPU time. Walsender processes could be considered here,
+ * but they have different session characteristics from normal backends (for
+ * example, they are always "active"), so they would skew session statistics.
+ * ----------
+ */
+static bool
+pgstat_should_report_connstat(void)
+{
+ return MyBackendType == B_BACKEND;
+}
+
/* ----------
* pgstat_report_replslot() -
*
@@ -3465,8 +3509,12 @@ PgstatCollectorMain(int argc, char *argv[])
pgstat_recv_replslot(&msg.msg_replslot, len);
break;
- case PGSTAT_MTYPE_CONNECTION:
- pgstat_recv_connstat(&msg.msg_conn, len);
+ case PGSTAT_MTYPE_CONNECT:
+ pgstat_recv_connect(&msg.msg_connect, len);
+ break;
+
+ case PGSTAT_MTYPE_DISCONNECT:
+ pgstat_recv_disconnect(&msg.msg_disconnect, len);
break;
default:
@@ -4904,6 +4952,10 @@ pgstat_recv_tabstat(PgStat_MsgTabstat *msg, int len)
dbentry->n_block_read_time += msg->m_block_read_time;
dbentry->n_block_write_time += msg->m_block_write_time;
+ dbentry->total_session_time += msg->m_session_time;
+ dbentry->total_active_time += msg->m_active_time;
+ dbentry->total_idle_in_xact_time += msg->m_idle_in_xact_time;
+
/*
* Process all table entries in the message.
*/
@@ -5568,23 +5620,34 @@ pgstat_recv_replslot(PgStat_MsgReplSlot *msg, int len)
}
/* ----------
- * pgstat_recv_connstat() -
+ * pgstat_recv_connect() -
*
- * Process connection information.
+ * Process a CONNECT message.
* ----------
*/
static void
-pgstat_recv_connstat(PgStat_MsgConn *msg, int len)
+pgstat_recv_connect(PgStat_MsgConnect *msg, int len)
{
PgStat_StatDBEntry *dbentry;
dbentry = pgstat_get_db_entry(msg->m_databaseid, true);
+ dbentry->n_sessions++;
+}
- dbentry->n_sessions += msg->m_count;
- dbentry->total_session_time += msg->m_session_time;
- dbentry->total_active_time += msg->m_active_time;
- dbentry->total_idle_in_xact_time += msg->m_idle_in_xact_time;
- switch (msg->m_disconnect)
+/* ----------
+ * pgstat_recv_disconnect() -
+ *
+ * Process a DISCONNECT message.
+ * ----------
+ */
+static void
+pgstat_recv_disconnect(PgStat_MsgDisconnect *msg, int len)
+{
+ PgStat_StatDBEntry *dbentry;
+
+ dbentry = pgstat_get_db_entry(msg->m_databaseid, true);
+
+ switch (msg->m_cause)
{
case DISCONNECT_NOT_YET:
case DISCONNECT_NORMAL: