v1-0001-Fix-transient-NULL-query_id-in-pg_stat_activity.patch
application/octet-stream
Filename: v1-0001-Fix-transient-NULL-query_id-in-pg_stat_activity.patch
Type: application/octet-stream
Part: 0
From 7cbcc4eb19958bef05d4a8ffae22221cf07813e9 Mon Sep 17 00:00:00 2001
From: Srinath Reddy Sadipiralla <srinath2133@gmail.com>
Date: Thu, 28 Aug 2025 17:37:23 +0530
Subject: [PATCH 1/1] Fix transient NULL query_id in pg_stat_activity
When compute_query_id = on, pg_stat_activity.query_id could sometimes
appear as NULL even for queries that did receive a query ID. The cause
was a timing gap in exec_simple_query(): pgstat_report_query_id() resets
st_query_id to 0, and only later is the new query_id assigned. A
concurrent backend inspecting pg_stat_activity during this window would
see 0, which is displayed as NULL.
To fix, track the previous st_query_id in prev_st_query_id before the
reset. In pg_stat_get_activity(), if st_query_id is still 0 but query
ID computation is enabled, return prev_st_query_id instead of reporting
NULL.
This change avoids NULLs and makes query_id reporting in pg_stat_activity
consistent. Queries that genuinely lack a query ID
(e.g. when compute_query_id = off) continue to show NULL.
---
src/backend/utils/activity/backend_status.c | 2 ++
src/backend/utils/adt/pgstatfuncs.c | 8 +++++++-
src/include/utils/backend_status.h | 1 +
3 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c
index a290cc4c975..f290306457f 100644
--- a/src/backend/utils/activity/backend_status.c
+++ b/src/backend/utils/activity/backend_status.c
@@ -320,6 +320,7 @@ pgstat_bestart_initial(void)
lbeentry.st_state = STATE_STARTING;
lbeentry.st_progress_command = PROGRESS_COMMAND_INVALID;
lbeentry.st_progress_command_target = InvalidOid;
+ lbeentry.prev_st_query_id = INT64CONST(0);
lbeentry.st_query_id = INT64CONST(0);
lbeentry.st_plan_id = INT64CONST(0);
@@ -662,6 +663,7 @@ pgstat_report_activity(BackendState state, const char *cmd_str)
*/
if (state == STATE_RUNNING)
{
+ beentry->prev_st_query_id = beentry->st_query_id;
beentry->st_query_id = INT64CONST(0);
beentry->st_plan_id = INT64CONST(0);
}
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index c756c2bebaa..726321e97b5 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -31,6 +31,7 @@
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/timestamp.h"
+#include "nodes/queryjumble.h"
#define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var))))
@@ -641,7 +642,12 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
* delegated */
}
if (beentry->st_query_id == INT64CONST(0))
- nulls[30] = true;
+ {
+ if(!IsQueryIdEnabled())
+ nulls[30] = true;
+ else
+ values[30] = Int64GetDatum(beentry->prev_st_query_id);
+ }
else
values[30] = Int64GetDatum(beentry->st_query_id);
}
diff --git a/src/include/utils/backend_status.h b/src/include/utils/backend_status.h
index 3016501ac05..efa9a67cbe2 100644
--- a/src/include/utils/backend_status.h
+++ b/src/include/utils/backend_status.h
@@ -170,6 +170,7 @@ typedef struct PgBackendStatus
int64 st_progress_param[PGSTAT_NUM_PROGRESS_PARAM];
/* query identifier, optionally computed using post_parse_analyze_hook */
+ int64 prev_st_query_id;
int64 st_query_id;
/* plan identifier, optionally computed using planner_hook */
--
2.43.0