现象:近期现场反馈一个问题。系统在审批的时候,常常卡死。整个系统全然用不了,浏览器訪问处于loading的状态。

排查:

1.一般系统挂了首先想到内存问题,可是现象是loading,也就是说没有挂,线程正在运行,怀疑是线程被堵塞了,配置上jvisualvm监控了一下。出问题后内存没满确定不是内存问题,查看线程dump发现大部分都在运行sql查询,

初步发现是运行sql慢导致的。

2.我们用的是sybase数据库,运行了几个简单sql发现几分钟都没运行完,使用sp_sysmon "00:00:30"监控近30秒的情况发现cpu、内存、线程都没问题,差点儿1%使用率都不到,怀疑是某个连接堵塞了表。导致其它连接所有堵塞导致的。

3.我们使用自己写的存储过程查看堵塞的连接。结果例如以下:

PS:使用sp_lock命令就能够查看哪个连接堵塞了数据库。可是显示的都是tableid等。还须要再次查询转换成详细表名等。自己写的存储过程仅仅是此处转换了一下,后面会附上。

发现当中1万多个锁。7000多个排它锁,Ex_row-blk是堵塞了其它连接的锁。发现有21个堵塞了其它连接的锁,相应的表是T_ZXLD_SYYH,运行select * from master..sysprocesses找到相应的连接。如上图的User有316/287/283等,结果例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveHVlcGlhb2hhbjIwMDY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

此时基本确定了原因,我们用的是c3p0连接池。应该是某个连接堵塞了表。其它全部连接查询时候都被堵塞了,导致连接池被占满。全部请求凡是涉及数据库查询的都被堵塞了,页面始终处于loading状态。

4.那么接下来就是找到堵塞的地方,上图发现tran_name都是$chained_transaction,结合程序推断。也就是说都在运行某个责任链里面的事务时堵塞了。系统就2处使用了责任链,直接就能够推断到时审批的责任链导致的,那么接下来就是排查此处代码是否有问题了。审批流程例如以下:

(1)开启事务

(2)依据參数查询出要审批的主表数据。2个sql

(3)逐条调用审批组件(类似工作流的一个组件)审批,每条数据大约5个更新sql,2个查询sql

(4)更新主表状态,每条数据1个更新sql

(5)插入审计日志,每条数据1个插入sql

(6)生成提醒消息,查询所有主表数据。20个查询sql,5个更新删除sql(很慢)

(7)更新增量记录表。记录该条数据改动时间和状态等,每条数据1个更新sql

(8)提交事务

怀疑并发时相互堵塞导致的,生成提醒消息的地方,会查询所有业务表。假设此时有其它连接在事务中审批,就会堵塞。其它连接在生成消息。相互堵塞,造成死锁。理论上数据库会自己主动处理死锁的。可是不知道什么原因。日志报的死锁数量不是特别多。

并且此处业务处理也太合理。正经常使用户每次批量审批大约100条数据,所以大约有900多个增删改sql,200多个查询sql,像生成消息等sql运行很慢(由于涉及更新旧消息),这么多操作放到一个事务中很慢。审批表大约3000w数据,业务主表500w数据,运行起来也不是很快。

解决的方法:重构了此处代码,讲上面运行慢的(5)(6)(7)步骤新起一个线程,不放到事务中运行,即使失败也影响不大。

这样sql降低了30%,速度快了不少。更新到现场,观察了一个星期,发现未出现不响应等情况,算是问题解决。

尽管问题解决。可是根本原因没有找到,为什么会相互堵塞。为什么死锁没自己主动检測,这个是兴许须要跟踪的。

最后。问题尽管攻克了,可是中间沟通花了不少时间,和运维人员要现场数据耽误了非常多事,简单整理一下。兴许出问题的时候搜集这几个数据:

1、sp__lock的结果;(使用文章最后提供的存储过程)

2、select * from master..sysprocesses;

3、假设数据库慢。加上sp_sysmon "00:00:30"的结果;

4、中间件线程dump文件。

附上sybase查看锁的存储过程

IF OBJECT_ID ('dbo.sp__lock') IS NOT NULL
DROP PROCEDURE dbo.sp__lock
GO create procedure sp__lock(
@dbname char(30)=null,@spid int=null,
@dont_format char(1) = null
)
as
begin declare @dbid smallint
if @dbname is not null
select @dbid=db_id(@dbname) if (charindex("sa_role", show_role()) > 0)
begin
if @dont_format is null
select "Type"=substring(v.name,1,11),
"User"=substring(suser_name(p.suid)+" ("+rtrim(convert(char(6),l.spid))+")",1,20),
"Table"=substring(db_name(l.dbid)+".."+convert(char(20),object_name(l.id,l.dbid)),1,26),
"Page"=convert(char(8),l.page),
"Cmd"=substring(p.cmd,1,11)
from master..syslocks l,
master..sysprocesses p,
master..spt_values v
where p.spid=l.spid and
l.type = v.number and
v.type = "L" and
p.dbid=isnull(@dbid,p.dbid) and
p.spid=isnull(@spid,p.spid) and
l.dbid=isnull(@dbid,l.dbid) and
l.spid=isnull(@spid,l.spid)
order by l.dbid, l.id, v.name
else
select "Type"=v.name,
"User"=suser_name(p.suid)+" ("+rtrim(convert(char(6),l.spid))+")",
"Table"=db_name(l.dbid)+".."+object_name(l.id,l.dbid),
"Page"=l.page,
"Cmd"=p.cmd
from master..syslocks l,
master..sysprocesses p,
master..spt_values v
where p.spid=l.spid and
l.type = v.number and
v.type = "L" and
p.dbid=isnull(@dbid,p.dbid) and
p.spid=isnull(@spid,p.spid) and
l.dbid=isnull(@dbid,l.dbid) and
l.spid=isnull(@spid,l.spid)
order by l.dbid, l.id, v.name
return
end select "Type"=v.name,
"Usernm"=convert(varchar(60),suser_name(p.suid)+" ("+rtrim(convert(char(6),l.spid))+")"),
"TableNm"=convert(varchar(60),db_name(l.dbid)+".."),
"Page"=l.page,
"Cmd"=p.cmd,
l.id,
l.dbid
into #locks
from master..syslocks l,
master..sysprocesses p,
master..spt_values v
where p.spid=l.spid and
l.type = v.number and
v.type = "L" and
l.dbid=isnull(@dbid,l.dbid) and
l.spid=isnull(@spid,l.spid) and
p.dbid=isnull(@dbid,p.dbid) and
p.spid=isnull(@spid,p.spid) update #locks
set TableNm=TableNm+object_name(id,dbid)
where dbid=db_id() or dbid=1 or dbid=2 update #locks
set TableNm=TableNm+convert(varchar,id)
where dbid<>db_id() and dbid>2 delete #locks
where TableNm like "tempdb..#locks%" if @dont_format is null
select substring(Type, 1,11),
"User"=substring(Usernm, 1,14),
"Table"=convert(char(26),TableNm),
"Page"=convert(char(8),Page),
"Cmd"=substring(Cmd,1,11)
from #locks
order by dbid, id, Type
else
select Type, "User"=Usernm, "Table"=TableNm, Page, Cmd
from #locks
order by dbid, id, Type end
GO

性能问题案例02——sybase连接堵塞问题的更多相关文章

  1. 性能问题案例01——sybase数据库内存问题

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/xuepiaohan2006/article/details/30064399     近期现场反馈问 ...

  2. 性能问题解决案例01——sybase数据库内存问题

    最近湖南现场反馈问题,所有电子签章页面打不开文书(pdf格式),后台日志没报任何错误. 1.首先想到是签章的ocx控件问题,检查ocx控件安装,发现其他电脑也打不开文书,测试页面可以直接打开pdf文档 ...

  3. SSRS Reports 2008性能优化案例

    我们的一个Reporting Service服务上部署了比较多的SSRS报表,其中有一个系统的SSRS报表部署后,执行时间相对较长,加之供应商又在ASP.NET页面里面嵌套了Reporting Ser ...

  4. 老李案例分享:Weblogic性能优化案例

    老李案例分享:Weblogic性能优化案例 POPTEST的测试技术交流qq群:450192312 网站应用首页大小在130K左右,在之前的测试过程中,其百用户并发的平均响应能力在6.5秒,性能优化后 ...

  5. Android-优化UI性能(1)-降低主线程的堵塞时间

    Android-优化UI性能(1)-降低主线程的堵塞时间 一 降低主线程的堵塞时间 Android已经提供了AsyncTask实现从主线程生成新的异步任务的方法. 定义并实现以下的类就可以(方法由系统 ...

  6. web综合案例02

    web综合案例02 web综合案例02 web综合案例02 ... ... 内容待添加

  7. android 性能分析案例

    本章以实际案例分析在android开发中,性能方面的优化和处理.设计到知识点有弱引用,memory monitor,Allocation Tracker和leakcanary插件. 1.测试demo ...

  8. SQL性能优化案例分析

    这段时间做一个SQL性能优化的案例分析, 整理了一下过往的案例,发现一个比较有意思的,拿出来给大家分享. 这个项目是我在项目开展2期的时候才加入的, 之前一期是个金融内部信息门户, 里面有个功能是收集 ...

  9. SSRS Reports 2008性能优化案例二

    前几天一同事反映海外工厂A的SSRS报表比较慢,让我检查优化一下.于是我检查了下2015-07-13到2015-07-15 12:00这段时间报表的耗时记录 USE [ReportServer];   ...

随机推荐

  1. 爬虫开发python工具包介绍 (1)

    本文来自网易云社区 作者:王涛 本文大纲: 简易介绍今天要讲解的两个爬虫开发的python库 详细介绍 requests库及函数中的各个参数 详细介绍 tornado 中的httpcilent的应用 ...

  2. C#Windows服务安装

    1,做好windows服务后,生成 一下,然后在项目目录中找到bin文件夹下的Debug文件夹,文件夹下有文件xxxx.exe 2,然后在C:\Windows\Microsoft.NET\Framew ...

  3. c#笔记2018-12-26

    using System; /*C#学习笔记2018-12-26 * 1.@逐字字符串 * 2.数据类型转换 * 3.变量声明和占位符使用 * 4.接收用户输入值 * 5.const 关键字 * 6. ...

  4. c++ - 在终端中,cout不显示任何内容

    g++ 是一个编译器,它将源代码转换成可以执行程序,但不运行它. 你必须亲自运行程序. g++ 生成的程序的默认名称是 a.out ( 因为历史原因),因此你将运行它作为 $./a.out   如果要 ...

  5. 【转载】标准C语言的输入输出流(i/o)方法详解

    标准 C I/O clearerr 语法: #include <stdio.h> void clearerr( FILE *stream ); clearerr函数重置错误标记和给出的流的 ...

  6. Educational Codeforces Round 24

    A. Diplomas and Certificates time limit per test 1 second memory limit per test 256 megabytes input ...

  7. “玲珑杯”ACM比赛 Round #11 " ---1097 - 萌萌哒的第二题

    1097 - 萌萌哒的第二题 题意:中文题好像没有必要说题意了吧.. 思路:我们知道由于运输桥不能交叉,所以从右往左所修建的桥的序号是严格单增的.但是每个工厂B有6种选择,只能选一个求最多能建造几座桥 ...

  8. Mysql 主外键与索引之间的区别和联系

    系数据库依赖于主键,它是数据库物理模式的基石.主键在物理层面上只有两个用途: 惟一地标识一行. 作为一个可以被外键有效引用的对象. 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部 ...

  9. BZOJ 4815 [Cqoi2017]小Q的表格 ——欧拉函数

    把式子化简一波. 发现一个比较厉害的性质:每个点只能影响到行列下标$gcd$与它相同的点. 然后就可以计算$\sum_{g<=k}f(g,g)*\sum_{i<=k}\sum_{j< ...

  10. 刷题总结——spoj1812(后缀自动机+DP)

    题目: A string is finite sequence of characters over a non-empty finite set Σ. In this problem, Σ is t ...