Нет доступа к Current Activity

abursh
Дата: 12.02.2001 14:21:30
Во время работы, подозреваю, что при динамическом создании таблиц, пропадает доступ к мониторингу locks: SEM зависает, а системные процедуры типа sp_dblock кричат, что из-за лока нет доступа к ресурсам, и ничего не показывают.
Кто-нибудь знает, блок какой таблицы приводит к столь плачевному результату, и как с этим бороться?
Задолбало уже, и не можем поймать, кто виноват.
Заранее благодарен - АБ
Александр Гладченко
Дата: 13.02.2001 10:53:42
Обычно, блокировки отлавливаются трассировщиком. Пробовали ли Вы трассировать всё и вся...?
abursh
Дата: 13.02.2001 11:18:35
Спасибо. Нет, не пробовал. Проверю и доложу.
abursh
Дата: 20.02.2001 15:08:51
Нет, трассировки мне не помогли, но помогла процедура, которую я привожу ниже.
С ее помощью я увидел, что проблема в том, что программа создает множество временных таблиц, а их создание локирует файлы SYSCOLUMNS и SYSCOMMENTS, прицхем подозреваю, что страничным lock'м, что очевидно и вызывает проблемы и приводит к зависанию SEM при попытке проверить CURRENT ACTIVITY. Процедура же, которую я привожу ниже, при этом обходит локированные ресурсы и выдает листинг без проблем. Из листинга видно, какой процесс - первичная причина лока.

/*When one process blocks another from accessing an object, it's often beacause yet another process is blocking it.
This situation can produce a virtual chain of resource blocks that is difficult to trace.
The best tool for the sleuth in this case is a stored procedure
that traces process blocks back to their originators:
*/

USE MASTER
go

Следующий код (в дополнение к приведенной выше процедуре) по-моему дает
исчерпывающую информацию для устранения проблемы.
IF OBJECT_ID('UP_rooter_blocker') IS NOT NULL
DROP PROC UP_rooter_blocker
GO
CREATE PROC UP_rooter_blocker
AS
declare @Rooter_Blocker int
exec @Rooter_Blocker = sp_find_root_blocker
select @Rooter_Blocker as Rooter_Blocker,
case @Rooter_Blocker
when 0 then 'No problems'
else 'Problems '
end as Status
select a.rsc_dbid as DB_ID,
b.name as DB_NAME,
object_name(a.rsc_objid)as Locked_Object,
case (req_status)
when 1 then 'Granted'
when 2 then 'Converting'
when 3 then 'Waiting'
end as Lock_Status
from master..syslockinfo a,
master..sysdatabases b
where req_spid = @Rooter_Blocker and b.dbid = a.rsc_dbid

--
-- Возможно добавить строку
-- exec sp_who @Rooter_Blocker
-- но она, как и Энтерпрайз Менеджер при входе в "текущую активность",
-- иногда у меня подвисала, так что не рекомендую.
--
go

IF OBJECT_ID('sp_find_root_blocker') IS NOT NULL
DROP PROC sp_find_root_blocker
go

CREATE PROC sp_find_root_blocker
@help char(2) = NULL
/*Usage: sp_find_root_blocker
*/
AS

IF (@help='/?') GOTO H

IF EXISTS (SELECT * FROM master..sysprocesses p1
JOIN master..sysprocesses p2
ON (p1.spid=p2.blocked))
BEGIN
DECLARE @spid INT

-- First select - to define @spid to return --

SELECT @spid=p1.spid --Get the _last_prime offender
FROM master..sysprocesses p1
JOIN master..sysprocesses p2
ON (p1.spid=p2.blocked)
WHERE p1.blocked=0

-- Second select - to prepare report to display --

SELECT p1.spid,
p1.status,
loginame=LEFT(p1.loginame,20),
blk=CONVERT(char(3),p1.blocked),
db=LEFT(db_name(p1.dbid),10),
p1.cmd,
p1.waittype
FROM master..sysprocesses p1
JOIN master..sysprocesses p2
ON (p1.spid=p2.blocked)
WHERE p1.blocked=0
RETURN(@spid)--The last root blocker

END
ELSE
BEGIN
PRINT 'No processes are currently blocking others.'
RETURN (0)
END
RETURN 0

H:
Return -1

GO

Буду рад, если эти процедуры кому-нибудь пригодятся.
АБ
abursh
Дата: 20.02.2001 15:22:40
Простите, при переносе текста процедур в сообщение форума, они были выдернуты неаккуратно. Правильный и полный текст здесь:


CREATE PROC sp_find_root_blocker
@help char(2) = NULL
/*Usage: sp_find_root_blocker
*/
AS

IF (@help='/?') GOTO H

IF EXISTS (SELECT * FROM master..sysprocesses p1
JOIN master..sysprocesses p2
ON (p1.spid=p2.blocked)) BEGIN
DECLARE @spid INT

SELECT @spid=p1.spid --Get the _last_prime offender
FROM master..sysprocesses p1
JOIN master..sysprocesses p2
ON (p1.spid=p2.blocked)
WHERE p1.blocked=0

SELECT p1.spid,
p1.status,
loginame=LEFT(p1.loginame,20),
blk=CONVERT(char(3),p1.blocked),
db=LEFT(db_name(p1.dbid),10),
p1.cmd,
p1.waittype
FROM master..sysprocesses p1
JOIN master..sysprocesses p2
ON (p1.spid=p2.blocked)
WHERE p1.blocked=0
RETURN(@spid)--The last root blocker
END ELSE BEGIN
PRINT 'No processes are currently blocking others.'
RETURN (0)
END
RETURN 0

H:
Return -1


GO


IF OBJECT_ID('UP_rooter_blocker') IS NOT NULL
DROP PROC UP_rooter_blocker
GO
CREATE PROC UP_rooter_blocker
AS
declare @Rooter_Blocker int
exec @Rooter_Blocker = sp_find_root_blocker
select @Rooter_Blocker as Rooter_Blocker,
case @Rooter_Blocker
when 0 then 'No problems'
else 'Problems '
end as Status
select a.rsc_dbid as DB_ID,
b.name as DB_NAME,
object_name(a.rsc_objid)as Locked_Object,
case (req_status)
when 1 then 'Granted'
when 2 then 'Converting'
when 3 then 'Waiting'
end as Lock_Status
from master..syslockinfo a,
master..sysdatabases b
where req_spid = @Rooter_Blocker and b.dbid = a.rsc_dbid

-- exec sp_who @Rooter_Blocker
go