From 42907f1c437e952a9d31fcc617ef3a296c8471dc Mon Sep 17 00:00:00 2001 From: "Sami Imseih (AWS)" Date: Thu, 30 Jul 2026 17:07:40 +0000 Subject: [PATCH 1/1] pgstat: Flush non-transactional stats at statement boundaries in-transaction Long-running transactions that execute many statements could accumulate non-transactional stats counters (numscans, tuples_returned, tuples_fetched, blocks_fetched, blocks_hit) without ever reporting them to shared stats until the transaction ended. This made monitoring blind to activity inside such transactions. Flush non-transactional counters at statement boundaries within a transaction, throttled to at most once every PGSTAT_INTXN_FLUSH_INTERVAL (10 seconds). --- src/backend/tcop/postgres.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index b6bdfe213fe..e3399b7f7c5 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -87,6 +87,13 @@ #include "utils/timestamp.h" #include "utils/varlena.h" +/* + * Minimum interval between automatic in-transaction stats flushes (ms). + * Non-transactional counters are flushed at statement boundaries within a + * transaction, but no more often than this. + */ +#define PGSTAT_INTXN_FLUSH_INTERVAL 10000 + /* ---------------- * global variables * ---------------- @@ -4760,6 +4767,29 @@ PostgresMain(const char *dbname, const char *username) } else if (IsTransactionOrTransactionBlock()) { + /* + * Flush non-transactional stats at statement boundaries + * within a transaction, at most once every + * PGSTAT_INTXN_FLUSH_INTERVAL seconds. + */ + static TimestampTz last_intxn_flush = 0; + + /* + * Use the statement start timestamp rather than + * GetCurrentTimestamp() to avoid a syscall per statement. + * This makes the interval approximate, but that's fine since + * we only flush at statement boundaries anyway. + */ + TimestampTz stmtts = GetCurrentStatementStartTimestamp(); + + if (last_intxn_flush == 0 || + TimestampDifferenceExceeds(last_intxn_flush, stmtts, + PGSTAT_INTXN_FLUSH_INTERVAL)) + { + pgstat_report_stat(true); + last_intxn_flush = stmtts; + } + set_ps_display("idle in transaction"); pgstat_report_activity(STATE_IDLEINTRANSACTION, NULL); -- 2.47.3