1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-22 12:22:45 +03:00

pgstat: split different types of stats into separate files.

pgstat.c is very long, and it's hard to find an order that makes sense and is
likely to be maintained over time. Splitting the different pieces into
separate files makes that a lot easier.

With a few exceptions, this commit just moves code around. Those exceptions
are:
- adding file headers for new files
- removing 'static' from functions
- adapting pgstat_assert_is_up() to work across TUs
- minor comment adjustments
git diff --color-moved=dimmed-zebra is very helpful separating code movement
from code changes.

The next commit in this series will reorder pgstat.[ch] contents to be a bit
more coherent.

Earlier revisions of this patch had "global" statistics (archiver, bgwriter,
checkpointer, replication slots, SLRU, WAL) in one file, because each seemed
small enough. However later commits will increase their size and their
aggregate size is not insubstantial. It also just seems easier to split each
type of statistic into its own file.

Author: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/20220303021600.hs34ghqcw6zcokdh@alap3.anarazel.de
This commit is contained in:
Andres Freund
2022-03-21 12:02:25 -07:00
parent cb02fcb4c9
commit 13619598f1
13 changed files with 2371 additions and 2003 deletions

View File

@@ -0,0 +1,279 @@
/* -------------------------------------------------------------------------
*
* pgstat_database.c
* Implementation of database statistics.
*
* This file contains the implementation of database statistics. It is kept
* separate from pgstat.c to enforce the line between the statistics access /
* storage implementation and the details about individual types of
* statistics.
*
* Copyright (c) 2001-2022, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/backend/utils/activity/pgstat_database.c
* -------------------------------------------------------------------------
*/
#include "postgres.h"
#include "utils/pgstat_internal.h"
#include "utils/timestamp.h"
static bool pgstat_should_report_connstat(void);
int pgStatXactCommit = 0;
int pgStatXactRollback = 0;
PgStat_Counter pgStatBlockReadTime = 0;
PgStat_Counter pgStatBlockWriteTime = 0;
PgStat_Counter pgStatActiveTime = 0;
PgStat_Counter pgStatTransactionIdleTime = 0;
SessionEndType pgStatSessionEndCause = DISCONNECT_NORMAL;
static PgStat_Counter pgLastSessionReportTime = 0;
/* ----------
* pgstat_drop_database() -
*
* Tell the collector that we just dropped a database.
* (If the message gets lost, we will still clean the dead DB eventually
* via future invocations of pgstat_vacuum_stat().)
* ----------
*/
void
pgstat_drop_database(Oid databaseid)
{
PgStat_MsgDropdb msg;
if (pgStatSock == PGINVALID_SOCKET)
return;
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_DROPDB);
msg.m_databaseid = databaseid;
pgstat_send(&msg, sizeof(msg));
}
/* --------
* pgstat_report_recovery_conflict() -
*
* Tell the collector about a Hot Standby recovery conflict.
* --------
*/
void
pgstat_report_recovery_conflict(int reason)
{
PgStat_MsgRecoveryConflict msg;
if (pgStatSock == PGINVALID_SOCKET || !pgstat_track_counts)
return;
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RECOVERYCONFLICT);
msg.m_databaseid = MyDatabaseId;
msg.m_reason = reason;
pgstat_send(&msg, sizeof(msg));
}
/* --------
* pgstat_report_deadlock() -
*
* Tell the collector about a deadlock detected.
* --------
*/
void
pgstat_report_deadlock(void)
{
PgStat_MsgDeadlock msg;
if (pgStatSock == PGINVALID_SOCKET || !pgstat_track_counts)
return;
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_DEADLOCK);
msg.m_databaseid = MyDatabaseId;
pgstat_send(&msg, sizeof(msg));
}
/* --------
* pgstat_report_checksum_failures_in_db() -
*
* Tell the collector about one or more checksum failures.
* --------
*/
void
pgstat_report_checksum_failures_in_db(Oid dboid, int failurecount)
{
PgStat_MsgChecksumFailure msg;
if (pgStatSock == PGINVALID_SOCKET || !pgstat_track_counts)
return;
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_CHECKSUMFAILURE);
msg.m_databaseid = dboid;
msg.m_failurecount = failurecount;
msg.m_failure_time = GetCurrentTimestamp();
pgstat_send(&msg, sizeof(msg));
}
/* --------
* pgstat_report_checksum_failure() -
*
* Tell the collector about a checksum failure.
* --------
*/
void
pgstat_report_checksum_failure(void)
{
pgstat_report_checksum_failures_in_db(MyDatabaseId, 1);
}
/* --------
* pgstat_report_tempfile() -
*
* Tell the collector about a temporary file.
* --------
*/
void
pgstat_report_tempfile(size_t filesize)
{
PgStat_MsgTempFile msg;
if (pgStatSock == PGINVALID_SOCKET || !pgstat_track_counts)
return;
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_TEMPFILE);
msg.m_databaseid = MyDatabaseId;
msg.m_filesize = 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.
* --------
*/
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));
}
void
AtEOXact_PgStat_Database(bool isCommit, bool parallel)
{
/* Don't count parallel worker transaction stats */
if (!parallel)
{
/*
* Count transaction commit or abort. (We use counters, not just
* bools, in case the reporting message isn't sent right away.)
*/
if (isCommit)
pgStatXactCommit++;
else
pgStatXactRollback++;
}
}
/*
* Subroutine for pgstat_send_tabstat: Handle xact commit/rollback and I/O
* timings.
*/
void
pgstat_update_dbstats(PgStat_MsgTabstat *tsmsg, TimestampTz now)
{
if (OidIsValid(tsmsg->m_databaseid))
{
tsmsg->m_xact_commit = pgStatXactCommit;
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
{
tsmsg->m_xact_commit = 0;
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;
}
}
/* --------
* 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;
}