为什么sleeping的会话会造成阻塞(2)
背景
客户反馈系统突然从11:10开始运行非常缓慢,在SQL专家云中看到大量的产生阻塞的活动会话,KILL掉阻塞的源头马上又出现新的源头,实在没有办法只能重启应用程序断开所有数据库连接才解决,请我们协助分析根本的原因。
现象
登录SQL专家云,进入趋势分析页面,下钻到11点钟内一个小时的数据,看到从11:12开始出现阻塞,越来越严重。
进入活动会话原始数据页面,看到不同时间点的阻塞源头会话是不同的,但都是同一类的现象,阻塞源头会话的状态是sleeping,被阻塞的会话都在对同一个表执行UPDATE语句。
分析
状态为sleeping代表当前会话没有执行SQL请求,之所以造成阻塞是因为会话以前开启了一个或多个事务, 在事务中修改了一个或多个表的数据,会话对这些修改的数据行持有排他锁,从而阻塞其他会话对该表的操作。如果这种状态持续很长时间,很有可能是前端应用程序出现了异常,并且没有健壮的异常处理机制,出错后没有回滚以前打开的事务并关闭连接,导致阻塞一直存在。 前端应用程序出错原因主要有两种,一种是执行SQL语句时被阻塞等原因导致执行时间长并产生超时;一种是执行非数据库访问逻辑时因为某些原因出错了,例如转换数据类型失败、接收数据量太大导致内存溢出、访问别的接口报错等。
本着这个经验,对这些sleeping的会话进行回溯,发现这些会话在sleeping之前,都曾经被阻塞过很长时间,根据慢语句的特征判断是执行超时了。
而且这些会话都存在打开的事务,事务开始时间都在执行语句超时的时间之前。
通过对存储过程进行分析,发现里面在用TRY CATCH的方式处理事务,因此推断该方式无法捕获应用程序端的超时错误,导致事务和连接的泄露,因为存储过程比较复杂,下面用一个测试来模拟。
测试
首先创建一个存储过程,逻辑为先开始事务,然后依次对两个表进行UPDATE,通过TRY CATCH的方法处理事务。
CREATE PROCEDURE dbo.usp_test
AS
BEGIN TRAN BEGIN TRY
UPDATE
dbo.Table_2 WITH(ROWLOCK)
SET
a = 'wang' UPDATE
dbo.Table_1 WITH(ROWLOCK)
SET
a = 'wang'
END TRY
BEGIN CATCH
IF @@ERROR = 0
BEGIN
GOTO succeed
END
ELSE
BEGIN
GOTO error
END
END CATCH succeed:
COMMIT TRAN
RETURN 1
error:
ROLLBACK TRAN
RETURN 0
新建一个查询,开始一个事务,然后执行UPDATE Table_1,不提交或者回滚事务,对表Table_1的排他锁一直存在, 用来模拟对表Table_1的锁定。
新建另一个查询,注意,执行超时值设置为30秒(默认是0,代表永不超时)。这个新建立的会话ID是56。
执行存储过程usp_test。updat dbo.Table_2很快执行完,在执行updat dbo.Table_1时产生阻塞,等待30秒后出现超时的报错。
新建一个查询,查看会话56的事务信息,可以看到存在一个打开的事务。
再通过sys.dm_tran_locks可以看到会话56还保持着对表Table_2和Table_1的意向排他锁以及Table_2上更改的两行数据的排他锁。此时在其他会话中对Table_2执行查询和修改,都被会话56阻塞。
总结:“超时”错误是应用程序端的异常,数据库驱动程序执行SQL语句时等待服务器端的响应,等待时间达到设置的阈值后发送一个终止执行的信号给服务器端并向上层应用程序抛出异常。服务器端接收到该信号后终止语句的执行,并不会报错,TRY CATCH是无法捕获的,因此无法执行到SUCCEED处的COMMIT或者ERROR处的ROLLBACK,导致了事务的泄露,该事务中的对表Table_2的排他锁一直持有,其他会话对表Table_2的操作会被阻塞,直到杀掉该会话。
解决
对于这类问题,根本的解决方法是修改应用程序,增加对于执行异常的捕获,检查是否存在事务并回滚,然后关闭数据库连接。
但是很多客户是购买软件厂商的产品,修改程序不容易实现或者周期很长。因此只能在数据库端进行补偿性的措施,就是配置一个自动查杀会话的作业,根据sleeping会话的特征定期KILL掉。也可以在SQL专家云中启用自动查杀会话的功能。
为什么sleeping的会话会造成阻塞(2)的更多相关文章
- Oracle RAC环境下定位并杀掉最终阻塞的会话
实验环境:Oracle RAC 11.2.0.4 (2节点) 1.模拟故障:会话被级联阻塞 2.常规方法:梳理找出最终阻塞会话 3.改进方法:立即找出最终阻塞会话 之前其实也写过一篇相关文章: 如何定 ...
- 会话执行存储过程,等待被阻塞,Kill session场景模拟
本次场景来源: 通知某个会话:执行execute addupp(1,'five');类似的存储过程,会话等待:(会话等待两种情况:一种确实执行,但是未完成:另一种就是执行的操作无法获取资源,等待资源释 ...
- MySQL的共享锁阻塞会话案例浅析输入日志标题
这是问题是一个网友遇到的问题:一个UPDATE语句产生的共享锁阻塞了其他会话的案例,对于这个案例,我进一步分析.总结和衍化了相关问题.下面分析如有不对的地方,敬请指正.下面是初始化环境和数据的 ...
- 初涉SQL Server性能问题(2/4):列出等待资源的会话
在初涉SQL Server性能问题(1/4)里,我们知道了如何快速检查服务器实例上正运行的任务数和IO等待的任务数.这个是轻量级的脚本,不会给服务器造成任何压力,即使服务器在高负荷下,也可以正常获得结 ...
- 一个特殊的SQL Server阻塞案例分析
上周,在SQL Server数据库下面遇到了一个有意思的SQL阻塞(SQL Blocking)案例.其实个人对SQL Server的阻塞还是颇有研究的.写过好几篇相关文章. 至于这里为什么要总结一下这 ...
- SQL Server中SELECT会真的阻塞SELECT吗?
在SQL Server中,我们知道一个SELECT语句执行过程中只会申请一些意向共享锁(IS) 与共享锁(S), 例如我使用SQL Profile跟踪会话86执行SELECT * FROM dbo.T ...
- With(ReadPast)就不会被阻塞吗?
在生产环境中,会有很多使用ReadPast查询提示的场合,来避免正在被其它事务锁定的行对当前查询造成阻塞,而又不会获取到“脏数据”. 可是很多人都疑惑,为什么我使用了ReadPast仍然有时会被阻塞? ...
- SQL Server 监控统计阻塞脚本信息
数据库产生阻塞(Blocking)的本质原因 :SQL语句连续持有锁的时间过长 ,数目过多, 粒度过大.阻塞是事务隔离带来的副作用,它是不可避免的,而且是一个数据库系统常见的现象. 但是阻塞的 ...
- DBA常用SQL之会话与等待事件
SELECT * FROM V$SESSION WHERE USERNAME IS NOT NULL AND STATUS = 'ACTIVE' ORDER BY LOGON_TIME, SID; 1 ...
- 查看数据库中有哪些活动的事务,对应的会话id,执行的语句
select dbt.database_id, DB_NAME(dbt.database_id) '数据库名', dbt.transaction_id, at.name, at.transaction ...
随机推荐
- qtcreator修改界面但是没有更新
原因 我之前修改了项目名(简单的修改文件夹和.pro文件名),但是项目构建的位置还是之前目录. 解决 将 build directory改为新的目录即可.
- springBoot 过滤器去除请求参数前后空格(附源码)
背景 : 用户在前端页面中不小心输入的前后空格,为了防止因为前后空格原因引起业务异常,所以我们需要去除参数的前后空格! 如果我们手动去除参数前后空格,我们可以这样做 @GetMapping(value ...
- JavaEE Day02MySQL
今日内容 数据库的基本概念 MySQL数据库软件 安装 卸载 配置 SQL语句 一.数据库的基本概念 1.数据库DataBase,简称DB 2.什么是数据库? 用于存储和管理数据的仓库 ...
- 【每日一题】【使用list&使用辅助栈实现】2022年2月11日-NC90 包含min函数的栈
描述定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的 min 函数,输入操作时保证 pop.top 和 min 函数操作时,栈中一定有元素. 此栈包含的方法有:push(value): ...
- ChatGPT杀疯了,这人工智能也太离谱了吧
转载请注明出处️ 作者:测试蔡坨坨 原文链接:caituotuo.top/2ac8440d.html 你好,我是测试蔡坨坨. 这几天被ChatGPT刷屏,各大网站平台都能看到关于它的文章和视频,上线短 ...
- css样式实现平行四边形
强大的css样式实现平行四边形: 啥也不说了,直接上代码 <!DOCTYPE html> <html lang="en"> <head> < ...
- JavaScript:箭头函数:省略写法
之所以把箭头函数拎出来,是因为它不仅仅是声明函数的一种方式,它还是函数式编程的重要根基,它使得函数的使用更加的灵活,同时,它的语法,也相对于function声明的函数更加灵活和复杂. 箭头函数的省略写 ...
- STL string常用API
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<string> using namespace std; ...
- tempdb数据文件暴增分析
背景 某客户tempdb数据文件突然暴增,导致磁盘可用空间紧张,让我们找到暴增的原因. 现象 登录到SQL专家云,通过趋势分析进行回溯,在4月12日,tempdb数据文件在3个小时内从10GB涨到了8 ...
- 在Ubuntu上安装OpenShift并使用
服务器信息 在阿里云买了个抢占式的服务器,地区为华南广州,系统为Ubuntu 20.04,8核16GB. 安装Docker 命令如下: $ apt-get update -y $ apt-get up ...