开发者社区> 问答> 正文

【RDS】RDS SQL Server出现死锁现象,该如何处理?

已解决

RDS SQL Server出现死锁现象,该如何处理?

展开
收起
云上猫猫 2022-01-14 15:10:31 1105 0
1 条回答
写回答
取消 提交回答
  • 采纳回答

    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。

    系统显示类似如下。

    1.png

    提示:监控结果中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
    

    系统显示类似如下。

    2.png 3.png

    注:

    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来监控和抓取死锁图谱,如下所示。

    4.png

    抓取的死锁图谱如下所示。

    5.png

    3、按照实际情况进行调优。

    关闭阻塞源会话,可以帮助快速解除阻塞。

    查看是否有长时间未提交的事务,及时提交事务。

    使用with(nolock)进行查询。

    注:如果有S锁参与死锁,并且应用允许脏读,可以使用with(nolock),让查询语句避免申请锁,从而避免死锁,如下SQL语句所示。select * from table with(nolock)

    检查应用程序逻辑,按顺序访问某个资源。

    2022-01-14 15:13:36
    赞同 展开评论 打赏
来源圈子
更多
收录在圈子:
问答排行榜
最热
最新

相关电子书

更多
One Box: 解读事务与分析一体化数据库 HybridDB for MySQL 立即下载
One Box:解读事务与分析一体化数据库HybridDB for MySQL 立即下载
如何支撑HTAP场景-HybridDB for MySQL系统架构和技术演进 立即下载

相关镜像