一、前言
近期一直在配合Oracle到OceanBase的兼容性业务适配测试,使用的是企业版OceanBase,版本号是 4.2.1.1。
前面我已经写了两篇关于Oracle到OceanBase遇到问题的文章,可参阅我之前写的xxxx
今天是该系列的第三篇,相比于前两次遇到的问题,这次遇到的问题真的是更复杂,排查问题的难度更难,目前还没有什么解决办法。
有些问题虽然很难处理,但能从一些相应日志等信息里获取到有价值的信息,但这次却不一样,难以获取到有价值的信息,很难定位具体的原因。
二、问题描述
业务在测试一个xxxx系统电子签约的业务时,在Oracle上测试正常,但切换到OceanBase数据库后,业务超时报错。OceanBase数据库数据是从Oracle测试库全量同步过来的,两边的数据和字段等都一致,另外也对OceanBase数据库的超时时间设置的足够长,但测试反馈每次在OceanBase上都报错,测试人员将报错的代码发了过来,代码具体内容如下:
Caused by: org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: interrupt
### The error may exist in URL [jar:file:/home/xxxxDSS/sale/sale-bootstrap.jar!/BOOT-INF/lib/sale-customer-xxx-DSS_LV_2023.56.2.jar!/com/xxxxx/xxx/zzzz/customer/dao/xxxxDSS/mapper/CrmAccMap.xml]
### The error may involve com.xxxxx.xxxx.xxxx.customer.dao.xxxxDSS.ICrmAccountDAO.getByPrimaryKey
### The error occurred while executing a query
### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: interrupt
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:153)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:145)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:76)
at jdk.internal.reflect.GeneratedMethodAccessor72.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:427)
... 54 common frames omitted
Caused by: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: interrupt
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:83)
at org.mybatis.spring.transaction.SpringManagedTransaction.openConnection(SpringManagedTransaction.java:80)
at org.mybatis.spring.transaction.SpringManagedTransaction.getConnection(SpringManagedTransaction.java:67)
at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:337)
at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:86)
at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:62)
at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:325)
at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)
at jdk.internal.reflect.GeneratedMethodAccessor58.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.apache.ibatis.plugin.Invocation.proceed(Invocation.java:49)
at com.xxxxx.DSS.commons.mybatis.interceptor.OperatorInfoInterceptor.intercept(OperatorInfoInterceptor.java:45)
at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:62)
at jdk.proxy3/jdk.proxy3.$Proxy253.query(Unknown Source)
at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:151)
at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:62)
at jdk.proxy3/jdk.proxy3.$Proxy253.query(Unknown Source)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:151)
... 61 common frames omitted
Caused by: java.sql.SQLException: interrupt
at com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1612)
at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:1404)
at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1384)
at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1374)
at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:98)
at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:159)
at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:117)
at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:80)
... 79 common frames omitted
Caused by: java.lang.InterruptedException: null
at java.base/java.util.concurrent.locks.ReentrantLock$Sync.lockInterruptibly(ReentrantLock.java:159)
at java.base/java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:372)
at com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1609)
... 86 common frames omitted
三、问题排查
针对测试人员反馈的报错,OB厂商人员过来后,我们沟通希望测试人员能复测下,得到的反馈依然是和之前一样报错。我也向测试人员索要了测试账号和密码,准备自己在复测下,另外测试人员也为提供了他们应用服务器的相关信息,我可以登录其上去查询应用的具体报错信息。
我按照测试人员提供的账号和密码登录销售系统测试环境,重新测试了一次,确实如测试人员所反馈。
于是我登录应用服务器,获取了测试过程中应用的日志等相关信息,获取的应用打印数据库的日志信息都是一些SQL语句,未见有明显的报错异常,SQL语句看似也比较平常。
于是又查看了下打印的应用方面的日志,信息和测试人员所反馈的日志一样。
于是又让测试人员提供了连接Oracle测试环境的代理地址,在Oracle测试环境重新测试了下那个业务,发现正常,应用所打印的数据库日志和应用日志都没有报错的信息。
跟测试人员沟通,本次jdbc连接OB也采用了OB原厂提供的jdbc:oceanbase:oracle://xxx.xxx.xxx.xxx:2883/xxxx?pool=false&socketTimeout=7200000&characterEncoding=utf8&useCursorFetch=true&defaultFetchSize=100&useSSL=false&rewriteBatchedStatements=true&cachePrepStmts=true&useServerPrepStmts=true&usePieceData=true&allowSendParamTypes=true 方式进行连接,也采用了他们所提供的最新驱动。
于是OB厂商人员又排查了下OB的observer等相关日志,但从日志里仍然无法获取到什么有价值的信息。
到底是哪地方出现了问题,该如何进一步的排查呢,OB技术人员在和他们厂商研发沟通后,建议采用tcpdump抓包的方式,登录到应用服务器进行抓包,将抓包到的信息提供给研发进行分析。
登录应用服务器,使用命令tcpdump -i eth0 -nn -s0 -w xxxx_17.4.pcap进行抓包,命令执行后然后重新测试了那个应用,将抓取到的相关信息提供给了OB厂商的研发。
OB厂商研发在对抓包的日志进行分析后,仍然没有获得什么有价值的信息。
此时,真的全面陷入了困境,问题到底出在哪…
四、写在结尾
这个问题目前仍然是个悬而未决的问题,处于安全考虑,我司无法将业务代码提供给OB厂商,目前从应用日志和数据库日志及获取的SQL去查询都没有获取到有价值的信息。
所以这块也希望听听大家的意见,看看你有没有什么更好的排查方法,欢迎在评论区留言。
其实人生也是如此,有些问题容易找到答案,有些问题需要你经过很多摸索后才能找到答案,还有些问题可能你苦苦摸索也很难找到答案,但答案可能就在你看不到的地方。




