1
0
mirror of https://github.com/postgres/postgres.git synced 2025-12-01 12:18:01 +03:00

pgstat: move transactional code into pgstat_xact.c.

The transactional integration code is largely independent from the rest of
pgstat.c. Subsequent commits will add more related code.

Author: Andres Freund <andres@anarazel.de>
Reviewed-By: Thomas Munro <thomas.munro@gmail.com>
Discussion: https://postgr.es/m/20220404041516.cctrvpadhuriawlq@alap3.anarazel.de
This commit is contained in:
Andres Freund
2022-04-06 13:23:47 -07:00
parent c3e9b07936
commit ab62a642d5
5 changed files with 189 additions and 163 deletions

View File

@@ -198,8 +198,6 @@ static time_t last_pgstat_start_time;
static bool pgStatRunningInCollector = false;
static PgStat_SubXactStatus *pgStatXactStack = NULL;
/*
* Info about current "snapshot" of stats file
*/
@@ -740,158 +738,6 @@ pgstat_initialize(void)
}
/* ------------------------------------------------------------
* Transaction integration
* ------------------------------------------------------------
*/
/*
* Called from access/transam/xact.c at top-level transaction commit/abort.
*/
void
AtEOXact_PgStat(bool isCommit, bool parallel)
{
PgStat_SubXactStatus *xact_state;
AtEOXact_PgStat_Database(isCommit, parallel);
/* handle transactional stats information */
xact_state = pgStatXactStack;
if (xact_state != NULL)
{
Assert(xact_state->nest_level == 1);
Assert(xact_state->prev == NULL);
AtEOXact_PgStat_Relations(xact_state, isCommit);
}
pgStatXactStack = NULL;
/* Make sure any stats snapshot is thrown away */
pgstat_clear_snapshot();
}
/*
* Called from access/transam/xact.c at subtransaction commit/abort.
*/
void
AtEOSubXact_PgStat(bool isCommit, int nestDepth)
{
PgStat_SubXactStatus *xact_state;
/* merge the sub-transaction's transactional stats into the parent */
xact_state = pgStatXactStack;
if (xact_state != NULL &&
xact_state->nest_level >= nestDepth)
{
/* delink xact_state from stack immediately to simplify reuse case */
pgStatXactStack = xact_state->prev;
AtEOSubXact_PgStat_Relations(xact_state, isCommit, nestDepth);
pfree(xact_state);
}
}
/*
* Save the transactional stats state at 2PC transaction prepare.
*/
void
AtPrepare_PgStat(void)
{
PgStat_SubXactStatus *xact_state;
xact_state = pgStatXactStack;
if (xact_state != NULL)
{
Assert(xact_state->nest_level == 1);
Assert(xact_state->prev == NULL);
AtPrepare_PgStat_Relations(xact_state);
}
}
/*
* Clean up after successful PREPARE.
*
* Note: AtEOXact_PgStat is not called during PREPARE.
*/
void
PostPrepare_PgStat(void)
{
PgStat_SubXactStatus *xact_state;
/*
* We don't bother to free any of the transactional state, since it's all
* in TopTransactionContext and will go away anyway.
*/
xact_state = pgStatXactStack;
if (xact_state != NULL)
{
Assert(xact_state->nest_level == 1);
Assert(xact_state->prev == NULL);
PostPrepare_PgStat_Relations(xact_state);
}
pgStatXactStack = NULL;
/* Make sure any stats snapshot is thrown away */
pgstat_clear_snapshot();
}
/*
* Discard any data collected in the current transaction. Any subsequent
* request will cause new snapshots to be read.
*
* This is also invoked during transaction commit or abort to discard
* the no-longer-wanted snapshot.
*/
void
pgstat_clear_snapshot(void)
{
pgstat_assert_is_up();
/* Release memory, if any was allocated */
if (pgStatLocalContext)
MemoryContextDelete(pgStatLocalContext);
/* Reset variables */
pgStatLocalContext = NULL;
pgStatDBHash = NULL;
replSlotStatHash = NULL;
subscriptionStatHash = NULL;
/*
* Historically the backend_status.c facilities lived in this file, and
* were reset with the same function. For now keep it that way, and
* forward the reset request.
*/
pgstat_clear_backend_activity_snapshot();
}
/*
* Ensure (sub)transaction stack entry for the given nest_level exists, adding
* it if needed.
*/
PgStat_SubXactStatus *
pgstat_xact_stack_level_get(int nest_level)
{
PgStat_SubXactStatus *xact_state;
xact_state = pgStatXactStack;
if (xact_state == NULL || xact_state->nest_level != nest_level)
{
xact_state = (PgStat_SubXactStatus *)
MemoryContextAlloc(TopTransactionContext,
sizeof(PgStat_SubXactStatus));
xact_state->nest_level = nest_level;
xact_state->prev = pgStatXactStack;
xact_state->first = NULL;
pgStatXactStack = xact_state;
}
return xact_state;
}
/* ------------------------------------------------------------
* Public functions used by backends follow
* ------------------------------------------------------------
@@ -1319,6 +1165,36 @@ pgstat_send_inquiry(TimestampTz clock_time, TimestampTz cutoff_time, Oid databas
pgstat_send(&msg, sizeof(msg));
}
/*
* Discard any data collected in the current transaction. Any subsequent
* request will cause new snapshots to be read.
*
* This is also invoked during transaction commit or abort to discard
* the no-longer-wanted snapshot.
*/
void
pgstat_clear_snapshot(void)
{
pgstat_assert_is_up();
/* Release memory, if any was allocated */
if (pgStatLocalContext)
MemoryContextDelete(pgStatLocalContext);
/* Reset variables */
pgStatLocalContext = NULL;
pgStatDBHash = NULL;
replSlotStatHash = NULL;
subscriptionStatHash = NULL;
/*
* Historically the backend_status.c facilities lived in this file, and
* were reset with the same function. For now keep it that way, and
* forward the reset request.
*/
pgstat_clear_backend_activity_snapshot();
}
/*
* Support function for the SQL-callable pgstat* functions. Returns
* the collected statistics for one database or NULL. NULL doesn't mean

View File

@@ -23,9 +23,10 @@ OBJS = \
pgstat_function.o \
pgstat_relation.o \
pgstat_replslot.o \
pgstat_slru.o \
pgstat_subscription.o \
pgstat_wal.o \
pgstat_slru.o \
pgstat_xact.o \
wait_event.o
include $(top_srcdir)/src/backend/common.mk

View File

@@ -0,0 +1,139 @@
/* -------------------------------------------------------------------------
*
* pgstat_xact.c
* Transactional integration for the cumulative statistics system.
*
* Copyright (c) 2001-2022, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/backend/utils/activity/pgstat_xact.c
* -------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/transam.h"
#include "access/xact.h"
#include "pgstat.h"
#include "utils/memutils.h"
#include "utils/pgstat_internal.h"
static PgStat_SubXactStatus *pgStatXactStack = NULL;
/*
* Called from access/transam/xact.c at top-level transaction commit/abort.
*/
void
AtEOXact_PgStat(bool isCommit, bool parallel)
{
PgStat_SubXactStatus *xact_state;
AtEOXact_PgStat_Database(isCommit, parallel);
/* handle transactional stats information */
xact_state = pgStatXactStack;
if (xact_state != NULL)
{
Assert(xact_state->nest_level == 1);
Assert(xact_state->prev == NULL);
AtEOXact_PgStat_Relations(xact_state, isCommit);
}
pgStatXactStack = NULL;
/* Make sure any stats snapshot is thrown away */
pgstat_clear_snapshot();
}
/*
* Called from access/transam/xact.c at subtransaction commit/abort.
*/
void
AtEOSubXact_PgStat(bool isCommit, int nestDepth)
{
PgStat_SubXactStatus *xact_state;
/* merge the sub-transaction's transactional stats into the parent */
xact_state = pgStatXactStack;
if (xact_state != NULL &&
xact_state->nest_level >= nestDepth)
{
/* delink xact_state from stack immediately to simplify reuse case */
pgStatXactStack = xact_state->prev;
AtEOSubXact_PgStat_Relations(xact_state, isCommit, nestDepth);
pfree(xact_state);
}
}
/*
* Save the transactional stats state at 2PC transaction prepare.
*/
void
AtPrepare_PgStat(void)
{
PgStat_SubXactStatus *xact_state;
xact_state = pgStatXactStack;
if (xact_state != NULL)
{
Assert(xact_state->nest_level == 1);
Assert(xact_state->prev == NULL);
AtPrepare_PgStat_Relations(xact_state);
}
}
/*
* Clean up after successful PREPARE.
*
* Note: AtEOXact_PgStat is not called during PREPARE.
*/
void
PostPrepare_PgStat(void)
{
PgStat_SubXactStatus *xact_state;
/*
* We don't bother to free any of the transactional state, since it's all
* in TopTransactionContext and will go away anyway.
*/
xact_state = pgStatXactStack;
if (xact_state != NULL)
{
Assert(xact_state->nest_level == 1);
Assert(xact_state->prev == NULL);
PostPrepare_PgStat_Relations(xact_state);
}
pgStatXactStack = NULL;
/* Make sure any stats snapshot is thrown away */
pgstat_clear_snapshot();
}
/*
* Ensure (sub)transaction stack entry for the given nest_level exists, adding
* it if needed.
*/
PgStat_SubXactStatus *
pgstat_xact_stack_level_get(int nest_level)
{
PgStat_SubXactStatus *xact_state;
xact_state = pgStatXactStack;
if (xact_state == NULL || xact_state->nest_level != nest_level)
{
xact_state = (PgStat_SubXactStatus *)
MemoryContextAlloc(TopTransactionContext,
sizeof(PgStat_SubXactStatus));
xact_state->nest_level = nest_level;
xact_state->prev = pgStatXactStack;
xact_state->first = NULL;
pgStatXactStack = xact_state;
}
return xact_state;
}