问题描述
云数据库RDS SQL Server版出现阻塞问题。
问题原因
当应用程序频繁读写某个表或者资源时,很容易出现阻塞情况。当阻塞问题严重时,应用程序端的语句执行会变得缓慢。
排查方法
针对云数据库RDS SQL Server版阻塞问题,排查建议如下。
-
循环监控
SYS.SYSPROCESSES,获取阻塞信息。命令如下:WHILE 1 = 1 BEGIN SELECT * FROM SYS.SYSPROCESSES WHERE BLOCKED <> 0; WAITFOR DELAY '00:00:01'; END;说明您可以自定义循环间隔时间,此处以
00:00:01为例。查询结果显示
spid=56被spid=53阻塞(blocked=53),等待锁类型为LCK_M_S,等待资源为KEY: 5:72057594038845440 (98ec012aa510)。多次循环查询中,waittime值依次为 9205、10206、11207、12208、13209,持续递增,表明锁等待未被释放。说明blocked列表示阻塞头session_id,waitresource表示被阻塞的session等待的资源。更多返回值字段的说明,请参见sys.sysprocesses官方文档。 -
循环监控
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 '00:00:01'; END;查询结果示例:数据库
jacky中,request_session_id 为 62 的会话被 blocking_session_id 为 56 的会话阻塞,被阻塞对象为Tbl1,资源类型为KEY,被阻塞语句(RequestingText)为(@1 int,@2 int)INSERT INTO [dbo].[Tbl2]([id],[c...,阻塞头语句(BlockingText)为BEGIN TRAN INSERT into dbo.Tbl1 (id, col) VALUE...,请求锁模式为S。返回参数说明如下:
参数
说明
DBName数据库名称。
request_session_id当前请求的session ID,即被阻塞的session。
blocking_session_id阻塞头session ID。
BlockedObjectName被阻塞的session操作的对象。
resource_type等待的资源类型。
RequestingText当前session执行的语句,即被阻塞的语句。
BlockingText阻塞头session执行的语句。
request_mode当前session请求的锁模式。
调优建议
可以参考以下步骤,进行调优。
-
关闭阻塞头连接,可以帮助快速解除阻塞。
-
查看是否有长时间未提交的事务,及时提交事务。
-
如果有S锁导致的查询阻塞,并且您的应用允许脏读,可以使用
WITH (NOLOCK)查询提示。例如在查询中写入SELECT * FROM table WITH (NOLOCK);使查询在执行时不申请锁,从而绕过阻塞状况。 -
检查应用程序逻辑,按顺序访问某个资源。
相关操作
-
如需应对紧急情况下的阻塞问题,请参见如何快速解决RDS SQL Server的阻塞问题。
-
您可以在RDS控制台通过设置性能监控指标、创建报警规则等方式,以便及时发现和响应数据库性能问题。具体详情,请参见监控与报警。
-
如需了解更多数据库性能调优策略,例如索引优化、查询优化、存储优化。具体详情,请参见性能优化与诊断。