mirror of
https://github.com/postgres/postgres.git
synced 2025-08-30 06:01:21 +03:00
Restructure LOCKTAG as per discussions of a couple months ago.
Essentially, we shoehorn in a lockable-object-type field by taking a byte away from the lockmethodid, which can surely fit in one byte instead of two. This allows less artificial definitions of all the other fields of LOCKTAG; we can get rid of the special pg_xactlock pseudo-relation, and also support locks on individual tuples and general database objects (including shared objects). None of those possibilities are actually exploited just yet, however. I removed pg_xactlock from pg_class, but did not force initdb for that change. At this point, relkind 's' (SPECIAL) is unused and could be removed entirely.
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/storage/lmgr/deadlock.c,v 1.33 2005/02/22 04:36:49 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/storage/lmgr/deadlock.c,v 1.34 2005/04/29 22:28:24 tgl Exp $
|
||||
*
|
||||
* Interface:
|
||||
*
|
||||
@@ -836,6 +836,69 @@ PrintLockQueue(LOCK *lock, const char *info)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Append a description of a lockable object to buf.
|
||||
*
|
||||
* XXX probably this should be exported from lmgr.c or some such place.
|
||||
*/
|
||||
static void
|
||||
DescribeLockTag(StringInfo buf, const LOCKTAG *lock)
|
||||
{
|
||||
switch (lock->locktag_type)
|
||||
{
|
||||
case LOCKTAG_RELATION:
|
||||
appendStringInfo(buf,
|
||||
_("relation %u of database %u"),
|
||||
lock->locktag_field2,
|
||||
lock->locktag_field1);
|
||||
break;
|
||||
case LOCKTAG_RELATION_EXTEND:
|
||||
appendStringInfo(buf,
|
||||
_("extension of relation %u of database %u"),
|
||||
lock->locktag_field2,
|
||||
lock->locktag_field1);
|
||||
break;
|
||||
case LOCKTAG_PAGE:
|
||||
appendStringInfo(buf,
|
||||
_("page %u of relation %u of database %u"),
|
||||
lock->locktag_field3,
|
||||
lock->locktag_field2,
|
||||
lock->locktag_field1);
|
||||
break;
|
||||
case LOCKTAG_TUPLE:
|
||||
appendStringInfo(buf,
|
||||
_("tuple (%u,%u) of relation %u of database %u"),
|
||||
lock->locktag_field3,
|
||||
lock->locktag_field4,
|
||||
lock->locktag_field2,
|
||||
lock->locktag_field1);
|
||||
break;
|
||||
case LOCKTAG_TRANSACTION:
|
||||
appendStringInfo(buf,
|
||||
_("transaction %u"),
|
||||
lock->locktag_field1);
|
||||
break;
|
||||
case LOCKTAG_OBJECT:
|
||||
appendStringInfo(buf,
|
||||
_("object %u of class %u of database %u"),
|
||||
lock->locktag_field3,
|
||||
lock->locktag_field2,
|
||||
lock->locktag_field1);
|
||||
break;
|
||||
case LOCKTAG_USERLOCK:
|
||||
appendStringInfo(buf,
|
||||
_("user lock [%u,%u]"),
|
||||
lock->locktag_field1,
|
||||
lock->locktag_field2);
|
||||
break;
|
||||
default:
|
||||
appendStringInfo(buf,
|
||||
_("unknown locktag type %d"),
|
||||
lock->locktag_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Report a detected deadlock, with available details.
|
||||
*/
|
||||
@@ -843,9 +906,12 @@ void
|
||||
DeadLockReport(void)
|
||||
{
|
||||
StringInfoData buf;
|
||||
StringInfoData buf2;
|
||||
int i;
|
||||
|
||||
initStringInfo(&buf);
|
||||
initStringInfo(&buf2);
|
||||
|
||||
for (i = 0; i < nDeadlockDetails; i++)
|
||||
{
|
||||
DEADLOCK_INFO *info = &deadlockDetails[i];
|
||||
@@ -860,27 +926,18 @@ DeadLockReport(void)
|
||||
if (i > 0)
|
||||
appendStringInfoChar(&buf, '\n');
|
||||
|
||||
if (info->locktag.relId == XactLockTableId && info->locktag.dbId == 0)
|
||||
{
|
||||
/* Lock is for transaction ID */
|
||||
appendStringInfo(&buf,
|
||||
_("Process %d waits for %s on transaction %u; blocked by process %d."),
|
||||
info->pid,
|
||||
GetLockmodeName(info->lockmode),
|
||||
info->locktag.objId.xid,
|
||||
nextpid);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Lock is for a relation */
|
||||
appendStringInfo(&buf,
|
||||
_("Process %d waits for %s on relation %u of database %u; blocked by process %d."),
|
||||
info->pid,
|
||||
GetLockmodeName(info->lockmode),
|
||||
info->locktag.relId,
|
||||
info->locktag.dbId,
|
||||
nextpid);
|
||||
}
|
||||
/* reset buf2 to hold next object description */
|
||||
buf2.len = 0;
|
||||
buf2.data[0] = '\0';
|
||||
|
||||
DescribeLockTag(&buf2, &info->locktag);
|
||||
|
||||
appendStringInfo(&buf,
|
||||
_("Process %d waits for %s on %s; blocked by process %d."),
|
||||
info->pid,
|
||||
GetLockmodeName(info->lockmode),
|
||||
buf2.data,
|
||||
nextpid);
|
||||
}
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_T_R_DEADLOCK_DETECTED),
|
||||
|
Reference in New Issue
Block a user