« Oracle数据库安全 - CVE-2011-3512 | Blog首页 | Oracle数据恢复 - 使用 lsof 查看进程打开的文件列表 »
JAVA连接池导致的超高回滚率 - rlbk=1
作者:eygle | 【转载请注出处】|【云和恩墨 领先的zData数据库一体机 | zCloud PaaS云管平台 | SQM SQL审核平台 | ZDBM 数据库备份一体机】
链接:https://www.eygle.com/archives/2011/12/java_dual_rlbk1.html
在客户的数据库中,我们发现事务数量非常高,最后确认是由于回滚导致的。链接:https://www.eygle.com/archives/2011/12/java_dual_rlbk1.html
经过检查发现在JAVA连接池的数据库活动性检查时,每次执行查询之后,都会执行一次回滚,从而导致了数据库回滚率超高:
=====================DBCP连接池的一些设置参数如下
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
=====================
(转自 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文章:
By eygle on 2011-12-20 08:25 | Comments (1) | FAQ | 2928 |
怎样减少或者杜绝不必要的回滚呢?
是不是 设置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/