Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 6e07228

Browse files
committed
Code review for log_lock_waits patch. Don't try to issue log messages from
within a signal handler (this might be safe given the relatively narrow code range in which the interrupt is enabled, but it seems awfully risky); do issue more informative log messages that tell what is being waited for and the exact length of the wait; minor other code cleanup. Greg Stark and Tom Lane
1 parent 4c310ec commit 6e07228

File tree

7 files changed

+229
-155
lines changed

7 files changed

+229
-155
lines changed

doc/src/sgml/config.sgml

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.126 2007/06/07 19:19:56 tgl Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.127 2007/06/19 20:13:21 tgl Exp $ -->
22

33
<chapter Id="runtime-config">
44
<title>Server Configuration</title>
@@ -2947,7 +2947,7 @@ SELECT * FROM parent WHERE key = 2400;
29472947
</indexterm>
29482948
<listitem>
29492949
<para>
2950-
Controls whether a log message is produced when a statement waits
2950+
Controls whether a log message is produced when a session waits
29512951
longer than <xref linkend="guc-deadlock-timeout"> to acquire a
29522952
lock. This is useful in determining if lock waits are causing
29532953
poor performance. The default is <literal>off</>.
@@ -4084,11 +4084,18 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
40844084
wasted in needless deadlock checks, but slows down reporting of
40854085
real deadlock errors. The default is one second (<literal>1s</>),
40864086
which is probably about the smallest value you would want in
4087-
practice. Set <xref linkend="guc-log-lock-waits"> to log deadlock
4088-
checks. On a heavily loaded server you might want to raise it.
4087+
practice. On a heavily loaded server you might want to raise it.
40894088
Ideally the setting should exceed your typical transaction time,
4090-
so as to improve the odds that a lock will be released before the
4091-
waiter decides to check for deadlock.
4089+
so as to improve the odds that a lock will be released before
4090+
the waiter decides to check for deadlock.
4091+
</para>
4092+
4093+
<para>
4094+
When <xref linkend="guc-log-lock-waits"> is set,
4095+
this parameter also determines the length of time to wait before
4096+
a log message is issued about the lock wait. If you are trying
4097+
to investigate locking delays you might want to set a shorter than
4098+
normal <varname>deadlock_timeout</varname>.
40924099
</para>
40934100
</listitem>
40944101
</varlistentry>

src/backend/storage/lmgr/deadlock.c

Lines changed: 14 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*
1313
*
1414
* IDENTIFICATION
15-
* $PostgreSQL: pgsql/src/backend/storage/lmgr/deadlock.c,v 1.47 2007/04/20 20:15:52 momjian Exp $
15+
* $PostgreSQL: pgsql/src/backend/storage/lmgr/deadlock.c,v 1.48 2007/06/19 20:13:21 tgl Exp $
1616
*
1717
* Interface:
1818
*
@@ -25,8 +25,8 @@
2525
*/
2626
#include "postgres.h"
2727

28-
#include "lib/stringinfo.h"
2928
#include "miscadmin.h"
29+
#include "storage/lmgr.h"
3030
#include "storage/proc.h"
3131
#include "utils/memutils.h"
3232

@@ -117,8 +117,9 @@ static int nDeadlockDetails;
117117
* allocation of working memory for DeadLockCheck. We do this per-backend
118118
* since there's no percentage in making the kernel do copy-on-write
119119
* inheritance of workspace from the postmaster. We want to allocate the
120-
* space at startup because the deadlock checker might be invoked when there's
121-
* no free memory left.
120+
* space at startup because (a) the deadlock checker might be invoked when
121+
* there's no free memory left, and (b) the checker is normally run inside a
122+
* signal handler, which is a very dangerous place to invoke palloc from.
122123
*/
123124
void
124125
InitDeadLockChecking(void)
@@ -184,17 +185,17 @@ InitDeadLockChecking(void)
184185
*
185186
* This code looks for deadlocks involving the given process. If any
186187
* are found, it tries to rearrange lock wait queues to resolve the
187-
* deadlock. If resolution is impossible, return TRUE --- the caller
188-
* is then expected to abort the given proc's transaction.
188+
* deadlock. If resolution is impossible, return DS_HARD_DEADLOCK ---
189+
* the caller is then expected to abort the given proc's transaction.
189190
*
190-
* Caller must already have locked all partitions of the lock tables,
191-
* so standard error logging/reporting code is handled by caller.
191+
* Caller must already have locked all partitions of the lock tables.
192192
*
193193
* On failure, deadlock details are recorded in deadlockDetails[] for
194194
* subsequent printing by DeadLockReport(). That activity is separate
195-
* because we don't want to do it while holding all those LWLocks.
195+
* because (a) we don't want to do it while holding all those LWLocks,
196+
* and (b) we are typically invoked inside a signal handler.
196197
*/
197-
DeadlockState
198+
DeadLockState
198199
DeadLockCheck(PGPROC *proc)
199200
{
200201
int i,
@@ -205,11 +206,6 @@ DeadLockCheck(PGPROC *proc)
205206
nPossibleConstraints = 0;
206207
nWaitOrders = 0;
207208

208-
#ifdef LOCK_DEBUG
209-
if (Debug_deadlocks)
210-
DumpAllLocks();
211-
#endif
212-
213209
/* Search for deadlocks and possible fixes */
214210
if (DeadLockCheckRecurse(proc))
215211
{
@@ -256,10 +252,11 @@ DeadLockCheck(PGPROC *proc)
256252
ProcLockWakeup(GetLocksMethodTable(lock), lock);
257253
}
258254

255+
/* Return code tells caller if we had to escape a deadlock or not */
259256
if (nWaitOrders > 0)
260257
return DS_SOFT_DEADLOCK;
261258
else
262-
return DS_DEADLOCK_NOT_FOUND;
259+
return DS_NO_DEADLOCK;
263260
}
264261

265262
/*
@@ -833,82 +830,7 @@ PrintLockQueue(LOCK *lock, const char *info)
833830
#endif
834831

835832
/*
836-
* Append a description of a lockable object to buf.
837-
*
838-
* XXX probably this should be exported from lmgr.c or some such place.
839-
* Ideally we would print names for the numeric values, but that requires
840-
* getting locks on system tables, which might cause problems.
841-
*/
842-
static void
843-
DescribeLockTag(StringInfo buf, const LOCKTAG *lock)
844-
{
845-
switch (lock->locktag_type)
846-
{
847-
case LOCKTAG_RELATION:
848-
appendStringInfo(buf,
849-
_("relation %u of database %u"),
850-
lock->locktag_field2,
851-
lock->locktag_field1);
852-
break;
853-
case LOCKTAG_RELATION_EXTEND:
854-
appendStringInfo(buf,
855-
_("extension of relation %u of database %u"),
856-
lock->locktag_field2,
857-
lock->locktag_field1);
858-
break;
859-
case LOCKTAG_PAGE:
860-
appendStringInfo(buf,
861-
_("page %u of relation %u of database %u"),
862-
lock->locktag_field3,
863-
lock->locktag_field2,
864-
lock->locktag_field1);
865-
break;
866-
case LOCKTAG_TUPLE:
867-
appendStringInfo(buf,
868-
_("tuple (%u,%u) of relation %u of database %u"),
869-
lock->locktag_field3,
870-
lock->locktag_field4,
871-
lock->locktag_field2,
872-
lock->locktag_field1);
873-
break;
874-
case LOCKTAG_TRANSACTION:
875-
appendStringInfo(buf,
876-
_("transaction %u"),
877-
lock->locktag_field1);
878-
break;
879-
case LOCKTAG_OBJECT:
880-
appendStringInfo(buf,
881-
_("object %u of class %u of database %u"),
882-
lock->locktag_field3,
883-
lock->locktag_field2,
884-
lock->locktag_field1);
885-
break;
886-
case LOCKTAG_USERLOCK:
887-
/* reserved for old contrib code, now on pgfoundry */
888-
appendStringInfo(buf,
889-
_("user lock [%u,%u,%u]"),
890-
lock->locktag_field1,
891-
lock->locktag_field2,
892-
lock->locktag_field3);
893-
break;
894-
case LOCKTAG_ADVISORY:
895-
appendStringInfo(buf,
896-
_("advisory lock [%u,%u,%u,%u]"),
897-
lock->locktag_field1,
898-
lock->locktag_field2,
899-
lock->locktag_field3,
900-
lock->locktag_field4);
901-
break;
902-
default:
903-
appendStringInfo(buf,
904-
_("unrecognized locktag type %d"),
905-
lock->locktag_type);
906-
break;
907-
}
908-
}
909-
910-
/*
911-
* Report a detected DS_HARD_DEADLOCK, with available details.
833+
* Report a detected deadlock, with available details.
912834
*/
913835
void
914836
DeadLockReport(void)

src/backend/storage/lmgr/lmgr.c

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.90 2007/01/05 22:19:38 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.91 2007/06/19 20:13:21 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -635,3 +635,79 @@ LockTagIsTemp(const LOCKTAG *tag)
635635
}
636636
return false; /* default case */
637637
}
638+
639+
640+
/*
641+
* Append a description of a lockable object to buf.
642+
*
643+
* Ideally we would print names for the numeric values, but that requires
644+
* getting locks on system tables, which might cause problems since this is
645+
* typically used to report deadlock situations.
646+
*/
647+
void
648+
DescribeLockTag(StringInfo buf, const LOCKTAG *tag)
649+
{
650+
switch (tag->locktag_type)
651+
{
652+
case LOCKTAG_RELATION:
653+
appendStringInfo(buf,
654+
_("relation %u of database %u"),
655+
tag->locktag_field2,
656+
tag->locktag_field1);
657+
break;
658+
case LOCKTAG_RELATION_EXTEND:
659+
appendStringInfo(buf,
660+
_("extension of relation %u of database %u"),
661+
tag->locktag_field2,
662+
tag->locktag_field1);
663+
break;
664+
case LOCKTAG_PAGE:
665+
appendStringInfo(buf,
666+
_("page %u of relation %u of database %u"),
667+
tag->locktag_field3,
668+
tag->locktag_field2,
669+
tag->locktag_field1);
670+
break;
671+
case LOCKTAG_TUPLE:
672+
appendStringInfo(buf,
673+
_("tuple (%u,%u) of relation %u of database %u"),
674+
tag->locktag_field3,
675+
tag->locktag_field4,
676+
tag->locktag_field2,
677+
tag->locktag_field1);
678+
break;
679+
case LOCKTAG_TRANSACTION:
680+
appendStringInfo(buf,
681+
_("transaction %u"),
682+
tag->locktag_field1);
683+
break;
684+
case LOCKTAG_OBJECT:
685+
appendStringInfo(buf,
686+
_("object %u of class %u of database %u"),
687+
tag->locktag_field3,
688+
tag->locktag_field2,
689+
tag->locktag_field1);
690+
break;
691+
case LOCKTAG_USERLOCK:
692+
/* reserved for old contrib code, now on pgfoundry */
693+
appendStringInfo(buf,
694+
_("user lock [%u,%u,%u]"),
695+
tag->locktag_field1,
696+
tag->locktag_field2,
697+
tag->locktag_field3);
698+
break;
699+
case LOCKTAG_ADVISORY:
700+
appendStringInfo(buf,
701+
_("advisory lock [%u,%u,%u,%u]"),
702+
tag->locktag_field1,
703+
tag->locktag_field2,
704+
tag->locktag_field3,
705+
tag->locktag_field4);
706+
break;
707+
default:
708+
appendStringInfo(buf,
709+
_("unrecognized locktag type %d"),
710+
tag->locktag_type);
711+
break;
712+
}
713+
}

0 commit comments

Comments
 (0)