RDS SQL Server出现死锁现象,该如何处理?
1、使用客户端连接实例,详情请参见连接实例。
2、监控相关视图。
a.执行如下SQL语句,循环监控sys.sysprocesses。
while 1=1
begin
select * from sys.sysprocesses where blocked<>0
waitfor delay '[$Time]'
end
注:[$Time]循环间隔时间可以自定义,例如00:00:01。
系统显示类似如下。
提示:监控结果中blocked列的值为阻塞该会话的阻塞源会话ID,waitresource为被阻塞的会话等待的资源。从上述结果可以看到,spid 53和spid 56相互阻塞,形成了死锁。
b.执行如下SQL语句,循环监控sys.dm_tran_locks和sys.dm_os_waiting_tasks等视图。
while 1=1
Begin
SELECT
db.name DBName,
tl.request_session_id,
wt.blocking_session_id,
OBJECT_NAME(p.OBJECT_ID) BlockedObjectName,
tl.resource_type,
h1.TEXT AS RequestingText,
h2.TEXT AS BlockingText,
tl.request_mode
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.partitions AS p ON p.hobt_id = tl.resource_associated_entity_id
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
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
waitfor delay '[$Time]'
End
系统显示类似如下。
注:
DBName:request_session_id操作的数据库。
request_session_id:当前请求的会话 ID,即被阻塞的会话。
blocking_session_id:阻塞源会话ID。
BlockedObjectName:被阻塞的会话操作的对象。
resource_type:等待的资源类型。
RequestingText:当前会话执行的语句,即被阻塞的语句。
BlockingText:阻塞源会话执行的语句。
request_mode:当前会话请求的锁模式。
c.如果您使用的是RDS SQL Server 2012,您还可以使用SQL Server Profiler来监控和抓取死锁图谱,如下所示。
抓取的死锁图谱如下所示。
3、按照实际情况进行调优。
关闭阻塞源会话,可以帮助快速解除阻塞。
查看是否有长时间未提交的事务,及时提交事务。
使用with(nolock)进行查询。
注:如果有S锁参与死锁,并且应用允许脏读,可以使用with(nolock),让查询语句避免申请锁,从而避免死锁,如下SQL语句所示。select * from table with(nolock)
检查应用程序逻辑,按顺序访问某个资源。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。