2014年12月10日上午9点左右,XX系统weblogic服务器应用程序的运行状态显示为overload。与此同时weblogic日志一直在提示无法连接错误。数据库存在大量的session,手动kill掉部分session后应用得以恢复。
2.1 经过分析故障时间段数据库的awr,发现数据库1和2节点的94%的时间都消耗在“enq: TX - row lock contention”。
2.2 并且数据库1节点的session数超过1000,每秒执行次数高达15000多次。说明数据库当时存在大量活动连接。
2.3 进行分析sql语句的执行状态,发现占用94%时间的语句是两个很简单delete语句,并且单次执行时间达到3200多秒。
2.4 故障期间,在数据库日志中发现大量死锁信息
Wed Dec 10 09:55:05 2014 Global Enqueue Services Deadlock detected. More info in file /oracle/admin/DWXX/bdump/DWXX1_lmd0_1541770.trc. Wed Dec 10 09:55:36 2014 Thread 1 advanced to log sequence 493665 (LGWR switch) Current log# 16 seq# 493665 mem# 0: +REDOGROUP/DWXX/onlinelog/group_16.263.837169415 Wed Dec 10 09:56:04 2014 Thread 1 advanced to log sequence 493666 (LGWR switch) Current log# 14 seq# 493666 mem# 0: +REDOGROUP/DWXX/onlinelog/group_14.261.837169357 Wed Dec 10 09:56:05 2014 Global Enqueue Services Deadlock detected. More info in file /oracle/admin/DWXX/bdump/DWXX1_lmd0_1541770.trc. |
语句DELETE FROM PUB_XXXLINE WHERE USER_ID=:1和DELETE FROM PUB_XXXLINE WHERE SESSION_ID=:1在执行过程中存在大量的行锁竞争,导致堵塞大量session,从而使Weblogic(中间件)的连接池消耗殆尽。无法新增连接。
5.1 PUB_XXXLINE表是在线用户记录表,用户登陆就增加一行记录,退出会话,就删除相对应的会话记录
5.2 DELETE FROM PUB_XXXLINE WHERESESSION_ID=:1语句,是用于在数据库内删除退出或超时的会话记录,每次只会有一行
5.3 DELETE FROM PUB_XXXLINE WHEREUSER_ID=:1语句,用于检测当用户登陆数超出最大允许范围(即一个帐号如果出现了超出允许数的登陆,如10次),如果超过允许范围,就将整个用户(USER_ID)的全部会话删除,根据USER_ID定位的多行数据,有可能包含SESSION_ID行的数据,两种删除操作同时高并发进行,就行成了请求死锁现象。
5.1 采用两个不同的DELETE操作使用同一个程序串行操作,而不是两个不同的程序进程并行操作,避免行请求死锁的现象
5.2 取消DELETEFROM PUB_XXXLINE WHERE USER_ID=:1操作,因为业务本身就是要控制一个帐号不能有过大的同时登陆,当超过时,可以不让新用户登陆,待其它用户退出后才能登陆,如果直接删除单个用户以前所有的登陆,反而使其它已登陆的用户异常退出。
本文作者:黎俊杰(网名:踩点),从事”系统架构、操作系统、存储设备、数据库、中间件、应用程序“六个层面系统性的性能优化工作
欢迎加入 系统性能优化专业群 ,共同探讨性能优化技术。群号:258187244