注册
JDBC-使用JDBC日志分析问题的方法
专栏/滴水藏海/ 文章详情 /

JDBC-使用JDBC日志分析问题的方法

yuao 2021/12/28 2766 6 0
摘要 本文举例说明如何开启JDBC日志和进行反向程序代码重构

对于使用了JDBC接口的程序,如果出现性能问题或者异常报错,正式生产系统的应用设计会相当复杂,我们不可能将生产系统的程序代码拿出来进行分析关于数据库操作的代码,我们该如何进行排查呢?答案是JDBC追踪日志,我们可以通过开启JDBC日志来查看程序中关于数据库操作的方法、耗时以及异常报错等,甚至可以通过JDBC日志来反向模拟应用进行数据库操作的测试程序,当然这需要一些编程知识。
需要注意的是,开启JDBC日志会严重影响数据库响应时间,正式生产系统中严禁开启JDBC日志!

开启JDBC日志方法:
在JDBC连接串中增加扩展属性:logLevel和logDir,分别表示开启日志级别和日志保存位置,一般使用logLevel=all记录全部日志,如果没有指定logDir则一般在JDBC程序的工程目录下,文件生成规则为:dm_jdbc_年_月_日_时_分_秒_序号.log,其中序号从0开始,例如dm_jdbc_2021_12_23_10_46_10_0.log
连接串举例:

jdbc:dm://127.0.0.1?logLevel=all&logDir=/home/dmdba/jdbclog

JDBC操作数据库无非逃不过这些步骤:
1.建立数据库连接
2.创建对应的语句句柄
3.如果是预编译sql,则进行变量值绑定
4.执行语句
5.获取元数据,获取结果集数据
6.关闭句柄和连接资源

举个例子我们获取到JDBC日志如下:
图片1.png
…省略截图
图片2.png
我们可以得到如下信息:
该sql操作使用了预编译方式,prepareStatment来准备sql语句句柄,绑定变量参数共计7个,执行后获取元数据信息得到查询字段个数为310个,然后依次使用getObject方法得到每一行每个字段的数据值,最后关闭各对象资源。
根据上述分析我们大致可以写出如下程序逻辑,然后配合我们的问题进行问题重现和分析啦。伪代码如下:

Connection conn = getConnection();
PreparedStatement pst = conn.prepareStatement(sql);
pst.clearParameters();
for (int i = 0; i < params.length; i++) {
        pst.setObject(i + 1, params[i]);
}
ResultSet rs = pst.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
while (rs.next()) {
	for (int i = 0; i < columnCount; i++) {
		String columnName = rsmd.getColumnName(i + 1);
		Object columdValue = rs.getObject(columnName);
	}
}
rs.close();
pst.close();
conn.close();

实际上JDBC日志信息非常丰富,上述只是举个例子,我们完全可以通过分析JDBC日志模拟一个简单的数据库操作测试程序,帮助我们进行问题定位和分析。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服