From f7d3b3854ece45b2ba3b79643e99c1acbb09abae Mon Sep 17 00:00:00 2001 From: Karoline Pauls Date: Wed, 8 May 2024 23:49:46 +0100 Subject: [PATCH] call pgstat_get_backend_current_activity once --- src/backend/storage/lmgr/deadlock.c | 31 +++++++++++++-------- src/backend/utils/activity/backend_status.c | 10 +++---- src/include/utils/backend_status.h | 4 ++- src/tools/pgindent/typedefs.list | 1 + 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/backend/storage/lmgr/deadlock.c b/src/backend/storage/lmgr/deadlock.c index d94f65df..c08f66af 100644 --- a/src/backend/storage/lmgr/deadlock.c +++ b/src/backend/storage/lmgr/deadlock.c @@ -1075,17 +1075,22 @@ DeadLockReport(void) StringInfoData logbuf; /* errdetail for server log */ StringInfoData locktagbuf; int i; + bool isSuperuser = superuser(); + LocalPgBackendCurrentActivity *activities = \ + (LocalPgBackendCurrentActivity *) palloc(sizeof(LocalPgBackendCurrentActivity) * nDeadlockDetails); initStringInfo(&clientbuf); initStringInfo(&logbuf); initStringInfo(&locktagbuf); - /* Generate the "waits for" lines sent to the client */ + /* Generate the "waits for" lines sent to the client and the log */ for (i = 0; i < nDeadlockDetails; i++) { DEADLOCK_INFO *info = &deadlockDetails[i]; int nextpid; - LocalPgBackendCurrentActivity activity = pgstat_get_backend_current_activity(info->pid, true); + const char *lockModeName = GetLockmodeName(info->locktag.locktag_lockmethodid, info->lockmode); + + activities[i] = pgstat_get_backend_current_activity(info->pid); /* The last proc waits for the first one... */ if (i < nDeadlockDetails - 1) @@ -1104,29 +1109,33 @@ DeadLockReport(void) appendStringInfo(&clientbuf, _("Process %d (application_name: %s) waits for %s on %s; blocked by process %d."), info->pid, - activity.st_appname, - GetLockmodeName(info->locktag.locktag_lockmethodid, - info->lockmode), + (activities[i].sameUser || isSuperuser) ? activities[i].st_appname : "", + lockModeName, locktagbuf.data, nextpid); - } - /* Duplicate all the above for the server ... */ - appendBinaryStringInfo(&logbuf, clientbuf.data, clientbuf.len); + /* the difference is that we don't do user checking for the server log */ + appendStringInfo(&logbuf, + _("Process %d (application_name: %s) waits for %s on %s; blocked by process %d."), + info->pid, + activities[i].st_appname, + lockModeName, + locktagbuf.data, + nextpid); + } /* ... and add info about query strings */ for (i = 0; i < nDeadlockDetails; i++) { DEADLOCK_INFO *info = &deadlockDetails[i]; - LocalPgBackendCurrentActivity activity = pgstat_get_backend_current_activity(info->pid, false); appendStringInfoChar(&logbuf, '\n'); appendStringInfo(&logbuf, _("Process %d, (application_name: %s): %s"), info->pid, - activity.st_appname, - activity.st_activity); + activities[i].st_appname, + activities[i].st_activity); } pgstat_report_deadlock(); diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c index 1703aa79..6ccc76ae 100644 --- a/src/backend/utils/activity/backend_status.c +++ b/src/backend/utils/activity/backend_status.c @@ -882,11 +882,11 @@ pgstat_read_current_status(void) * ---------- */ struct LocalPgBackendCurrentActivity -pgstat_get_backend_current_activity(int pid, bool checkUser) +pgstat_get_backend_current_activity(int pid) { PgBackendStatus *beentry; int i; - LocalPgBackendCurrentActivity activity = {"", ""}; + LocalPgBackendCurrentActivity activity = {"?", "", false}; beentry = BackendStatusArray; for (i = 1; i <= MaxBackends; i++) @@ -926,9 +926,9 @@ pgstat_get_backend_current_activity(int pid, bool checkUser) if (found) { /* Now it is safe to use the non-volatile pointer */ - if (checkUser && !superuser() && beentry->st_userid != GetUserId()) - activity.st_activity = ""; - else if (*(beentry->st_activity_raw) == '\0') + activity.sameUser = beentry->st_userid != GetUserId(); + + if (*(beentry->st_activity_raw) == '\0') activity.st_activity = ""; else { diff --git a/src/include/utils/backend_status.h b/src/include/utils/backend_status.h index a2110a8a..08d1b026 100644 --- a/src/include/utils/backend_status.h +++ b/src/include/utils/backend_status.h @@ -283,6 +283,8 @@ typedef struct LocalPgBackendCurrentActivity { char *st_appname; char *st_activity; + /* true if the activity user is the caller user */ + bool sameUser; } LocalPgBackendCurrentActivity; /* ---------- @@ -325,7 +327,7 @@ extern void pgstat_report_query_id(uint64 query_id, bool force); extern void pgstat_report_tempfile(size_t filesize); extern void pgstat_report_appname(const char *appname); extern void pgstat_report_xact_timestamp(TimestampTz tstamp); -extern LocalPgBackendCurrentActivity pgstat_get_backend_current_activity(int pid, bool checkUser); +extern LocalPgBackendCurrentActivity pgstat_get_backend_current_activity(int pid); extern const char *pgstat_get_crashed_backend_activity(int pid, char *buffer, int buflen); extern uint64 pgstat_get_my_query_id(void); diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 2311f82d..f50c8935 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -1492,6 +1492,7 @@ ListenStmt LoInfo LoadStmt LocalBufferLookupEnt +LocalPgBackendCurrentActivity LocalPgBackendStatus LocalTransactionId LocationIndex -- 2.34.1