SQL SERVER 2008 有一个数据表老被阻塞,一句对主键定位的Update都要200秒.
要如何去查到是哪句语句阻塞了这个表?
------解决思路----------------------
黄版主发过不少监控的脚本,我个人也收集了一些
SELECT wt.blocking_session_id AS BlockingSessesionId,
sp.program_name AS ProgramName,
COALESCE(sp.LOGINAME, sp.nt_username) AS HostName,
ec1.client_net_address AS ClientIpAddress,
db.name AS DatabaseName,
wt.wait_type AS WaitType,
ec1.connect_time AS BlockingStartTime,
wt.WAIT_DURATION_MS / 1000 AS WaitDuration,
ec1.session_id AS BlockedSessionId,
h1.TEXT AS BlockedSQLText,
h2.TEXT AS BlockingSQLText
FROM sys.dm_tran_locks AS tl
INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id
INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address =
wt.resource_address
INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id =
tl.request_session_id
INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id =
wt.blocking_session_id
LEFT OUTER JOIN master.dbo.sysprocesses sp ON SP.spid =
wt.blocking_session_id
CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1
CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2
------解决思路----------------------
/*
exec p_lockinfo 1,0
--*/
create proc p_lockinfo
@kill_lock_spid bit=1, --是否杀掉死锁的进程,1 杀掉, 0 仅显示
@show_spid_if_nolock bit=1 --如果没有死锁的进程,是否显示正常进程信息,1 显示,0 不显示
as
declare @count int,@s nvarchar(1000),@i int
select id=identity(int,1,1),标志,
进程ID=spid,线程ID=kpid,块进程ID=blocked,数据库ID=dbid,
数据库名=db_name(dbid),用户ID=uid,用户名=loginame,累计CPU时间=cpu,
登陆时间=login_time,打开事务数=open_tran, 进程状态=status,
工作站名=hostname,应用程序名=program_name,工作站进程ID=hostprocess,
域名=nt_domain,网卡地址=net_address
into #t from(
select 标志='死锁的进程',
spid,kpid,a.blocked,dbid,uid,loginame,cpu,login_time,open_tran,
status,hostname,program_name,hostprocess,nt_domain,net_address,
s1=a.spid,s2=0
from master..sysprocesses a join (
select blocked from master..sysprocesses group by blocked
)b on a.spid=b.blocked where a.blocked=0
union all
select '
------解决思路----------------------
_牺牲品_>',
spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran,
status,hostname,program_name,hostprocess,nt_domain,net_address,
s1=blocked,s2=1
from master..sysprocesses a where blocked<>0
)a order by s1,s2
select @count=@@rowcount,@i=1
if @count=0 and @show_spid_if_nolock=1
begin
insert #t
select 标志='正常的进程',
spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time,
open_tran,status,hostname,program_name,hostprocess,nt_domain,net_address
from master..sysprocesses
set @count=@@rowcount
end
if @count>0
begin
create table #t1(id int identity(1,1),a nvarchar(30),b Int,EventInfo nvarchar(255))
if @kill_lock_spid=1
begin
declare @spid varchar(10),@标志 varchar(10)
while @i<=@count
begin
select @spid=进程ID,@标志=标志 from #t where id=@i
insert #t1 exec('dbcc inputbuffer('+@spid+')')
if @标志='死锁的进程' exec('kill '+@spid)
set @i=@i+1
end
end
else
while @i<=@count
begin
select @s='dbcc inputbuffer('+cast(进程ID as varchar)+')' from #t where id=@i
insert #t1 exec(@s)
set @i=@i+1
end
select a.*,进程的SQL语句=b.EventInfo
from #t a join #t1 b on a.id=b.id
end
go
begin tran exec
sp_helptext p_test_hy select * from #f_sale_vendor rollback
抄的一个,很好用的!
------解决思路----------------------
select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName看下不知道有没有用~~
from sys.dm_tran_locks where resource_type='OBJECT'
spid 锁表进程
tableName 被锁表名
解锁:
declare @spid int
Set @spid = 57 --锁表进程
declare @sql varchar(1000)
set @sql='kill '+cast(@spid as varchar)
exec(@sql)
------解决思路----------------------
一些平时0秒的查询语句(带了 WIth (nolock) 参数的)也超过200秒.
是不是有数据库文件的自动增长所致?