性能问题案例02——sybase连接堵塞问题

现象:近期现场反馈一个问题,系统在审批的时候,常常卡死,整个系统全然用不了,浏览器訪问处于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等,结果例如以下:

此时基本确定了原因,我们用的是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
时间: 2024-12-15 01:37:31

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

性能问题案例02——sybase连接阻塞问题

现象:最近现场反馈一个问题,系统在审批的时候,经常卡死,整个系统完全用不了,浏览器访问处于loading的状态. 排查: 1.一般系统挂了首先想到内存问题,但是现象是loading,也就是说没有挂,线程正在执行,怀疑是线程被阻塞了,配置上jvisualvm监控了一下,出问题后内存没满确定不是内存问题,查看线程dump发现大部分都在执行sql查询, 初步发现是执行sql慢导致的. 2.我们用的是sybase数据库,执行了几个简单sql发现几分钟都没执行完,使用sp_sysmon "00:00:30

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

最近现场反馈问题,所有电子签章页面打不开文书(pdf格式),后台日志没报任何错误,效果就是空白: 1.首先想到是签章的ocx控件问题,检查ocx控件安装,发现其他电脑也打不开文书,测试页面可以直接打开pdf文档,排除控件的问题. 2.怀疑是文书下载出问题了,检查文书下载功能,我们是把pdf文书下载到本地"我的文档"目录中,然后使用ocx控件打开文书,检查发现有的文书能正常下载到本地,有的干脆不下载,能下载到本地的文书可以正常打开.检查ftp发现文书都没问题,定位问题就出在从ftp下载这

大型电商互联网性能优化案例

大型电商互联网性能优化案例 理论基础 The Theory 平台设计 Platform Design 业务结果 Business Impact 双11优化 架构思考 Architecture Takeaways   ----------------------------------------------------------------------------------------------------------------------------------------------

SSRS Reports 2008性能优化案例

我们的一个Reporting Service服务上部署了比较多的SSRS报表,其中有一个系统的SSRS报表部署后,执行时间相对较长,加之供应商又在ASP.NET页面里面嵌套了Reporting Service的报表,使得用户对报表响应速度非常不满,于是和几个同事研究了一番如何定位.优化SSRS报表性能. 案例环境: 操作系统   :   Windows Server 2008 R2 Standard SP1 数据库版本 :   SQL Server 2008 R2 (SP2) - 10.50.4

清算/报表/日终跑批程序之性能优化案例(一)

前言 不知不觉,技术人生系列·我和数据中心的故事来到了第五期.小y又和大家见面了! 前几期主要发了一些TroubleShooting的案例分享,其实小y最擅长的是性能优化,所以从这期开始,小y会陆续的分享更多的数据库性能优化案例. 进入正题,如果您的日终跑批/清算/报表等程序时快时慢,或者从某一天以后就一直变慢,作为运维DBA或开发的您,会怎么下手?还有,除了解决问题外,你要如何解答领导最关心的一个问题,"为什么现在有问题,但是以前没有问题呢"! 小y今天要和大家分享的就是这样一个性能

android 性能分析案例

本章以实际案例分析在android开发中,性能方面的优化和处理.设计到知识点有弱引用,memory monitor,Allocation Tracker和leakcanary插件. 1.测试demo 下载bug项目:https://github.com/lzyzsd/MemoryBugs,请注意配合使用MemoryMonitor, AllocationTracker以及HeapDump,LeakCanary等工具来查找潜在的内存问题,并尝试解决. 2.测试工具介绍 (1)memory monit

Oracle SQL Developer 添加SQLServer 和Sybase 连接

来源于: http://blog.csdn.net/kk185800961/article/details/8602306 1. 开始只有Oracle 和access 连接 2. 打开Oracle SQL Developer: 工具-->首选项-->数据库-->第三方JDBC驱动程序-->添加驱动条目 3. 自动加载到目录,JTDS.jar 下载后就到放这里. (我的路径:C:\Documents and Settings\Administrator\Application Dat

SQL性能优化案例分析

这段时间做一个SQL性能优化的案例分析, 整理了一下过往的案例,发现一个比较有意思的,拿出来给大家分享. 这个项目是我在项目开展2期的时候才加入的, 之前一期是个金融内部信息门户, 里面有个功能是收集各个上市公司的财报, 然后做各种分析, 数据图表展示, 使用的人数并不多, 仅百人左右. 2期打算面向行外用户, 刚开始预计同时在线人数不超过50, 就以50访问用户/秒的性能测试, 结果在把1期的图表类数据展示响应基本在5分钟左右, 属于严重不可用, 说说我们的服务器配置, 有2台网站前端承载用户

mysql语句性能分析案例

写法不一样而功能完全相同的两条 SQL 的在性能方面的差异.示例一需求:取出某个 group(假设 id 为 100)下的用户编号(id),用户昵称(nick_name).用户性别( sexuality ) . 用 户 签 名 ( sign ) 和 用 户 生 日 ( birthday ) , 并 按 照 加 入 组 的 时 间(user_group.gmt_create)来进行倒序排列,取出前 20 个.解决方案一.SELECT id,nick_nameFROM user,user_group