git.postgresql.org Git - postgresql.git/commitdiff

git projects / postgresql.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: efe2222)
Add some optional code (conditionally compiled under #ifdef LWLOCK_STATS)
2006年4月21日 16:45:12 +0000 (16:45 +0000)
2006年4月21日 16:45:12 +0000 (16:45 +0000)
to track the number of LWLock acquisitions and the number of times we
block waiting for an LWLock, on a per-process basis. After having needed
this twice in the past few months, seems like it should go into CVS.


diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index a2a6592d5a0479073af4c6ca65bb5bbbff0da0cd..f63318cf0e47fd687ee3cdf1b3766c8d2a9bf320 100644 (file)
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/lmgr/lwlock.c,v 1.38 2006年03月05日 15:58:39 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/lmgr/lwlock.c,v 1.39 2006年04月21日 16:45:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,6 +25,7 @@
#include "access/multixact.h"
#include "access/subtrans.h"
#include "miscadmin.h"
+#include "storage/ipc.h"
#include "storage/lwlock.h"
#include "storage/proc.h"
#include "storage/spin.h"
@@ -84,6 +85,13 @@ NON_EXEC_STATIC LWLockPadded *LWLockArray = NULL;
static int num_held_lwlocks = 0;
static LWLockId held_lwlocks[MAX_SIMUL_LWLOCKS];
+#ifdef LWLOCK_STATS
+static int counts_for_pid = 0;
+static int *sh_acquire_counts;
+static int *ex_acquire_counts;
+static int *block_counts;
+#endif
+
#ifdef LOCK_DEBUG
bool Trace_lwlocks = false;
@@ -109,6 +117,31 @@ LOG_LWDEBUG(const char *where, LWLockId lockid, const char *msg)
#define LOG_LWDEBUG(a,b,c)
#endif /* LOCK_DEBUG */
+#ifdef LWLOCK_STATS
+
+static void
+print_lwlock_stats(int code, Datum arg)
+{
+ int i;
+ int *LWLockCounter = (int *) ((char *) LWLockArray - 2 * sizeof(int));
+ int numLocks = LWLockCounter[1];
+
+ /* Grab an LWLock to keep different backends from mixing reports */
+ LWLockAcquire(0, LW_EXCLUSIVE);
+
+ for (i = 0; i < numLocks; i++)
+ {
+ if (sh_acquire_counts[i] || ex_acquire_counts[i] || block_counts[i])
+ fprintf(stderr, "PID %d lwlock %d: shacq %u exacq %u blk %u\n",
+ MyProcPid, i, sh_acquire_counts[i], ex_acquire_counts[i],
+ block_counts[i]);
+ }
+
+ LWLockRelease(0);
+}
+
+#endif /* LWLOCK_STATS */
+
/*
* Compute number of LWLocks to allocate.
@@ -263,6 +296,26 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode)
PRINT_LWDEBUG("LWLockAcquire", lockid, lock);
+#ifdef LWLOCK_STATS
+ /* Set up local count state first time through in a given process */
+ if (counts_for_pid != MyProcPid)
+ {
+ int *LWLockCounter = (int *) ((char *) LWLockArray - 2 * sizeof(int));
+ int numLocks = LWLockCounter[1];
+
+ sh_acquire_counts = calloc(numLocks, sizeof(int));
+ ex_acquire_counts = calloc(numLocks, sizeof(int));
+ block_counts = calloc(numLocks, sizeof(int));
+ counts_for_pid = MyProcPid;
+ on_shmem_exit(print_lwlock_stats, 0);
+ }
+ /* Count lock acquisition attempts */
+ if (mode == LW_EXCLUSIVE)
+ ex_acquire_counts[lockid]++;
+ else
+ sh_acquire_counts[lockid]++;
+#endif /* LWLOCK_STATS */
+
/*
* We can't wait if we haven't got a PGPROC. This should only occur
* during bootstrap or shared memory initialization. Put an Assert here
@@ -369,6 +422,10 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode)
*/
LOG_LWDEBUG("LWLockAcquire", lockid, "waiting");
+#ifdef LWLOCK_STATS
+ block_counts[lockid]++;
+#endif
+
for (;;)
{
/* "false" means cannot accept cancel/die interrupt here. */
This is the main PostgreSQL git repository.
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /