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

Commit8abd424

Browse files
committed
More deadlock code to check for escallation locks.
offsetof() addition to local socket size.
1 parent54399bb commit8abd424

File tree

4 files changed

+111
-30
lines changed

4 files changed

+111
-30
lines changed

‎src/backend/storage/lmgr/README

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
$Header: /cvsroot/pgsql/src/backend/storage/lmgr/README,v 1.1.1.1 1996/07/09 06:21:55 scrappy Exp $
1+
$Header: /cvsroot/pgsql/src/backend/storage/lmgr/README,v 1.2 1998/01/28 02:29:26 momjian Exp $
22

33
This file is an attempt to save me (and future code maintainers) some
44
time and a lot of headaches. The existing lock manager code at the time
@@ -88,6 +88,12 @@ activeHolders -
8888
holders, summing the values of activeHolders should total to the value
8989
of nActive.
9090

91+
---------------------------------------------------------------------------
9192

92-
This is all I had the stomach for right now..... I will get back to this
93-
someday.-mer 17 June 1992 12:00 am
93+
Locks are accessed in two ways. Each PROC structure has a lockQueue,
94+
that is a circular linked list of LOCK pointers that this process holds
95+
or is waiting on.
96+
97+
Second, there is a hash table that can do a lookup by combined LOCK
98+
address and transaction id(xid) which allows a process to see what
99+
type of locks it holds on that table.

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

Lines changed: 93 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.23 1998/01/27 15:34:49 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lock.c,v 1.24 1998/01/28 02:29:27 momjian Exp $
1111
*
1212
* NOTES
1313
* Outside modules can create a lock table and acquire/release
@@ -755,7 +755,7 @@ LockResolveConflicts(LOCKTAB *ltable,
755755
tmpMask=2;
756756
for (i=1;i <=nLockTypes;i++,tmpMask <<=1)
757757
{
758-
if (lock->activeHolders[i]-myHolders[i])
758+
if (lock->activeHolders[i]!=myHolders[i])
759759
{
760760
bitmask |=tmpMask;
761761
}
@@ -1429,14 +1429,38 @@ DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check)
14291429
XIDLookupEnt*tmp=NULL;
14301430
SHMEM_OFFSETend=MAKE_OFFSET(lockQueue);
14311431
LOCK*lock;
1432-
staticPROC*checked_procs[MaxBackendId];
1433-
staticintnprocs;
14341432

1433+
LOCKTAB*ltable;
1434+
XIDLookupEnt*result,
1435+
item;
1436+
HTAB*xidTable;
1437+
boolfound;
1438+
1439+
staticPROC*checked_procs[MaxBackendId];
1440+
staticintnprocs;
1441+
staticboolMyNHolding;
1442+
1443+
/* initialize at start of recursion */
14351444
if (skip_check)
14361445
{
1437-
/* initialize at start of recursion */
14381446
checked_procs[0]=MyProc;
14391447
nprocs=1;
1448+
1449+
ltable=AllTables[1];
1450+
xidTable=ltable->xidHash;
1451+
1452+
MemSet(&item,0,XID_TAGSIZE);
1453+
TransactionIdStore(MyProc->xid,&item.tag.xid);
1454+
item.tag.lock=MAKE_OFFSET(findlock);
1455+
#if0
1456+
item.tag.pid=pid;
1457+
#endif
1458+
1459+
if ((result= (XIDLookupEnt*)
1460+
hash_search(xidTable, (Pointer)&item,HASH_FIND,&found))&&found)
1461+
MyNHolding=result->nHolding;
1462+
else
1463+
MyNHolding=0;
14401464
}
14411465

14421466
if (SHMQueueEmpty(lockQueue))
@@ -1469,13 +1493,7 @@ DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check)
14691493
if (lock==findlock&& !skip_check)
14701494
return true;
14711495

1472-
/*
1473-
*No sense in looking at the wait queue of the lock we are
1474-
*looking for as it is MyProc's lock entry.
1475-
* If lock == findlock, and I got here, skip_check must be true.
1476-
*/
1477-
if (lock!=findlock)
1478-
{
1496+
{
14791497
PROC_QUEUE*waitQueue=&(lock->waitProcs);
14801498
PROC*proc;
14811499
inti;
@@ -1484,16 +1502,70 @@ DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check)
14841502
proc= (PROC*)MAKE_PTR(waitQueue->links.prev);
14851503
for (i=0;i<waitQueue->size;i++)
14861504
{
1487-
for (j=0;j<nprocs;j++)
1488-
if (checked_procs[j]==proc)
1489-
break;
1490-
if (j >=nprocs)
1505+
if (proc!=MyProc&&
1506+
lock==findlock&&/* skip_check also true */
1507+
MyNHolding)/* I already hold some lock on it */
1508+
{
1509+
/*
1510+
*For findlock's wait queue, we are interested in
1511+
*procs who are blocked waiting for a write-lock on the
1512+
*table we are waiting on, and already hold a lock on it.
1513+
*We first check to see if there is an escalation
1514+
*deadlock, where we hold a readlock and want a
1515+
*writelock, and someone else holds readlock on
1516+
*the same table, and wants a writelock.
1517+
*
1518+
*Basically, the test is, "Do we both hold some lock
1519+
*on findlock, and we are both waiting in the lock
1520+
*queue?"
1521+
*/
1522+
1523+
Assert(skip_check);
1524+
Assert(MyProc->prio==2);
1525+
1526+
ltable=AllTables[1];
1527+
xidTable=ltable->xidHash;
1528+
1529+
MemSet(&item,0,XID_TAGSIZE);
1530+
TransactionIdStore(proc->xid,&item.tag.xid);
1531+
item.tag.lock=MAKE_OFFSET(findlock);
1532+
#if0
1533+
item.tag.pid=pid;
1534+
#endif
1535+
1536+
if ((result= (XIDLookupEnt*)
1537+
hash_search(xidTable, (Pointer)&item,HASH_FIND,&found))&&found)
1538+
{
1539+
if (result->nHolding)
1540+
return true;
1541+
}
1542+
}
1543+
/*
1544+
*No sense in looking at the wait queue of the lock we are
1545+
*looking for.
1546+
* If lock == findlock, and I got here, skip_check must be
1547+
*true too.
1548+
*/
1549+
if (lock!=findlock)
14911550
{
1492-
checked_procs[nprocs++]=proc;
1493-
Assert(nprocs <=MaxBackendId);
1494-
/* If we found a deadlock, we can stop right now */
1495-
if (DeadLockCheck(&(proc->lockQueue),findlock, false))
1496-
return true;
1551+
for (j=0;j<nprocs;j++)
1552+
if (checked_procs[j]==proc)
1553+
break;
1554+
if (j >=nprocs&&lock!=findlock)
1555+
{
1556+
checked_procs[nprocs++]=proc;
1557+
Assert(nprocs <=MaxBackendId);
1558+
/*
1559+
*For non-MyProc entries, we are looking only waiters,
1560+
*not necessarily people who already hold locks and are
1561+
*waiting.
1562+
*Now we check for cases where we have two or more
1563+
*tables in a deadlock. We do this by continuing
1564+
*to search for someone holding a lock
1565+
*/
1566+
if (DeadLockCheck(&(proc->lockQueue),findlock, false))
1567+
return true;
1568+
}
14971569
}
14981570
proc= (PROC*)MAKE_PTR(proc->links.prev);
14991571
}

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.29 1998/01/27 03:00:29 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.30 1998/01/28 02:29:29 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -46,7 +46,7 @@
4646
*This is so that we can support more backends. (system-wide semaphore
4747
*sets run out pretty fast.) -ay 4/95
4848
*
49-
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.29 1998/01/27 03:00:29 momjian Exp $
49+
* $Header: /cvsroot/pgsql/src/backend/storage/lmgr/proc.c,v 1.30 1998/01/28 02:29:29 momjian Exp $
5050
*/
5151
#include<sys/time.h>
5252
#include<unistd.h>
@@ -249,7 +249,10 @@ InitProcess(IPCKey key)
249249
*/
250250
SpinRelease(ProcStructLock);
251251

252+
MyProc->pid=0;
253+
#if0
252254
MyProc->pid=MyProcPid;
255+
#endif
253256
MyProc->xid=InvalidTransactionId;
254257

255258
/* ----------------

‎src/include/libpq/pqcomm.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*
77
* Copyright (c) 1994, Regents of the University of California
88
*
9-
* $Id: pqcomm.h,v 1.21 1998/01/27 15:35:22 momjian Exp $
9+
* $Id: pqcomm.h,v 1.22 1998/01/28 02:29:40 momjian Exp $
1010
*
1111
*-------------------------------------------------------------------------
1212
*/
@@ -35,10 +35,10 @@ typedef union SockAddr {
3535

3636
#defineUNIXSOCK_PATH(sun,port) \
3737
(sprintf((sun).sun_path, "/tmp/.s.PGSQL.%d", (port)) + \
38-
+ 1 + sizeof ((sun).sun_family))
38+
offsetof(struct sockaddr_un, sun_path))
3939
/*
40-
*+ 1isfor BSD-specific sizeof((sun).sun_len)
41-
*We never actually set sun_len, and I can't think of a
40+
*We do this because sun_lenisin BSD's struct, while others don't.
41+
*We never actually setBSD'ssun_len, and I can't think of a
4242
*platform-safe way of doing it, but the code still works. bjm
4343
*/
4444

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp