Commit 9b8e1eb3 authored by Tom Lane's avatar Tom Lane

Adjust the recent patch for reporting of deadlocked queries so that we report

query texts only to the server log.  This eliminates the issue of possible
leaking of security-sensitive data in other sessions' queries.  Since the
log is presumed secure, we can now log the queries of all sessions involved
in the deadlock, whether or not they belong to the same user as the one
reporting the failure.
parent 05fc744b
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* Copyright (c) 2001-2008, PostgreSQL Global Development Group * Copyright (c) 2001-2008, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.170 2008/03/21 21:08:31 tgl Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.171 2008/03/24 18:22:36 tgl Exp $
* ---------- * ----------
*/ */
#include "postgres.h" #include "postgres.h"
...@@ -2056,7 +2056,7 @@ pgstat_read_current_status(void) ...@@ -2056,7 +2056,7 @@ pgstat_read_current_status(void)
* ---------- * ----------
*/ */
const char * const char *
pgstat_get_backend_current_activity(int pid) pgstat_get_backend_current_activity(int pid, bool checkUser)
{ {
PgBackendStatus *beentry; PgBackendStatus *beentry;
int i; int i;
...@@ -2094,7 +2094,7 @@ pgstat_get_backend_current_activity(int pid) ...@@ -2094,7 +2094,7 @@ pgstat_get_backend_current_activity(int pid)
if (found) if (found)
{ {
/* Now it is safe to use the non-volatile pointer */ /* Now it is safe to use the non-volatile pointer */
if (!superuser() && beentry->st_userid != GetUserId()) if (checkUser && !superuser() && beentry->st_userid != GetUserId())
return "<insufficient privilege>"; return "<insufficient privilege>";
else if (*(beentry->st_activity) == '\0') else if (*(beentry->st_activity) == '\0')
return "<command string not enabled>"; return "<command string not enabled>";
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/lmgr/deadlock.c,v 1.52 2008/03/21 21:08:31 tgl Exp $ * $PostgreSQL: pgsql/src/backend/storage/lmgr/deadlock.c,v 1.53 2008/03/24 18:22:36 tgl Exp $
* *
* Interface: * Interface:
* *
...@@ -879,15 +879,16 @@ PrintLockQueue(LOCK *lock, const char *info) ...@@ -879,15 +879,16 @@ PrintLockQueue(LOCK *lock, const char *info)
void void
DeadLockReport(void) DeadLockReport(void)
{ {
StringInfoData detailbuf; StringInfoData clientbuf; /* errdetail for client */
StringInfoData contextbuf; StringInfoData logbuf; /* errdetail for server log */
StringInfoData locktagbuf; StringInfoData locktagbuf;
int i; int i;
initStringInfo(&detailbuf); initStringInfo(&clientbuf);
initStringInfo(&contextbuf); initStringInfo(&logbuf);
initStringInfo(&locktagbuf); initStringInfo(&locktagbuf);
/* Generate the "waits for" lines sent to the client */
for (i = 0; i < nDeadlockDetails; i++) for (i = 0; i < nDeadlockDetails; i++)
{ {
DEADLOCK_INFO *info = &deadlockDetails[i]; DEADLOCK_INFO *info = &deadlockDetails[i];
...@@ -905,30 +906,39 @@ DeadLockReport(void) ...@@ -905,30 +906,39 @@ DeadLockReport(void)
DescribeLockTag(&locktagbuf, &info->locktag); DescribeLockTag(&locktagbuf, &info->locktag);
if (i > 0) if (i > 0)
appendStringInfoChar(&detailbuf, '\n'); appendStringInfoChar(&clientbuf, '\n');
appendStringInfo(&detailbuf, appendStringInfo(&clientbuf,
_("Process %d waits for %s on %s; blocked by process %d."), _("Process %d waits for %s on %s; blocked by process %d."),
info->pid, info->pid,
GetLockmodeName(info->locktag.locktag_lockmethodid, GetLockmodeName(info->locktag.locktag_lockmethodid,
info->lockmode), info->lockmode),
locktagbuf.data, locktagbuf.data,
nextpid); nextpid);
}
if (i > 0) /* Duplicate all the above for the server ... */
appendStringInfoChar(&contextbuf, '\n'); appendStringInfoString(&logbuf, clientbuf.data);
/* ... and add info about query strings */
for (i = 0; i < nDeadlockDetails; i++)
{
DEADLOCK_INFO *info = &deadlockDetails[i];
appendStringInfoChar(&logbuf, '\n');
appendStringInfo(&contextbuf, appendStringInfo(&logbuf,
_("Process %d: %s"), _("Process %d: %s"),
info->pid, info->pid,
pgstat_get_backend_current_activity(info->pid)); pgstat_get_backend_current_activity(info->pid, false));
} }
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_T_R_DEADLOCK_DETECTED), (errcode(ERRCODE_T_R_DEADLOCK_DETECTED),
errmsg("deadlock detected"), errmsg("deadlock detected"),
errdetail("%s", detailbuf.data), errdetail("%s", clientbuf.data),
errcontext("%s", contextbuf.data))); errdetail_log("%s", logbuf.data),
errhint("See server log for query details.")));
} }
/* /*
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Copyright (c) 2001-2008, PostgreSQL Global Development Group * Copyright (c) 2001-2008, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/include/pgstat.h,v 1.72 2008/03/21 21:08:31 tgl Exp $ * $PostgreSQL: pgsql/src/include/pgstat.h,v 1.73 2008/03/24 18:22:36 tgl Exp $
* ---------- * ----------
*/ */
#ifndef PGSTAT_H #ifndef PGSTAT_H
...@@ -507,7 +507,7 @@ extern void pgstat_bestart(void); ...@@ -507,7 +507,7 @@ extern void pgstat_bestart(void);
extern void pgstat_report_activity(const char *what); extern void pgstat_report_activity(const char *what);
extern void pgstat_report_xact_timestamp(TimestampTz tstamp); extern void pgstat_report_xact_timestamp(TimestampTz tstamp);
extern void pgstat_report_waiting(bool waiting); extern void pgstat_report_waiting(bool waiting);
extern const char *pgstat_get_backend_current_activity(int pid); extern const char *pgstat_get_backend_current_activity(int pid, bool checkUser);
extern void pgstat_initstats(Relation rel); extern void pgstat_initstats(Relation rel);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment