如何快速解决RDS SQL Server的阻塞问题

重要

本文为阻塞问题的快速解决方案,适合紧急情况下的快速应对。如果需要从根本上解决问题,建议您确认和分析下发生阻塞的原因,根据原因制定方案解决问题。一般常见原因是缺失索引或者大事务,导致事务执行时间长,持有锁的时间也会增加,从而引起了大量阻塞的情况。具体详情,请参见云数据库RDS SQL Server版阻塞问题处理方法

问题描述

在云数据库RDS SQL Server中出现阻塞情况。

问题原因

事务之间锁资源争抢导致出现阻塞情况。

解决方案

  1. RDS SQL Server发生锁现象时,通过执行下面的脚本,获取详细的锁和阻塞信息。

    SELECT dtl.request_session_id AS waitSID,
           der.blocking_session_id AS blockSID,
           dowt.resource_description,
           der.wait_type,
           dowt.wait_duration_ms,
           DB_NAME(dtl.resource_database_id) AS DB,
           dtl.resource_associated_entity_id AS waitingAssociatedEntity,
           dtl.resource_type AS waitResType,
           dtl.request_type AS waitReqType,
           dest.[text] AS waitSQL,
           dtl1.request_type AS blockReqType,
           dest1.[text] AS blockingSQL
    FROM sys.dm_tran_locks dtl
    JOIN sys.dm_os_waiting_tasks dowt ON dowt.resource_address=dtl.lock_owner_address
    JOIN sys.dm_exec_requests der ON der.session_id=dtl.request_session_id CROSS apply sys.dm_exec_sql_text(der.sql_handle) dest
    LEFT JOIN sys.dm_exec_requests der1 ON der.session_id=dowt.blocking_session_id OUTER apply sys.dm_exec_sql_text(der1.sql_handle) dest1
    LEFT JOIN sys.dm_tran_locks dtl1 ON dtl1.request_session_id=der1.session_id
  2. 执行以下命令,获取到锁资源信息。

    SELECT OBJECT_NAME(i.object_id) obj,
           i.name
    FROM sys.partitions p
    JOIN sys.indexes i ON i.object_id=p.object_id
    AND i.index_id=p.index_id
    WHERE p.partition_id=[$Waiting_Associate_Entity]
    说明

    [$Waiting_Associate_Entity]为等待的资源参数值。

  3. 通过获取的资源信息,使用kill命令,终止掉阻塞源的会话。