eygle.com   eygle.com
eygle.com eygle
eygle.com  
 

« Oracle数据库安全 - CVE-2011-3512 | Blog首页 | Oracle数据恢复 - 使用 lsof 查看进程打开的文件列表 »

JAVA连接池导致的超高回滚率 - rlbk=1
modb.pro

在客户的数据库中,我们发现事务数量非常高,最后确认是由于回滚导致的。

经过检查发现在JAVA连接池的数据库活动性检查时,每次执行查询之后,都会执行一次回滚,从而导致了数据库回滚率超高:
=====================
PARSING IN CURSOR #1 len=18 dep=0 uid=26 oct=3 lid=26 tim=1292816994316916 hv=3876449241 ad='ab946d24'
SELECT 1 FROM DUAL
END OF STMT
PARSE #1:c=0,e=19,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=1292816994316914
EXEC #1:c=0,e=9,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=4,tim=1292816994316979
WAIT #1: nam='SQL*Net message to client' ela= 1 p1=675562835 p2=1 p3=0
WAIT #1: nam='SQL*Net message from client' ela= 116 p1=675562835 p2=1 p3=0
WAIT #1: nam='SQL*Net message to client' ela= 1 p1=675562835 p2=1 p3=0
WAIT #1: nam='SQL*Net message from client' ela= 128 p1=675562835 p2=1 p3=0
WAIT #1: nam='SQL*Net message to client' ela= 1 p1=675562835 p2=1 p3=0
FETCH #1:c=0,e=37,p=0,cr=3,cu=0,mis=0,r=1,dep=0,og=4,tim=1292816994317363
WAIT #1: nam='SQL*Net message from client' ela= 118 p1=675562835 p2=1 p3=0
WAIT #1: nam='SQL*Net message to client' ela= 1 p1=675562835 p2=1 p3=0
WAIT #1: nam='SQL*Net message from client' ela= 96 p1=675562835 p2=1 p3=0
STAT #1 id=1 cnt=1 pid=0 pos=1 obj=222 op='TABLE ACCESS FULL DUAL (cr=3 r=0 w=0 time=16 us)'
WAIT #1: nam='SQL*Net message to client' ela= 1 p1=675562835 p2=1 p3=0
WAIT #1: nam='SQL*Net message from client' ela= 97 p1=675562835 p2=1 p3=0
XCTEND rlbk=1, rd_only=1
WAIT #0: nam='SQL*Net message to client' ela= 1 p1=675562835 p2=1 p3=0
WAIT #0: nam='SQL*Net message from client' ela= 96 p1=675562835 p2=1 p3=0
WAIT #0: nam='SQL*Net message to client' ela= 1 p1=675562835 p2=1 p3=0
WAIT #0: nam='SQL*Net message from client' ela= 113 p1=675562835 p2=1 p3=0
WAIT #0: nam='SQL*Net message to client' ela= 2 p1=675562835 p2=1 p3=0
WAIT #0: nam='SQL*Net message from client' ela= 96 p1=675562835 p2=1 p3=0
WAIT #1: nam='SQL*Net message to client' ela= 2 p1=675562835 p2=1 p3=0
WAIT #1: nam='SQL*Net message from client' ela= 117 p1=675562835 p2=1 p3=0
=====================

DBCP连接池的一些设置参数如下
(转自 http://agapple.iteye.com/blog/791943 ):

sql validate 配置
<property name= "testWhileIdle" ><value> true </value></property>
<property name= "testOnBorrow" ><value> false </value></property>
<property name= "testOnReturn" ><value> false </value></property>
<property name= "validationQuery" ><value>select sysdate from dual</value></property>
<property name= "validationQueryTimeout" ><value>1</value></property>
<property name= "timeBetweenEvictionRunsMillis" ><value>30000</value></property>
<property name= "numTestsPerEvictionRun" ><value>16</value></property>

参数说明
   dbcp 是采用了 commons-pool 做为其连接池管理, testOnBorrow,testOnReturn, testWhileIdle 是 pool 是提供的几种校验机制,通过外部钩子的方式回调 dbcp 的相关数据库链接 (validationQuery) 校验 , dbcp 相关外部钩子类: PoolableConnectionFactory, 继承于 common-pool PoolableObjectFactory , dbcp 通过 GenericObjectPool 这一入口,进行连接池的 borrow,return 处理。

具体参数描述:
   1. testOnBorrow : 顾明思义,就是在进行borrowObject进行处理时,对拿到的connection进行validateObject校验
   2. testOnReturn : 顾明思义,就是在进行returnObject对返回的connection进行validateObject校验,个人觉得对数据库连接池的管理意义不大
   3. testWhileIdle : 关注的重点,GenericObjectPool中针对pool管理,起了一个 异步Evict的TimerTask定时线程进行控制 ( 可通过设置参数 timeBetweenEvictionRunsMillis>0), 定时对线程池中的链接进行validateObject校验,对无效的链接进行关闭后,会调用ensureMinIdle,适当建立链接保证最小的minIdle连接数。
   4. timeBetweenEvictionRunsMillis, 设置的Evict线程的时间,单位ms,大于0才会开启evict检查线程
   5. validateQuery , 代表检查的sql
   6. validateQueryTimeout , 代表在执行检查时,通过statement设置,statement.setQueryTimeout(validationQueryTimeout)
   7. numTestsPerEvictionRun ,代表每次检查链接的数量,建议设置和maxActive一样大,这样每次可以有效检查所有的链接.



历史上的今天...
    >> 2008-12-20文章:
    >> 2006-12-20文章:
    >> 2005-12-20文章:
    >> 2004-12-20文章:
           纪念Veritas的离去
           Gmail你还需要吗?
           Rman Crosscheck删除失效归档
           SUN的DISKSUITE
           Man Page Of METASTAT

By eygle on 2011-12-20 08:25 | Comments (1) | FAQ | 2928 |

1 Comment

怎样减少或者杜绝不必要的回滚呢?

是不是 设置testWhileIdle = 0?

这些设置跟我们公司使用的Sprint JDBC有点不一样. 在我的努力下,我们停止了连接接检查, 代之以JDBC/SQL exception handle. 就是根本不做validateQuery, Turn off liveness checks in DBCP connection pools.

优秀实践: http://www.mysqlperformanceblog.com/2010/05/05/checking-for-a-live-database-connection-considered-harmful/


CopyRight © 2004~2020 云和恩墨,成就未来!, All rights reserved.
数据恢复·紧急救援·性能优化 云和恩墨 24x7 热线电话:400-600-8755 业务咨询:010-59007017-7040 or 7037 业务合作: marketing@enmotech.com