pg_stat_get_backend_subxact() and backend IDs?
Hi
I was playing around with "pg_stat_get_backend_subxact()" (commit 10ea0f924)
and see it emits NULL values for some backends, e.g.:
postgres=# \pset null NULL
Null display is "NULL".
postgres=# SELECT id, pg_stat_get_backend_pid(id), s.*,
pg_stat_get_backend_activity (id)
FROM pg_stat_get_backend_idset() id
JOIN LATERAL pg_stat_get_backend_subxact(id) AS s ON TRUE;
id | pg_stat_get_backend_pid | subxact_count |
subxact_overflowed | pg_stat_get_backend_activity
-----+-------------------------+---------------+--------------------+------------------------------------------------------------
1 | 3175972 | 0 | f
| <command string not enabled>
2 | 3175973 | 0 | f
| <command string not enabled>
3 | 3177889 | 0 | f
| SELECT id, pg_stat_get_backend_pid(id), s.*, +
| | |
| pg_stat_get_backend_activity (id) +
| | |
| FROM pg_stat_get_backend_idset() id +
| | |
| JOIN LATERAL pg_stat_get_backend_subxact(id) AS s ON TRUE;
4 | 3176027 | 5 | f
| savepoint s4;
256 | 3175969 | NULL | NULL
| <command string not enabled>
258 | 3175968 | NULL | NULL
| <command string not enabled>
259 | 3175971 | NULL | NULL
| <command string not enabled>
(7 rows)
Reading through the thread [1]/messages/by-id/CAFiTN-uvYAofNRaGF4R+u6_OrABdkqNRoX7V6+PP3H_0HuYMwg@mail.gmail.com, it looks like 0/false are intended to be
returned for non-backend processes too [2]/messages/by-id/CAFiTN-ut0uwkRJDQJeDPXpVyTWD46m3gt3JDToE02hTfONEN=Q@mail.gmail.com, so it seems odd that NULL/NULL is
getting returned in some cases, especially as that's what's returned if a
non-existent backend ID is provided.
[1]: /messages/by-id/CAFiTN-uvYAofNRaGF4R+u6_OrABdkqNRoX7V6+PP3H_0HuYMwg@mail.gmail.com
[2]: /messages/by-id/CAFiTN-ut0uwkRJDQJeDPXpVyTWD46m3gt3JDToE02hTfONEN=Q@mail.gmail.com
Looking at the code, this is happening because
"pgstat_fetch_stat_local_beentry()"
expects to be passed the backend ID as an integer representing a 1-based index
referring to "localBackendStatusTable", but "pg_stat_get_backend_subxact()"
is presumably intended to take the actual BackendId , as per other
"pg_stat_get_XXX()"
functions.
Also, the comment for "pgstat_fetch_stat_local_beentry()" says:
Returns NULL if the argument is out of range (no current caller does that).
so the last part is currently incorrect.
Assuming I am not misunderstanding something here (always a
possibility, apologies
in advance if this is merely noise), what is actually needed is a function which
accepts a BackendId (as per "pgstat_fetch_stat_beentry()"), but returns a
LocalPgBackendStatus (as per "pgstat_fetch_stat_local_beentry()") like the
attached, clumsily named "pgstat_fetch_stat_backend_local_beentry()".
Regards
Ian Barwick
Attachments:
pg_stat_get_backend_subxact-fix.v1.patchtext/x-patch; charset=US-ASCII; name=pg_stat_get_backend_subxact-fix.v1.patchDownload
commit d4292d3347658f61855fd84827954f587838a324
Author: Ian Barwick <barwick@gmail.com>
Date: Thu Aug 24 10:16:51 2023 +0900
pg_stat_get_backend_subxact(): handle backend ID correctly
diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c
index 38f91a495b..bce7836264 100644
--- a/src/backend/utils/activity/backend_status.c
+++ b/src/backend/utils/activity/backend_status.c
@@ -1136,6 +1136,39 @@ pgstat_fetch_stat_local_beentry(int beid)
}
+/* ----------
+ * pgstat_fetch_stat_backend_local_beentry() -
+ *
+ * Like pgstat_fetch_stat_local_beentry() but takes the BackendId of the
+ * desired session.
+ *
+ * Returns NULL if the given beid doesn't identify any known session.
+ *
+ * NB: caller is responsible for a check if the user is permitted to see
+ * this info (especially the querystring).
+ * ----------
+ */
+
+LocalPgBackendStatus *
+pgstat_fetch_stat_backend_local_beentry(BackendId beid)
+{
+ LocalPgBackendStatus key;
+
+ pgstat_read_current_status();
+
+ /*
+ * Since the localBackendStatusTable is in order by backend_id, we can use
+ * bsearch() to search it efficiently.
+ */
+ key.backend_id = beid;
+
+ return (LocalPgBackendStatus *) bsearch(&key, localBackendStatusTable,
+ localNumBackends,
+ sizeof(LocalPgBackendStatus),
+ cmp_lbestatus);
+}
+
+
/* ----------
* pgstat_fetch_stat_numbackends() -
*
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 2b9742ad21..8479ea130b 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -727,7 +727,7 @@ pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
BlessTupleDesc(tupdesc);
- if ((local_beentry = pgstat_fetch_stat_local_beentry(beid)) != NULL)
+ if ((local_beentry = pgstat_fetch_stat_backend_local_beentry(beid)) != NULL)
{
/* Fill values and NULLs */
values[0] = Int32GetDatum(local_beentry->backend_subxact_count);
diff --git a/src/include/utils/backend_status.h b/src/include/utils/backend_status.h
index 77939a0aed..760ddc48ae 100644
--- a/src/include/utils/backend_status.h
+++ b/src/include/utils/backend_status.h
@@ -334,6 +334,7 @@ extern uint64 pgstat_get_my_query_id(void);
*/
extern int pgstat_fetch_stat_numbackends(void);
extern PgBackendStatus *pgstat_fetch_stat_beentry(BackendId beid);
+extern LocalPgBackendStatus *pgstat_fetch_stat_backend_local_beentry(BackendId beid);
extern LocalPgBackendStatus *pgstat_fetch_stat_local_beentry(int beid);
extern char *pgstat_clip_activity(const char *raw_activity);
On Thu, Aug 24, 2023 at 10:22:49AM +0900, Ian Lawrence Barwick wrote:
Looking at the code, this is happening because
"pgstat_fetch_stat_local_beentry()"
expects to be passed the backend ID as an integer representing a 1-based index
referring to "localBackendStatusTable", but "pg_stat_get_backend_subxact()"
is presumably intended to take the actual BackendId , as per other
"pg_stat_get_XXX()"
functions.
Yes, this was changed in d7e39d7, but 10ea0f9 seems to have missed the
memo.
Assuming I am not misunderstanding something here (always a
possibility, apologies
in advance if this is merely noise), what is actually needed is a function which
accepts a BackendId (as per "pgstat_fetch_stat_beentry()"), but returns a
LocalPgBackendStatus (as per "pgstat_fetch_stat_local_beentry()") like the
attached, clumsily named "pgstat_fetch_stat_backend_local_beentry()".
I think you are right. The relevant information is only available in
LocalPgBackendStatus, but there's presently no helper function for
obtaining the "local" status with the BackendId.
+LocalPgBackendStatus * +pgstat_fetch_stat_backend_local_beentry(BackendId beid) +{ + LocalPgBackendStatus key; + + pgstat_read_current_status(); + + /* + * Since the localBackendStatusTable is in order by backend_id, we can use + * bsearch() to search it efficiently. + */ + key.backend_id = beid; + + return (LocalPgBackendStatus *) bsearch(&key, localBackendStatusTable, + localNumBackends, + sizeof(LocalPgBackendStatus), + cmp_lbestatus); +}
We could probably modify pgstat_fetch_stat_beentry() to use this new
function. I suspect we'll want to work on the naming, too. Maybe we could
name them pg_stat_fetch_local_beentry_by_index() and
pg_stat_fetch_local_beentry_by_backendid().
--
Nathan Bossart
Amazon Web Services: https://aws.amazon.com
On Wed, Aug 23, 2023 at 07:32:06PM -0700, Nathan Bossart wrote:
On Thu, Aug 24, 2023 at 10:22:49AM +0900, Ian Lawrence Barwick wrote:
Looking at the code, this is happening because
"pgstat_fetch_stat_local_beentry()"
expects to be passed the backend ID as an integer representing a 1-based index
referring to "localBackendStatusTable", but "pg_stat_get_backend_subxact()"
is presumably intended to take the actual BackendId , as per other
"pg_stat_get_XXX()"
functions.Yes, this was changed in d7e39d7, but 10ea0f9 seems to have missed the
memo.
BTW I'd argue that this is a bug in v16 that we should try to fix before
GA, so I've added an open item [0]https://wiki.postgresql.org/wiki/PostgreSQL_16_Open_Items#Open_Issues. I assigned it to Robert (CC'd) since
he was the committer, but I'm happy to pick it up.
[0]: https://wiki.postgresql.org/wiki/PostgreSQL_16_Open_Items#Open_Issues
--
Nathan Bossart
Amazon Web Services: https://aws.amazon.com
On Wed, Aug 23, 2023 at 07:51:40PM -0700, Nathan Bossart wrote:
On Wed, Aug 23, 2023 at 07:32:06PM -0700, Nathan Bossart wrote:
On Thu, Aug 24, 2023 at 10:22:49AM +0900, Ian Lawrence Barwick wrote:
Looking at the code, this is happening because
"pgstat_fetch_stat_local_beentry()"
expects to be passed the backend ID as an integer representing a 1-based index
referring to "localBackendStatusTable", but "pg_stat_get_backend_subxact()"
is presumably intended to take the actual BackendId , as per other
"pg_stat_get_XXX()"
functions.Yes, this was changed in d7e39d7, but 10ea0f9 seems to have missed the
memo.BTW I'd argue that this is a bug in v16 that we should try to fix before
GA, so I've added an open item [0]. I assigned it to Robert (CC'd) since
he was the committer, but I'm happy to pick it up.
Since RC1 is fast approaching, I put together a revised patch set. 0001
renames the existing pgstat_fetch_stat* functions, and 0002 adds
pgstat_get_local_beentry_by_backend_id() and uses it for
pg_stat_get_backend_subxact(). Thoughts?
--
Nathan Bossart
Amazon Web Services: https://aws.amazon.com
Attachments:
v2-0001-rename-some-pgstat-functions.patchtext/x-diff; charset=us-asciiDownload
From 3af12242ec10abe83d195e4b3f0765afec40f710 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Thu, 24 Aug 2023 07:42:54 -0700
Subject: [PATCH v2 1/2] rename some pgstat functions
---
src/backend/utils/activity/backend_status.c | 22 +++++++-------
src/backend/utils/adt/pgstatfuncs.c | 32 ++++++++++-----------
src/include/utils/backend_status.h | 4 +--
3 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c
index 38f91a495b..aea05a9014 100644
--- a/src/backend/utils/activity/backend_status.c
+++ b/src/backend/utils/activity/backend_status.c
@@ -849,8 +849,8 @@ pgstat_read_current_status(void)
/*
* The BackendStatusArray index is exactly the BackendId of the
* source backend. Note that this means localBackendStatusTable
- * is in order by backend_id. pgstat_fetch_stat_beentry() depends
- * on that.
+ * is in order by backend_id. pgstat_get_beentry_by_backend_id()
+ * depends on that.
*/
localentry->backend_id = i;
BackendIdGetTransactionIds(i,
@@ -1073,21 +1073,21 @@ cmp_lbestatus(const void *a, const void *b)
}
/* ----------
- * pgstat_fetch_stat_beentry() -
+ * pgstat_get_beentry_by_backend_id() -
*
* Support function for the SQL-callable pgstat* functions. Returns
* our local copy of the current-activity entry for one backend,
* or NULL if the given beid doesn't identify any known session.
*
* The beid argument is the BackendId of the desired session
- * (note that this is unlike pgstat_fetch_stat_local_beentry()).
+ * (note that this is unlike pgstat_get_local_beentry_by_index()).
*
* NB: caller is responsible for a check if the user is permitted to see
* this info (especially the querystring).
* ----------
*/
PgBackendStatus *
-pgstat_fetch_stat_beentry(BackendId beid)
+pgstat_get_beentry_by_backend_id(BackendId beid)
{
LocalPgBackendStatus key;
LocalPgBackendStatus *ret;
@@ -1111,13 +1111,13 @@ pgstat_fetch_stat_beentry(BackendId beid)
/* ----------
- * pgstat_fetch_stat_local_beentry() -
+ * pgstat_get_local_beentry_by_index() -
*
- * Like pgstat_fetch_stat_beentry() but with locally computed additions (like
- * xid and xmin values of the backend)
+ * Like pgstat_get_beentry_by_backend_id() but with locally computed additions
+ * (like xid and xmin values of the backend)
*
* The beid argument is a 1-based index in the localBackendStatusTable
- * (note that this is unlike pgstat_fetch_stat_beentry()).
+ * (note that this is unlike pgstat_get_beentry_by_backend_id()).
* Returns NULL if the argument is out of range (no current caller does that).
*
* NB: caller is responsible for a check if the user is permitted to see
@@ -1125,7 +1125,7 @@ pgstat_fetch_stat_beentry(BackendId beid)
* ----------
*/
LocalPgBackendStatus *
-pgstat_fetch_stat_local_beentry(int beid)
+pgstat_get_local_beentry_by_index(int beid)
{
pgstat_read_current_status();
@@ -1141,7 +1141,7 @@ pgstat_fetch_stat_local_beentry(int beid)
*
* Support function for the SQL-callable pgstat* functions. Returns
* the number of sessions known in the localBackendStatusTable, i.e.
- * the maximum 1-based index to pass to pgstat_fetch_stat_local_beentry().
+ * the maximum 1-based index to pass to pgstat_get_local_beentry_by_index().
* ----------
*/
int
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 2b9742ad21..7deefed5ab 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -211,7 +211,7 @@ pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
if (fctx[0] <= pgstat_fetch_stat_numbackends())
{
/* do when there is more left to send */
- LocalPgBackendStatus *local_beentry = pgstat_fetch_stat_local_beentry(fctx[0]);
+ LocalPgBackendStatus *local_beentry = pgstat_get_local_beentry_by_index(fctx[0]);
SRF_RETURN_NEXT(funcctx, Int32GetDatum(local_beentry->backend_id));
}
@@ -264,7 +264,7 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS)
bool nulls[PG_STAT_GET_PROGRESS_COLS] = {0};
int i;
- local_beentry = pgstat_fetch_stat_local_beentry(curr_backend);
+ local_beentry = pgstat_get_local_beentry_by_index(curr_backend);
beentry = &local_beentry->backendStatus;
/*
@@ -325,7 +325,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
const char *wait_event = NULL;
/* Get the next one in the list */
- local_beentry = pgstat_fetch_stat_local_beentry(curr_backend);
+ local_beentry = pgstat_get_local_beentry_by_index(curr_backend);
beentry = &local_beentry->backendStatus;
/* If looking for specific PID, ignore all the others */
@@ -672,7 +672,7 @@ pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
int32 beid = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
PG_RETURN_NULL();
PG_RETURN_INT32(beentry->st_procpid);
@@ -685,7 +685,7 @@ pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
int32 beid = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
PG_RETURN_NULL();
PG_RETURN_OID(beentry->st_databaseid);
@@ -698,7 +698,7 @@ pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
int32 beid = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
PG_RETURN_NULL();
PG_RETURN_OID(beentry->st_userid);
@@ -727,7 +727,7 @@ pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
BlessTupleDesc(tupdesc);
- if ((local_beentry = pgstat_fetch_stat_local_beentry(beid)) != NULL)
+ if ((local_beentry = pgstat_get_local_beentry_by_index(beid)) != NULL)
{
/* Fill values and NULLs */
values[0] = Int32GetDatum(local_beentry->backend_subxact_count);
@@ -752,7 +752,7 @@ pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
char *clipped_activity;
text *ret;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
activity = "<backend information not available>";
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
activity = "<insufficient privilege>";
@@ -776,7 +776,7 @@ pg_stat_get_backend_wait_event_type(PG_FUNCTION_ARGS)
PGPROC *proc;
const char *wait_event_type = NULL;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
wait_event_type = "<backend information not available>";
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
wait_event_type = "<insufficient privilege>";
@@ -797,7 +797,7 @@ pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS)
PGPROC *proc;
const char *wait_event = NULL;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
wait_event = "<backend information not available>";
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
wait_event = "<insufficient privilege>";
@@ -818,7 +818,7 @@ pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
TimestampTz result;
PgBackendStatus *beentry;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
PG_RETURN_NULL();
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
@@ -844,7 +844,7 @@ pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS)
TimestampTz result;
PgBackendStatus *beentry;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
PG_RETURN_NULL();
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
@@ -866,7 +866,7 @@ pg_stat_get_backend_start(PG_FUNCTION_ARGS)
TimestampTz result;
PgBackendStatus *beentry;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
PG_RETURN_NULL();
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
@@ -890,7 +890,7 @@ pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
char remote_host[NI_MAXHOST];
int ret;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
PG_RETURN_NULL();
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
@@ -935,7 +935,7 @@ pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
char remote_port[NI_MAXSERV];
int ret;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
PG_RETURN_NULL();
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
@@ -983,7 +983,7 @@ pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
result = 0;
for (beid = 1; beid <= tot_backends; beid++)
{
- LocalPgBackendStatus *local_beentry = pgstat_fetch_stat_local_beentry(beid);
+ LocalPgBackendStatus *local_beentry = pgstat_get_local_beentry_by_index(beid);
if (local_beentry->backendStatus.st_databaseid == dbid)
result++;
diff --git a/src/include/utils/backend_status.h b/src/include/utils/backend_status.h
index 77939a0aed..e53098ec9e 100644
--- a/src/include/utils/backend_status.h
+++ b/src/include/utils/backend_status.h
@@ -333,8 +333,8 @@ extern uint64 pgstat_get_my_query_id(void);
* ----------
*/
extern int pgstat_fetch_stat_numbackends(void);
-extern PgBackendStatus *pgstat_fetch_stat_beentry(BackendId beid);
-extern LocalPgBackendStatus *pgstat_fetch_stat_local_beentry(int beid);
+extern PgBackendStatus *pgstat_get_beentry_by_backend_id(BackendId beid);
+extern LocalPgBackendStatus *pgstat_get_local_beentry_by_index(int beid);
extern char *pgstat_clip_activity(const char *raw_activity);
--
2.25.1
v2-0002-fix-pg_stat_get_backend_subxact-to-use-real-backe.patchtext/x-diff; charset=us-asciiDownload
From 82d95d01526d09c565413696a366b350a9f796ff Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Thu, 24 Aug 2023 07:58:01 -0700
Subject: [PATCH v2 2/2] fix pg_stat_get_backend_subxact to use real backend id
---
src/backend/utils/activity/backend_status.c | 36 +++++++++++++++------
src/backend/utils/adt/pgstatfuncs.c | 2 +-
src/include/utils/backend_status.h | 1 +
3 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c
index aea05a9014..d5babd9fb0 100644
--- a/src/backend/utils/activity/backend_status.c
+++ b/src/backend/utils/activity/backend_status.c
@@ -1088,9 +1088,33 @@ cmp_lbestatus(const void *a, const void *b)
*/
PgBackendStatus *
pgstat_get_beentry_by_backend_id(BackendId beid)
+{
+ LocalPgBackendStatus *ret = pgstat_get_local_beentry_by_backend_id(beid);
+
+ if (ret)
+ return &ret->backendStatus;
+
+ return NULL;
+}
+
+
+/* ----------
+ * pgstat_get_local_beentry_by_backend_id() -
+ *
+ * Like pgstat_get_beentry_by_backend_id() but with locally computed additions
+ * (like xid and xmin values of the backend)
+ *
+ * The beid argument is the BackendId of the desired session
+ * (note that this is unlike pgstat_get_local_beentry_by_index()).
+ *
+ * NB: caller is responsible for checking if the user is permitted to see this
+ * info (especially the querystring).
+ * ----------
+ */
+LocalPgBackendStatus *
+pgstat_get_local_beentry_by_backend_id(BackendId beid)
{
LocalPgBackendStatus key;
- LocalPgBackendStatus *ret;
pgstat_read_current_status();
@@ -1099,14 +1123,8 @@ pgstat_get_beentry_by_backend_id(BackendId beid)
* bsearch() to search it efficiently.
*/
key.backend_id = beid;
- ret = (LocalPgBackendStatus *) bsearch(&key, localBackendStatusTable,
- localNumBackends,
- sizeof(LocalPgBackendStatus),
- cmp_lbestatus);
- if (ret)
- return &ret->backendStatus;
-
- return NULL;
+ return bsearch(&key, localBackendStatusTable, localNumBackends,
+ sizeof(LocalPgBackendStatus), cmp_lbestatus);
}
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 7deefed5ab..62d327bb92 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -727,7 +727,7 @@ pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
BlessTupleDesc(tupdesc);
- if ((local_beentry = pgstat_get_local_beentry_by_index(beid)) != NULL)
+ if ((local_beentry = pgstat_get_local_beentry_by_backend_id(beid)) != NULL)
{
/* Fill values and NULLs */
values[0] = Int32GetDatum(local_beentry->backend_subxact_count);
diff --git a/src/include/utils/backend_status.h b/src/include/utils/backend_status.h
index e53098ec9e..a996c7fd23 100644
--- a/src/include/utils/backend_status.h
+++ b/src/include/utils/backend_status.h
@@ -334,6 +334,7 @@ extern uint64 pgstat_get_my_query_id(void);
*/
extern int pgstat_fetch_stat_numbackends(void);
extern PgBackendStatus *pgstat_get_beentry_by_backend_id(BackendId beid);
+extern LocalPgBackendStatus *pgstat_get_local_beentry_by_backend_id(BackendId beid);
extern LocalPgBackendStatus *pgstat_get_local_beentry_by_index(int beid);
extern char *pgstat_clip_activity(const char *raw_activity);
--
2.25.1
2023年8月25日(金) 1:19 Nathan Bossart <nathandbossart@gmail.com>:
On Wed, Aug 23, 2023 at 07:51:40PM -0700, Nathan Bossart wrote:
On Wed, Aug 23, 2023 at 07:32:06PM -0700, Nathan Bossart wrote:
On Thu, Aug 24, 2023 at 10:22:49AM +0900, Ian Lawrence Barwick wrote:
Looking at the code, this is happening because
"pgstat_fetch_stat_local_beentry()"
expects to be passed the backend ID as an integer representing a 1-based index
referring to "localBackendStatusTable", but "pg_stat_get_backend_subxact()"
is presumably intended to take the actual BackendId , as per other
"pg_stat_get_XXX()"
functions.Yes, this was changed in d7e39d7, but 10ea0f9 seems to have missed the
memo.BTW I'd argue that this is a bug in v16 that we should try to fix before
GA, so I've added an open item [0]. I assigned it to Robert (CC'd) since
he was the committer, but I'm happy to pick it up.Since RC1 is fast approaching, I put together a revised patch set. 0001
renames the existing pgstat_fetch_stat* functions, and 0002 adds
pgstat_get_local_beentry_by_backend_id() and uses it for
pg_stat_get_backend_subxact(). Thoughts?
Thanks for looking at this. In summary we now have these functions:
extern PgBackendStatus *pgstat_get_beentry_by_backend_id(BackendId beid);
extern LocalPgBackendStatus
*pgstat_get_local_beentry_by_backend_id(BackendId beid);
extern LocalPgBackendStatus *pgstat_get_local_beentry_by_index(int beid);
which LGTM; patches work as expected and resolve the reported issue.
Regards
Ian Barwick
I tested the patch and it does the correct thing.
I have a few comments:
1/ cast the return of bsearch. This was done previously and is the common
convention in the code.
So
+ return bsearch(&key, localBackendStatusTable, localNumBackends,
+ sizeof(LocalPgBackendStatus), cmp_lbestatus);
Should be
+ return (LocalPgBackendStatus *) bsearch(&key, localBackendStatusTable, localNumBackends,
+ sizeof(LocalPgBackendStatus), cmp_lbestatus);
2/ This will probably be a good time to update the docs for pg_stat_get_backend_subxact [1]
to call out that "subxact_count" will "only increase if a transaction is performing writes". Also to link
the reader to the subtransactions doc [2].
1. https://www.postgresql.org/docs/16/monitoring-stats.html#WAIT-EVENT-TIMEOUT-TABLE
2. https://www.postgresql.org/docs/16/subxacts.html
Regards,
Sami Imseih
Amazon Web Services (AWS)
On Fri, Aug 25, 2023 at 09:36:18AM +0900, Ian Lawrence Barwick wrote:
Thanks for looking at this. In summary we now have these functions:
extern PgBackendStatus *pgstat_get_beentry_by_backend_id(BackendId beid);
extern LocalPgBackendStatus
*pgstat_get_local_beentry_by_backend_id(BackendId beid);
extern LocalPgBackendStatus *pgstat_get_local_beentry_by_index(int beid);which LGTM; patches work as expected and resolve the reported issue.
On second thought, renaming these exported functions so close to release is
probably not a great idea. I should probably skip back-patching that one.
Or I could have the existing functions call the new ones in v16 for
backward compatibility...
--
Nathan Bossart
Amazon Web Services: https://aws.amazon.com
On Fri, Aug 25, 2023 at 03:01:40PM +0000, Imseih (AWS), Sami wrote:
1/ cast the return of bsearch. This was done previously and is the common
convention in the code.
Will do.
2/ This will probably be a good time to update the docs for pg_stat_get_backend_subxact [1]
to call out that "subxact_count" will "only increase if a transaction is performing writes". Also to link
the reader to the subtransactions doc [2].
I'd rather keep this patch focused on fixing the bug, given we are so close
to the v16 release.
--
Nathan Bossart
Amazon Web Services: https://aws.amazon.com
On Fri, Aug 25, 2023 at 08:32:51AM -0700, Nathan Bossart wrote:
On second thought, renaming these exported functions so close to release is
probably not a great idea. I should probably skip back-patching that one.
Or I could have the existing functions call the new ones in v16 for
backward compatibility...
Here is a new version of the patch that avoids changing the names of the
existing functions. I'm not thrilled about the name
(pgstat_fetch_stat_local_beentry_by_backend_id), so I am open to
suggestions. In any case, I'd like to rename all three of the
pgstat_fetch_stat_* functions in v17.
--
Nathan Bossart
Amazon Web Services: https://aws.amazon.com
Attachments:
v3-0001-fix-pg_stat_get_backend_subxact-to-use-real-backe.patchtext/x-diff; charset=us-asciiDownload
From e1ce8bf67f1b713294ef8d38dbee26bfc7ef16f4 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Thu, 24 Aug 2023 07:58:01 -0700
Subject: [PATCH v3 1/1] fix pg_stat_get_backend_subxact to use real backend id
---
src/backend/utils/activity/backend_status.c | 39 ++++++++++++++++-----
src/backend/utils/adt/pgstatfuncs.c | 2 +-
src/include/utils/backend_status.h | 1 +
3 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c
index 38f91a495b..231cc5dd9a 100644
--- a/src/backend/utils/activity/backend_status.c
+++ b/src/backend/utils/activity/backend_status.c
@@ -1089,9 +1089,34 @@ cmp_lbestatus(const void *a, const void *b)
PgBackendStatus *
pgstat_fetch_stat_beentry(BackendId beid)
{
- LocalPgBackendStatus key;
LocalPgBackendStatus *ret;
+ ret = pgstat_fetch_stat_local_beentry_by_backend_id(beid);
+ if (ret)
+ return &ret->backendStatus;
+
+ return NULL;
+}
+
+
+/* ----------
+ * pgstat_fetch_stat_local_beentry_by_backend_id() -
+ *
+ * Like pgstat_fetch_stat_beentry() but with locally computed additions
+ * (like xid and xmin values of the backend)
+ *
+ * The beid argument is the BackendId of the desired session
+ * (note that this is unlike pgstat_fetch_stat_local_beentry()).
+ *
+ * NB: caller is responsible for checking if the user is permitted to see this
+ * info (especially the querystring).
+ * ----------
+ */
+LocalPgBackendStatus *
+pgstat_fetch_stat_local_beentry_by_backend_id(BackendId beid)
+{
+ LocalPgBackendStatus key;
+
pgstat_read_current_status();
/*
@@ -1099,14 +1124,10 @@ pgstat_fetch_stat_beentry(BackendId beid)
* bsearch() to search it efficiently.
*/
key.backend_id = beid;
- ret = (LocalPgBackendStatus *) bsearch(&key, localBackendStatusTable,
- localNumBackends,
- sizeof(LocalPgBackendStatus),
- cmp_lbestatus);
- if (ret)
- return &ret->backendStatus;
-
- return NULL;
+ return (LocalPgBackendStatus *) bsearch(&key, localBackendStatusTable,
+ localNumBackends,
+ sizeof(LocalPgBackendStatus),
+ cmp_lbestatus);
}
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 2b9742ad21..68ae044399 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -727,7 +727,7 @@ pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
BlessTupleDesc(tupdesc);
- if ((local_beentry = pgstat_fetch_stat_local_beentry(beid)) != NULL)
+ if ((local_beentry = pgstat_fetch_stat_local_beentry_by_backend_id(beid)) != NULL)
{
/* Fill values and NULLs */
values[0] = Int32GetDatum(local_beentry->backend_subxact_count);
diff --git a/src/include/utils/backend_status.h b/src/include/utils/backend_status.h
index 77939a0aed..060431a39b 100644
--- a/src/include/utils/backend_status.h
+++ b/src/include/utils/backend_status.h
@@ -335,6 +335,7 @@ extern uint64 pgstat_get_my_query_id(void);
extern int pgstat_fetch_stat_numbackends(void);
extern PgBackendStatus *pgstat_fetch_stat_beentry(BackendId beid);
extern LocalPgBackendStatus *pgstat_fetch_stat_local_beentry(int beid);
+extern LocalPgBackendStatus *pgstat_fetch_stat_local_beentry_by_backend_id(BackendId beid);
extern char *pgstat_clip_activity(const char *raw_activity);
--
2.25.1
Here is a new version of the patch that avoids changing the names of the
existing functions. I'm not thrilled about the name
(pgstat_fetch_stat_local_beentry_by_backend_id), so I am open to
suggestions. In any case, I'd like to rename all three of the>
pgstat_fetch_stat_* functions in v17.
Thanks for the updated patch.
I reviewed/tested the latest version and I don't have any more comments.
Regards,
Sami
On Fri, Aug 25, 2023 at 10:56:14PM +0000, Imseih (AWS), Sami wrote:
Here is a new version of the patch that avoids changing the names of the
existing functions. I'm not thrilled about the name
(pgstat_fetch_stat_local_beentry_by_backend_id), so I am open to
suggestions. In any case, I'd like to rename all three of the>
pgstat_fetch_stat_* functions in v17.Thanks for the updated patch.
I reviewed/tested the latest version and I don't have any more comments.
FWIW, I find the new routine introduced by this patch rather
confusing. pgstat_fetch_stat_local_beentry() and
pgstat_fetch_stat_local_beentry_by_backend_id() use the same
argument name for a BackendId or an int. This is not entirely the
fault of this patch as pg_stat_get_backend_subxact() itself is
confused about "beid" being a uint32 or a BackendId. However, I think
that this makes much harder to figure out that
pgstat_fetch_stat_local_beentry() is only here because it is cheaper
to do sequential scan of all the local beentries rather than a
bsearch() for all its callers, while
pgstat_fetch_stat_local_beentry_by_backend_id() is here because we
want to retrieve the local beentry matching with the *backend ID* with
the binary search().
I understand that this is not a fantastic naming, but renaming
pgstat_fetch_stat_local_beentry() to something like
pgstat_fetch_stat_local_beentry_by_{index|position}_id() would make
the difference much easier to grasp, and we should avoid the use of
"beid" when we refer to the *position/index ID* in
localBackendStatusTable, because it is not a BackendId at all, just a
position in the local array.
--
Michael
On Mon, Aug 28, 2023 at 10:53:52AM +0900, Michael Paquier wrote:
I understand that this is not a fantastic naming, but renaming
pgstat_fetch_stat_local_beentry() to something like
pgstat_fetch_stat_local_beentry_by_{index|position}_id() would make
the difference much easier to grasp, and we should avoid the use of
"beid" when we refer to the *position/index ID* in
localBackendStatusTable, because it is not a BackendId at all, just a
position in the local array.
This was my first reaction [0]/messages/by-id/20230824161913.GA1394441@nathanxps13.lan. I was concerned about renaming the
exported functions so close to release, so I was suggesting that we hold
off on that part until v17. If there isn't a concern with renaming these
functions in v16, I can proceed with something more like v2.
[0]: /messages/by-id/20230824161913.GA1394441@nathanxps13.lan
--
Nathan Bossart
Amazon Web Services: https://aws.amazon.com
On Tue, Aug 29, 2023 at 09:46:55AM -0700, Nathan Bossart wrote:
This was my first reaction [0]. I was concerned about renaming the
exported functions so close to release, so I was suggesting that we hold
off on that part until v17. If there isn't a concern with renaming these
functions in v16, I can proceed with something more like v2.
Thanks for the pointer. This version is much better IMO, because it
removes entirely the source of the confusion between the difference in
backend ID and index ID treatments when fetching the local entries in
the array. So I'm okay to rename these functions now, before .0 is
released to get things in a better shape while addressing the issue
reported.
+extern LocalPgBackendStatus *pgstat_get_local_beentry_by_index(int beid);
Still I would to a bit more of s/beid/id/ for cases where the code
refers to an index ID, and not a backend ID, especially for the
internal routines.
--
Michael
On Wed, Aug 30, 2023 at 08:22:27AM +0900, Michael Paquier wrote:
On Tue, Aug 29, 2023 at 09:46:55AM -0700, Nathan Bossart wrote:
This was my first reaction [0]. I was concerned about renaming the
exported functions so close to release, so I was suggesting that we hold
off on that part until v17. If there isn't a concern with renaming these
functions in v16, I can proceed with something more like v2.Thanks for the pointer. This version is much better IMO, because it
removes entirely the source of the confusion between the difference in
backend ID and index ID treatments when fetching the local entries in
the array. So I'm okay to rename these functions now, before .0 is
released to get things in a better shape while addressing the issue
reported.
Okay.
+extern LocalPgBackendStatus *pgstat_get_local_beentry_by_index(int beid);
Still I would to a bit more of s/beid/id/ for cases where the code
refers to an index ID, and not a backend ID, especially for the
internal routines.
Makes sense. I did this in v4.
--
Nathan Bossart
Amazon Web Services: https://aws.amazon.com
Attachments:
v4-0001-rename-some-pgstat-functions.patchtext/x-diff; charset=us-asciiDownload
From 3e360c1b970526079528159fe1c49be03d0b13b5 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Thu, 24 Aug 2023 07:42:54 -0700
Subject: [PATCH v4 1/2] rename some pgstat functions
---
src/backend/utils/activity/backend_status.c | 28 ++++++++--------
src/backend/utils/adt/pgstatfuncs.c | 36 ++++++++++-----------
src/include/utils/backend_status.h | 4 +--
3 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c
index 38f91a495b..a4860b10fc 100644
--- a/src/backend/utils/activity/backend_status.c
+++ b/src/backend/utils/activity/backend_status.c
@@ -849,8 +849,8 @@ pgstat_read_current_status(void)
/*
* The BackendStatusArray index is exactly the BackendId of the
* source backend. Note that this means localBackendStatusTable
- * is in order by backend_id. pgstat_fetch_stat_beentry() depends
- * on that.
+ * is in order by backend_id. pgstat_get_beentry_by_backend_id()
+ * depends on that.
*/
localentry->backend_id = i;
BackendIdGetTransactionIds(i,
@@ -1073,21 +1073,21 @@ cmp_lbestatus(const void *a, const void *b)
}
/* ----------
- * pgstat_fetch_stat_beentry() -
+ * pgstat_get_beentry_by_backend_id() -
*
* Support function for the SQL-callable pgstat* functions. Returns
* our local copy of the current-activity entry for one backend,
* or NULL if the given beid doesn't identify any known session.
*
* The beid argument is the BackendId of the desired session
- * (note that this is unlike pgstat_fetch_stat_local_beentry()).
+ * (note that this is unlike pgstat_get_local_beentry_by_index()).
*
* NB: caller is responsible for a check if the user is permitted to see
* this info (especially the querystring).
* ----------
*/
PgBackendStatus *
-pgstat_fetch_stat_beentry(BackendId beid)
+pgstat_get_beentry_by_backend_id(BackendId beid)
{
LocalPgBackendStatus key;
LocalPgBackendStatus *ret;
@@ -1111,13 +1111,13 @@ pgstat_fetch_stat_beentry(BackendId beid)
/* ----------
- * pgstat_fetch_stat_local_beentry() -
+ * pgstat_get_local_beentry_by_index() -
*
- * Like pgstat_fetch_stat_beentry() but with locally computed additions (like
- * xid and xmin values of the backend)
+ * Like pgstat_get_beentry_by_backend_id() but with locally computed additions
+ * (like xid and xmin values of the backend)
*
- * The beid argument is a 1-based index in the localBackendStatusTable
- * (note that this is unlike pgstat_fetch_stat_beentry()).
+ * The idx argument is a 1-based index in the localBackendStatusTable
+ * (note that this is unlike pgstat_get_beentry_by_backend_id()).
* Returns NULL if the argument is out of range (no current caller does that).
*
* NB: caller is responsible for a check if the user is permitted to see
@@ -1125,14 +1125,14 @@ pgstat_fetch_stat_beentry(BackendId beid)
* ----------
*/
LocalPgBackendStatus *
-pgstat_fetch_stat_local_beentry(int beid)
+pgstat_get_local_beentry_by_index(int idx)
{
pgstat_read_current_status();
- if (beid < 1 || beid > localNumBackends)
+ if (idx < 1 || idx > localNumBackends)
return NULL;
- return &localBackendStatusTable[beid - 1];
+ return &localBackendStatusTable[idx - 1];
}
@@ -1141,7 +1141,7 @@ pgstat_fetch_stat_local_beentry(int beid)
*
* Support function for the SQL-callable pgstat* functions. Returns
* the number of sessions known in the localBackendStatusTable, i.e.
- * the maximum 1-based index to pass to pgstat_fetch_stat_local_beentry().
+ * the maximum 1-based index to pass to pgstat_get_local_beentry_by_index().
* ----------
*/
int
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 2b9742ad21..49cc887b97 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -211,7 +211,7 @@ pg_stat_get_backend_idset(PG_FUNCTION_ARGS)
if (fctx[0] <= pgstat_fetch_stat_numbackends())
{
/* do when there is more left to send */
- LocalPgBackendStatus *local_beentry = pgstat_fetch_stat_local_beentry(fctx[0]);
+ LocalPgBackendStatus *local_beentry = pgstat_get_local_beentry_by_index(fctx[0]);
SRF_RETURN_NEXT(funcctx, Int32GetDatum(local_beentry->backend_id));
}
@@ -264,7 +264,7 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS)
bool nulls[PG_STAT_GET_PROGRESS_COLS] = {0};
int i;
- local_beentry = pgstat_fetch_stat_local_beentry(curr_backend);
+ local_beentry = pgstat_get_local_beentry_by_index(curr_backend);
beentry = &local_beentry->backendStatus;
/*
@@ -325,7 +325,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
const char *wait_event = NULL;
/* Get the next one in the list */
- local_beentry = pgstat_fetch_stat_local_beentry(curr_backend);
+ local_beentry = pgstat_get_local_beentry_by_index(curr_backend);
beentry = &local_beentry->backendStatus;
/* If looking for specific PID, ignore all the others */
@@ -672,7 +672,7 @@ pg_stat_get_backend_pid(PG_FUNCTION_ARGS)
int32 beid = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
PG_RETURN_NULL();
PG_RETURN_INT32(beentry->st_procpid);
@@ -685,7 +685,7 @@ pg_stat_get_backend_dbid(PG_FUNCTION_ARGS)
int32 beid = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
PG_RETURN_NULL();
PG_RETURN_OID(beentry->st_databaseid);
@@ -698,7 +698,7 @@ pg_stat_get_backend_userid(PG_FUNCTION_ARGS)
int32 beid = PG_GETARG_INT32(0);
PgBackendStatus *beentry;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
PG_RETURN_NULL();
PG_RETURN_OID(beentry->st_userid);
@@ -727,7 +727,7 @@ pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
BlessTupleDesc(tupdesc);
- if ((local_beentry = pgstat_fetch_stat_local_beentry(beid)) != NULL)
+ if ((local_beentry = pgstat_get_local_beentry_by_index(beid)) != NULL)
{
/* Fill values and NULLs */
values[0] = Int32GetDatum(local_beentry->backend_subxact_count);
@@ -752,7 +752,7 @@ pg_stat_get_backend_activity(PG_FUNCTION_ARGS)
char *clipped_activity;
text *ret;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
activity = "<backend information not available>";
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
activity = "<insufficient privilege>";
@@ -776,7 +776,7 @@ pg_stat_get_backend_wait_event_type(PG_FUNCTION_ARGS)
PGPROC *proc;
const char *wait_event_type = NULL;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
wait_event_type = "<backend information not available>";
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
wait_event_type = "<insufficient privilege>";
@@ -797,7 +797,7 @@ pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS)
PGPROC *proc;
const char *wait_event = NULL;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
wait_event = "<backend information not available>";
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
wait_event = "<insufficient privilege>";
@@ -818,7 +818,7 @@ pg_stat_get_backend_activity_start(PG_FUNCTION_ARGS)
TimestampTz result;
PgBackendStatus *beentry;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
PG_RETURN_NULL();
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
@@ -844,7 +844,7 @@ pg_stat_get_backend_xact_start(PG_FUNCTION_ARGS)
TimestampTz result;
PgBackendStatus *beentry;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
PG_RETURN_NULL();
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
@@ -866,7 +866,7 @@ pg_stat_get_backend_start(PG_FUNCTION_ARGS)
TimestampTz result;
PgBackendStatus *beentry;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
PG_RETURN_NULL();
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
@@ -890,7 +890,7 @@ pg_stat_get_backend_client_addr(PG_FUNCTION_ARGS)
char remote_host[NI_MAXHOST];
int ret;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
PG_RETURN_NULL();
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
@@ -935,7 +935,7 @@ pg_stat_get_backend_client_port(PG_FUNCTION_ARGS)
char remote_port[NI_MAXSERV];
int ret;
- if ((beentry = pgstat_fetch_stat_beentry(beid)) == NULL)
+ if ((beentry = pgstat_get_beentry_by_backend_id(beid)) == NULL)
PG_RETURN_NULL();
else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
@@ -978,12 +978,12 @@ pg_stat_get_db_numbackends(PG_FUNCTION_ARGS)
Oid dbid = PG_GETARG_OID(0);
int32 result;
int tot_backends = pgstat_fetch_stat_numbackends();
- int beid;
+ int idx;
result = 0;
- for (beid = 1; beid <= tot_backends; beid++)
+ for (idx = 1; idx <= tot_backends; idx++)
{
- LocalPgBackendStatus *local_beentry = pgstat_fetch_stat_local_beentry(beid);
+ LocalPgBackendStatus *local_beentry = pgstat_get_local_beentry_by_index(idx);
if (local_beentry->backendStatus.st_databaseid == dbid)
result++;
diff --git a/src/include/utils/backend_status.h b/src/include/utils/backend_status.h
index 77939a0aed..1718ff7ce6 100644
--- a/src/include/utils/backend_status.h
+++ b/src/include/utils/backend_status.h
@@ -333,8 +333,8 @@ extern uint64 pgstat_get_my_query_id(void);
* ----------
*/
extern int pgstat_fetch_stat_numbackends(void);
-extern PgBackendStatus *pgstat_fetch_stat_beentry(BackendId beid);
-extern LocalPgBackendStatus *pgstat_fetch_stat_local_beentry(int beid);
+extern PgBackendStatus *pgstat_get_beentry_by_backend_id(BackendId beid);
+extern LocalPgBackendStatus *pgstat_get_local_beentry_by_index(int idx);
extern char *pgstat_clip_activity(const char *raw_activity);
--
2.25.1
v4-0002-fix-pg_stat_get_backend_subxact-to-use-real-backe.patchtext/x-diff; charset=us-asciiDownload
From dc162a99a94e7c5483bfb77c40dac877e0ed5682 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Thu, 24 Aug 2023 07:58:01 -0700
Subject: [PATCH v4 2/2] fix pg_stat_get_backend_subxact to use real backend id
---
src/backend/utils/activity/backend_status.c | 36 +++++++++++++++------
src/backend/utils/adt/pgstatfuncs.c | 2 +-
src/include/utils/backend_status.h | 1 +
3 files changed, 29 insertions(+), 10 deletions(-)
diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c
index a4860b10fc..722c5acf38 100644
--- a/src/backend/utils/activity/backend_status.c
+++ b/src/backend/utils/activity/backend_status.c
@@ -1088,9 +1088,33 @@ cmp_lbestatus(const void *a, const void *b)
*/
PgBackendStatus *
pgstat_get_beentry_by_backend_id(BackendId beid)
+{
+ LocalPgBackendStatus *ret = pgstat_get_local_beentry_by_backend_id(beid);
+
+ if (ret)
+ return &ret->backendStatus;
+
+ return NULL;
+}
+
+
+/* ----------
+ * pgstat_get_local_beentry_by_backend_id() -
+ *
+ * Like pgstat_get_beentry_by_backend_id() but with locally computed additions
+ * (like xid and xmin values of the backend)
+ *
+ * The beid argument is the BackendId of the desired session
+ * (note that this is unlike pgstat_get_local_beentry_by_index()).
+ *
+ * NB: caller is responsible for checking if the user is permitted to see this
+ * info (especially the querystring).
+ * ----------
+ */
+LocalPgBackendStatus *
+pgstat_get_local_beentry_by_backend_id(BackendId beid)
{
LocalPgBackendStatus key;
- LocalPgBackendStatus *ret;
pgstat_read_current_status();
@@ -1099,14 +1123,8 @@ pgstat_get_beentry_by_backend_id(BackendId beid)
* bsearch() to search it efficiently.
*/
key.backend_id = beid;
- ret = (LocalPgBackendStatus *) bsearch(&key, localBackendStatusTable,
- localNumBackends,
- sizeof(LocalPgBackendStatus),
- cmp_lbestatus);
- if (ret)
- return &ret->backendStatus;
-
- return NULL;
+ return bsearch(&key, localBackendStatusTable, localNumBackends,
+ sizeof(LocalPgBackendStatus), cmp_lbestatus);
}
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 49cc887b97..dd5094a2d4 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -727,7 +727,7 @@ pg_stat_get_backend_subxact(PG_FUNCTION_ARGS)
BlessTupleDesc(tupdesc);
- if ((local_beentry = pgstat_get_local_beentry_by_index(beid)) != NULL)
+ if ((local_beentry = pgstat_get_local_beentry_by_backend_id(beid)) != NULL)
{
/* Fill values and NULLs */
values[0] = Int32GetDatum(local_beentry->backend_subxact_count);
diff --git a/src/include/utils/backend_status.h b/src/include/utils/backend_status.h
index 1718ff7ce6..d51c840daf 100644
--- a/src/include/utils/backend_status.h
+++ b/src/include/utils/backend_status.h
@@ -334,6 +334,7 @@ extern uint64 pgstat_get_my_query_id(void);
*/
extern int pgstat_fetch_stat_numbackends(void);
extern PgBackendStatus *pgstat_get_beentry_by_backend_id(BackendId beid);
+extern LocalPgBackendStatus *pgstat_get_local_beentry_by_backend_id(BackendId beid);
extern LocalPgBackendStatus *pgstat_get_local_beentry_by_index(int idx);
extern char *pgstat_clip_activity(const char *raw_activity);
--
2.25.1
On Tue, Aug 29, 2023 at 07:01:51PM -0700, Nathan Bossart wrote:
On Wed, Aug 30, 2023 at 08:22:27AM +0900, Michael Paquier wrote:
+extern LocalPgBackendStatus *pgstat_get_local_beentry_by_index(int beid);
Still I would to a bit more of s/beid/id/ for cases where the code
refers to an index ID, and not a backend ID, especially for the
internal routines.Makes sense. I did this in v4.
Yep, that looks more consistent, at quick glance.
--
Michael
On Wed, Aug 30, 2023 at 12:13 AM Michael Paquier <michael@paquier.xyz> wrote:
Yep, that looks more consistent, at quick glance.
Sorry, I'm only just noticing this thread. Thanks, Nathan, Ian, and
others, for your work on this. Apart from hoping that the 0002 patch
will get a more detailed commit message spelling out the problem very
explicitly, I don't have any comments on the proposed patches.
--
Robert Haas
EDB: http://www.enterprisedb.com
On Wed, Aug 30, 2023 at 09:50:41AM -0400, Robert Haas wrote:
Sorry, I'm only just noticing this thread. Thanks, Nathan, Ian, and
others, for your work on this. Apart from hoping that the 0002 patch
will get a more detailed commit message spelling out the problem very
explicitly, I don't have any comments on the proposed patches.
I'm about to spend way too much time writing the commit message for 0002,
but I plan to commit both patches sometime today.
--
Nathan Bossart
Amazon Web Services: https://aws.amazon.com
On Wed, Aug 30, 2023 at 10:27 AM Nathan Bossart
<nathandbossart@gmail.com> wrote:
On Wed, Aug 30, 2023 at 09:50:41AM -0400, Robert Haas wrote:
Sorry, I'm only just noticing this thread. Thanks, Nathan, Ian, and
others, for your work on this. Apart from hoping that the 0002 patch
will get a more detailed commit message spelling out the problem very
explicitly, I don't have any comments on the proposed patches.I'm about to spend way too much time writing the commit message for 0002,
but I plan to commit both patches sometime today.
Thanks! I'm glad your committing the patches, and I approve of you
spending way too much time on the commit message. :-)
--
Robert Haas
EDB: http://www.enterprisedb.com
On Wed, Aug 30, 2023 at 10:56:22AM -0400, Robert Haas wrote:
On Wed, Aug 30, 2023 at 10:27 AM Nathan Bossart
<nathandbossart@gmail.com> wrote:I'm about to spend way too much time writing the commit message for 0002,
but I plan to commit both patches sometime today.Thanks! I'm glad your committing the patches, and I approve of you
spending way too much time on the commit message. :-)
Committed.
--
Nathan Bossart
Amazon Web Services: https://aws.amazon.com
On Wed, Aug 30, 2023 at 02:56:48PM -0700, Nathan Bossart wrote:
Committed.
Cool, thanks!
--
Michael
On Thu, Aug 31, 2023 at 4:38 AM Nathan Bossart <nathandbossart@gmail.com> wrote:
On Wed, Aug 30, 2023 at 10:56:22AM -0400, Robert Haas wrote:
On Wed, Aug 30, 2023 at 10:27 AM Nathan Bossart
<nathandbossart@gmail.com> wrote:I'm about to spend way too much time writing the commit message for 0002,
but I plan to commit both patches sometime today.Thanks! I'm glad your committing the patches, and I approve of you
spending way too much time on the commit message. :-)Committed.
Sorry, I didn't notice this thread earlier. The new behavior looks
better to me, thanks for working on it.
--
Regards,
Dilip Kumar
EnterpriseDB: http://www.enterprisedb.com
2023年8月31日(木) 6:56 Nathan Bossart <nathandbossart@gmail.com>:
On Wed, Aug 30, 2023 at 10:56:22AM -0400, Robert Haas wrote:
On Wed, Aug 30, 2023 at 10:27 AM Nathan Bossart
<nathandbossart@gmail.com> wrote:I'm about to spend way too much time writing the commit message for 0002,
but I plan to commit both patches sometime today.Thanks! I'm glad your committing the patches, and I approve of you
spending way too much time on the commit message. :-)Committed.
Thanks for taking care of this (saw the commits, then got distracted
by something else and forgot to follow up).
Regards
Ian Barwick