Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit588fb50

Browse files
committed
Show PIDs of lock holders and waiters in log_lock_waits log message.
Christian Kruse, reviewed by Kumar Rajeev Rastogi.
1 parenta0b4c35 commit588fb50

File tree

4 files changed

+122
-5
lines changed

4 files changed

+122
-5
lines changed

‎doc/src/sgml/sources.sgml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,15 @@ ereport(ERROR,
249249
sent to the client.
250250
</para>
251251
</listitem>
252+
<listitem>
253+
<para>
254+
<function>errdetail_log_plural(const char *fmt_singuar, const char
255+
*fmt_plural, unsigned long n, ...)</function> is like
256+
<function>errdetail_log</>, but with support for various plural forms of
257+
the message.
258+
For more information see <xref linkend="nls-guidelines">.
259+
</para>
260+
</listitem>
252261
<listitem>
253262
<para>
254263
<function>errhint(const char *msg, ...)</function> supplies an optional

‎src/backend/storage/lmgr/proc.c

Lines changed: 83 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,13 +1208,23 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
12081208
*/
12091209
if (log_lock_waits&&deadlock_state!=DS_NOT_YET_CHECKED)
12101210
{
1211-
StringInfoDatabuf;
1211+
StringInfoDatabuf,
1212+
lock_waiters_sbuf,
1213+
lock_holders_sbuf;
12121214
constchar*modename;
12131215
longsecs;
12141216
intusecs;
12151217
longmsecs;
1218+
SHM_QUEUE*procLocks;
1219+
PROCLOCK*proclock;
1220+
boolfirst_holder= true,
1221+
first_waiter= true;
1222+
intlockHoldersNum=0;
12161223

12171224
initStringInfo(&buf);
1225+
initStringInfo(&lock_waiters_sbuf);
1226+
initStringInfo(&lock_holders_sbuf);
1227+
12181228
DescribeLockTag(&buf,&locallock->tag.lock);
12191229
modename=GetLockmodeName(locallock->tag.lock.locktag_lockmethodid,
12201230
lockmode);
@@ -1224,10 +1234,67 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
12241234
msecs=secs*1000+usecs /1000;
12251235
usecs=usecs %1000;
12261236

1237+
/*
1238+
* we loop over the lock's procLocks to gather a list of all
1239+
* holders and waiters. Thus we will be able to provide more
1240+
* detailed information for lock debugging purposes.
1241+
*
1242+
* lock->procLocks contains all processes which hold or wait for
1243+
* this lock.
1244+
*/
1245+
1246+
LWLockAcquire(partitionLock,LW_SHARED);
1247+
1248+
procLocks=&(lock->procLocks);
1249+
proclock= (PROCLOCK*)SHMQueueNext(procLocks,procLocks,
1250+
offsetof(PROCLOCK,lockLink));
1251+
1252+
while (proclock)
1253+
{
1254+
/*
1255+
* we are a waiter if myProc->waitProcLock == proclock; we are
1256+
* a holder if it is NULL or something different
1257+
*/
1258+
if (proclock->tag.myProc->waitProcLock==proclock)
1259+
{
1260+
if (first_waiter)
1261+
{
1262+
appendStringInfo(&lock_waiters_sbuf,"%d",
1263+
proclock->tag.myProc->pid);
1264+
first_waiter= false;
1265+
}
1266+
else
1267+
appendStringInfo(&lock_waiters_sbuf,", %d",
1268+
proclock->tag.myProc->pid);
1269+
}
1270+
else
1271+
{
1272+
if (first_holder)
1273+
{
1274+
appendStringInfo(&lock_holders_sbuf,"%d",
1275+
proclock->tag.myProc->pid);
1276+
first_holder= false;
1277+
}
1278+
else
1279+
appendStringInfo(&lock_holders_sbuf,", %d",
1280+
proclock->tag.myProc->pid);
1281+
1282+
lockHoldersNum++;
1283+
}
1284+
1285+
proclock= (PROCLOCK*)SHMQueueNext(procLocks,&proclock->lockLink,
1286+
offsetof(PROCLOCK,lockLink));
1287+
}
1288+
1289+
LWLockRelease(partitionLock);
1290+
12271291
if (deadlock_state==DS_SOFT_DEADLOCK)
12281292
ereport(LOG,
12291293
(errmsg("process %d avoided deadlock for %s on %s by rearranging queue order after %ld.%03d ms",
1230-
MyProcPid,modename,buf.data,msecs,usecs)));
1294+
MyProcPid,modename,buf.data,msecs,usecs),
1295+
(errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1296+
"Processes holding the lock: %s. Wait queue: %s.",
1297+
lockHoldersNum,lock_holders_sbuf.data,lock_waiters_sbuf.data))));
12311298
elseif (deadlock_state==DS_HARD_DEADLOCK)
12321299
{
12331300
/*
@@ -1239,13 +1306,19 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
12391306
*/
12401307
ereport(LOG,
12411308
(errmsg("process %d detected deadlock while waiting for %s on %s after %ld.%03d ms",
1242-
MyProcPid,modename,buf.data,msecs,usecs)));
1309+
MyProcPid,modename,buf.data,msecs,usecs),
1310+
(errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1311+
"Processes holding the lock: %s. Wait queue: %s.",
1312+
lockHoldersNum,lock_holders_sbuf.data,lock_waiters_sbuf.data))));
12431313
}
12441314

12451315
if (myWaitStatus==STATUS_WAITING)
12461316
ereport(LOG,
12471317
(errmsg("process %d still waiting for %s on %s after %ld.%03d ms",
1248-
MyProcPid,modename,buf.data,msecs,usecs)));
1318+
MyProcPid,modename,buf.data,msecs,usecs),
1319+
(errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1320+
"Processes holding the lock: %s. Wait queue: %s.",
1321+
lockHoldersNum,lock_holders_sbuf.data,lock_waiters_sbuf.data))));
12491322
elseif (myWaitStatus==STATUS_OK)
12501323
ereport(LOG,
12511324
(errmsg("process %d acquired %s on %s after %ld.%03d ms",
@@ -1265,7 +1338,10 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
12651338
if (deadlock_state!=DS_HARD_DEADLOCK)
12661339
ereport(LOG,
12671340
(errmsg("process %d failed to acquire %s on %s after %ld.%03d ms",
1268-
MyProcPid,modename,buf.data,msecs,usecs)));
1341+
MyProcPid,modename,buf.data,msecs,usecs),
1342+
(errdetail_log_plural("Process holding the lock: %s. Wait queue: %s.",
1343+
"Processes holding the lock: %s. Wait queue: %s.",
1344+
lockHoldersNum,lock_holders_sbuf.data,lock_waiters_sbuf.data))));
12691345
}
12701346

12711347
/*
@@ -1275,6 +1351,8 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
12751351
deadlock_state=DS_NO_DEADLOCK;
12761352

12771353
pfree(buf.data);
1354+
pfree(lock_holders_sbuf.data);
1355+
pfree(lock_waiters_sbuf.data);
12781356
}
12791357
}while (myWaitStatus==STATUS_WAITING);
12801358

‎src/backend/utils/error/elog.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,28 @@ errdetail_log(const char *fmt,...)
937937
return0;/* return value does not matter */
938938
}
939939

940+
/*
941+
* errdetail_log_plural --- add a detail_log error message text to the current error
942+
* with support for pluralization of the message text
943+
*/
944+
int
945+
errdetail_log_plural(constchar*fmt_singular,constchar*fmt_plural,
946+
unsigned longn,...)
947+
{
948+
ErrorData*edata=&errordata[errordata_stack_depth];
949+
MemoryContextoldcontext;
950+
951+
recursion_depth++;
952+
CHECK_STACK_DEPTH();
953+
oldcontext=MemoryContextSwitchTo(edata->assoc_context);
954+
955+
EVALUATE_MESSAGE_PLURAL(edata->domain,detail_log, false);
956+
957+
MemoryContextSwitchTo(oldcontext);
958+
recursion_depth--;
959+
return0;/* return value does not matter */
960+
}
961+
940962

941963
/*
942964
* errdetail_plural --- add a detail error message text to the current error,

‎src/include/utils/elog.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,14 @@ errdetail_log(const char *fmt,...)
181181
the supplied arguments. */
182182
__attribute__((format(PG_PRINTF_ATTRIBUTE,1,2)));
183183

184+
externint
185+
errdetail_log_plural(constchar*fmt_singular,constchar*fmt_plural,
186+
unsigned longn,...)
187+
/* This extension allows gcc to check the format string for consistency with
188+
the supplied arguments. */
189+
__attribute__((format(PG_PRINTF_ATTRIBUTE,1,4)))
190+
__attribute__((format(PG_PRINTF_ATTRIBUTE,2,4)));
191+
184192
externint
185193
errdetail_plural(constchar*fmt_singular,constchar*fmt_plural,
186194
unsigned longn,...)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp