*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.6 1996/12/26 17:50:26 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.7 1997/02/12 05:23:49 scrappy Exp $
*
* NOTES
* Outside modules can create a lock table and acquire/release
#else /* LOCK_MGR_DEBUG */
+int lockDebug = 0;
+
+#ifndef LOCK_DEBUG_OID_MIN
+/*
+ * This is totally arbitrary. It is the minimum relation oid
+ * which will trigger the locking debug when the -K option
+ * is given to the backend. This is done to avoid tracing
+ * locks on system relations.
+ */
+#define LOCK_DEBUG_OID_MIN 20000
+#endif
+
#define LOCK_PRINT(where,tag,type)\
- elog(NOTICE, "%s: rel (%d) dbid (%d) tid (%d,%d) type (%d)\n",where, \
- tag->relId, tag->dbId, \
- ( (tag->tupleId.ip_blkid.data[0] >= 0) ? \
- BlockIdGetBlockNumber(&tag->tupleId.ip_blkid) : -1 ), \
- tag->tupleId.ip_posid, \
- type);
+ if ((lockDebug >= 1) && (tag->relId >= LOCK_DEBUG_OID_MIN)) \
+ elog(DEBUG, \
+ "%s: pid (%d) rel (%d) dbid (%d) tid (%d,%d) type (%d)",where, \
+ getpid(),\
+ tag->relId, tag->dbId, \
+ ((tag->tupleId.ip_blkid.bi_hi<<16)+\
+ tag->tupleId.ip_blkid.bi_lo),\
+ tag->tupleId.ip_posid, \
+ type);
#define LOCK_DUMP(where,lock,type)\
- elog(NOTICE, "%s: rel (%d) dbid (%d) tid (%d,%d) nHolding (%d) holders (%d,%d,%d,%d,%d) type (%d)\n",where, \
- lock->tag.relId, lock->tag.dbId, \
- ((lock->tag.tupleId.ip_blkid.data[0] >= 0) ? \
- BlockIdGetBlockNumber(&lock->tag.tupleId.ip_blkid) : -1 ), \
- lock->tag.tupleId.ip_posid, \
- lock->nHolding,\
- lock->holders[1],\
- lock->holders[2],\
- lock->holders[3],\
- lock->holders[4],\
- lock->holders[5],\
- type);
+ if ((lockDebug >= 1) && (lock->tag.relId >= LOCK_DEBUG_OID_MIN)) \
+ elog(DEBUG, \
+ "%s: pid (%d) rel (%d) dbid (%d) tid (%d,%d) nHolding (%d) "\
+ "holders (%d,%d,%d,%d,%d) type (%d)",where, \
+ getpid(),\
+ lock->tag.relId, lock->tag.dbId, \
+ ((lock->tag.tupleId.ip_blkid.bi_hi<<16)+\
+ lock->tag.tupleId.ip_blkid.bi_lo),\
+ lock->tag.tupleId.ip_posid, \
+ lock->nHolding,\
+ lock->holders[1],\
+ lock->holders[2],\
+ lock->holders[3],\
+ lock->holders[4],\
+ lock->holders[5],\
+ type);
#define XID_PRINT(where,xidentP)\
- elog(NOTICE,\
- "%s:xid (%d) pid (%d) lock (%x) nHolding (%d) holders (%d,%d,%d,%d,%d)",\
- where,\
- xidentP->tag.xid,\
- xidentP->tag.pid,\
- xidentP->tag.lock,\
- xidentP->nHolding,\
- xidentP->holders[1],\
- xidentP->holders[2],\
- xidentP->holders[3],\
- xidentP->holders[4],\
- xidentP->holders[5]);
+ if ((lockDebug >= 2) && \
+ (((LOCK *)MAKE_PTR(xidentP->tag.lock))->tag.relId \
+ >= LOCK_DEBUG_OID_MIN)) \
+ elog(DEBUG,\
+ "%s: pid (%d) xid (%d) pid (%d) lock (%x) nHolding (%d) "\
+ "holders (%d,%d,%d,%d,%d)",\
+ where,\
+ getpid(),\
+ xidentP->tag.xid,\
+ xidentP->tag.pid,\
+ xidentP->tag.lock,\
+ xidentP->nHolding,\
+ xidentP->holders[1],\
+ xidentP->holders[2],\
+ xidentP->holders[3],\
+ xidentP->holders[4],\
+ xidentP->holders[5]);
#endif /* LOCK_MGR_DEBUG */
}
if (!found)
{
- XID_PRINT("queueing XidEnt LockAcquire:", result);
+ XID_PRINT("LockAcquire: queueing XidEnt", result);
ProcAddLock(&result->queue);
result->nHolding = 0;
memset((char *)result->holders, 0, sizeof(int)*MAX_LOCKTYPES);
#endif
SHMQueueFirst(lockQueue,(Pointer*)&xidLook,&xidLook->queue);
- XID_PRINT("LockReleaseAll:", xidLook);
+ XID_PRINT("LockReleaseAll", xidLook);
#ifndef USER_LOCKS
SpinAcquire(masterLock);
{
return LockingIsDisabled;
}
+
+#ifdef DEADLOCK_DEBUG
+/*
+ * Dump all locks. Must have already acquired the masterLock.
+ */
+void
+DumpLocks()
+{
+ SHMEM_OFFSET location;
+ PROC *proc;
+ SHM_QUEUE *lockQueue;
+ int done;
+ XIDLookupEnt *xidLook = NULL;
+ XIDLookupEnt *tmp = NULL;
+ SHMEM_OFFSET end;
+ SPINLOCK masterLock;
+ int nLockTypes;
+ LOCK *lock;
+ int pid, count;
+ int tableId = 1;
+ LOCKTAB *ltable;
+
+ pid = getpid();
+ ShmemPIDLookup(pid,&location);
+ if (location == INVALID_OFFSET)
+ return;
+ proc = (PROC *) MAKE_PTR(location);
+ if (proc != MyProc)
+ return;
+ lockQueue = &proc->lockQueue;
+
+ Assert (tableId < NumTables);
+ ltable = AllTables[tableId];
+ if (!ltable)
+ return;
+
+ nLockTypes = ltable->ctl->nLockTypes;
+ masterLock = ltable->ctl->masterLock;
+
+ if (SHMQueueEmpty(lockQueue))
+ return;
+
+ SHMQueueFirst(lockQueue,(Pointer*)&xidLook,&xidLook->queue);
+ end = MAKE_OFFSET(lockQueue);
+
+ LOCK_DUMP("DumpLocks", MyProc->waitLock, 0);
+ XID_PRINT("DumpLocks", xidLook);
+
+ for (count=0;;) {
+ /* ---------------------------
+ * XXX Here we assume the shared memory queue is circular and
+ * that we know its internal structure. Should have some sort of
+ * macros to allow one to walk it. mer 20 July 1991
+ * ---------------------------
+ */
+ done = (xidLook->queue.next == end);
+ lock = (LOCK *) MAKE_PTR(xidLook->tag.lock);
+
+ LOCK_DUMP("DumpLocks",lock,0);
+
+ if (count++ > 2000) {
+ elog(NOTICE,"DumpLocks: xid loop detected, giving up");
+ break;
+ }
+
+ if (done)
+ break;
+ SHMQueueFirst(&xidLook->queue,(Pointer*)&tmp,&tmp->queue);
+ xidLook = tmp;
+ }
+}
+#endif
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.29 1997/02/03 04:43:31 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.30 1997/02/12 05:24:22 scrappy Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
/*static bool EnableRewrite = true; , never changes why have it*/
CommandDest whereToSendOutput;
+#ifdef LOCK_MGR_DEBUG
+extern int lockDebug;
+#endif
extern int lockingOff;
extern int NBuffers;
fprintf(stderr, " F: turn off fsync\n");
fprintf(stderr, " f: forbid plantype generation\n");
fprintf(stderr, " i: don't execute the query, just show the plan tree\n");
+#ifdef LOCK_MGR_DEBUG
+ fprintf(stderr, " K: set locking debug level [0|1|2]\n");
+#endif
fprintf(stderr, " L: turn off locking\n");
fprintf(stderr, " m: set up a listening backend at portno to support multiple front-ends\n");
fprintf(stderr, " M: start as postmaster\n");
*/
flagC = flagQ = flagS = flagE = flagEu = ShowStats = 0;
ShowParserStats = ShowPlannerStats = ShowExecutorStats = 0;
-
+#ifdef LOCK_MGR_DEBUG
+ lockDebug = 0;
+#endif
+
/* get hostname is either the environment variable PGHOST
or 'localhost' */
if (!(hostName = getenv("PGHOST"))) {
DataDir = getenv("PGDATA"); /* default */
multiplexedBackend = false; /* default */
- while ((flag = getopt(argc, argv, "B:bCD:d:Eef:iLm:MNo:P:pQSst:x:F"))
+ while ((flag = getopt(argc, argv, "B:bCD:d:Eef:iK:Lm:MNo:P:pQSst:x:F"))
!= EOF)
switch (flag) {
dontExecute = 1;
break;
+ case 'K':
+#ifdef LOCK_MGR_DEBUG
+ lockDebug = atoi(optarg);
+#else
+ fprintf(stderr, "Lock debug not compiled in\n");
+#endif
+ break;
+
case 'L':
/* --------------------
* turn off locking
*/
if (IsUnderPostmaster == false) {
puts("\nPOSTGRES backend interactive interface");
- puts("$Revision: 1.29 $ $Date: 1997/02/03 04:43:31 $");
+ puts("$Revision: 1.30 $ $Date: 1997/02/12 05:24:22 $");
}
/* ----------------