日期:2014-05-16  浏览次数:20506 次

数据库死锁问题及相关解决建议

 1.数据库 死锁问题及相关解决建议

  当执行100用户并发审批二种票场景时,Loadrunner 提 示100个审批事务全部成功通过,而通过应用查询,实际提交数目却为60个。Loadrunner出现“误判”是由于HTTP协议的本身的限制,由于 HTTP协议的无状态特点,Loadrunner只能通过HTTP协议返回码来判断脚本是否执行成功,而不是在业务层次上做判断。

  经排查,发现在并发负载下,提交审批二种票时,失败的页面上出现了如下错误信息:

  信息:执行查询SQL 语 句时发生错误:[IBM][CLI Driver][DB2/AIX64] SQL0911N? The current transaction has been rolled back because of a deadlock or timeout.? Reason code "68".? SQLSTATE=40001

  [IBM][CLI Driver][DB2/AIX64] SQL0911N? The current transaction has been rolled back because of a deadlock or timeout.? Reason code "68".? SQLSTATE=40001

  从DB2的监控数据来看,在并发数目超过30后,lock time大大增加,超过10秒,最终导致死锁超时。

  问题可能根源在:

  (1)开发人员在提交sql语句,做update,insert等操作时,启用了排它锁,导致死锁。

  (2)数据库的locktimeout参数设置过小。

  在针对locktimeout参数做过优化调试后,成功提交数有所提升,但仍无法从根本上消除死锁问题的发生。因此,建议在应用程序jdbc层上修改代码,避免死锁发生,才是解决问题根本之道。

  具体解决建议:

  建议开发人员检查jdbc层上可能存在死锁语句,这有可能:

  ● 一次commit包含多条sql语句

  ● 涉及同时多表操作的sql语句

  ● 逻辑死锁

  2.数据库表索引设计相关问题及解决建议

  数据库在设计上存在如下两个问题:

  (1)表设计存在大表风险

  在测试 过程中,发现工单和两票在做删除操作时,记录只是改变状态字段,而始终分别保存在USERID.T_GDMX_GD,USERID.T_LP_GZP,USERID.T_LP_ CZP表中。

  这可能会导致在生产环境下,随着运行时间和用户数的增加,如上表数据记录越来越多,最终成为大表,引起查询性能的下降。一般,业界通常的解决类似问题的办法是另建备份表保存被删除的记录。

 (2)索引构建不合理,没有起到相应的作用。

  在运行两票性能测试场景过程中,通过loadrunner的db2 performance counter监控捕获pool_index_read指标,发现此指标的值一直为0。因此,我们推断当前数据库中存在着索引构建不合理的问题。

  已经查证,两票的工单存放于一张数据库表中,此表有80多个字段,而索引仅为7个。

  另外,通过变电一种票的性能测试结果可以看到total_sort_time总共花费986秒,排序时间过长,说明数据库的索引没有建在order by的字段上。

  具体解决建议:

  与开发人员进行沟通,构建合理的表及索引。

  3.硬件可能瓶颈

  在负载测试过程中,曾发生过数据库服务器cpu 100%运行,memory居高不下,最终数据库服务宕掉。经检测,在操作系统中有过虚拟内存分配高达9GB,导致机子负荷过重。

  具体解决建议:

  鉴于此,我们建议实际生产环境上的数据库服务器内存至少16GB或更高。