PostgreSQL jdbc driver的一个不完善之处

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介: 公司一个产品在上线到云以后,运行一段时间就会提示获取数据库连接失败,用 select * from pg_stat_activity; 查看所有连接,发现有很多连接最后一次执行的SQL语句是 SELECT t.typname,t.oid FROM pg_catalog.pg_type t JOIN pg_catalog.pg_namespace n ON (t.typspace = n.oid)  WHERE n.nspname  != 'pg_toast',经确认在程序中没有任何一处执行了该SQL。

公司一个产品在上线到云以后,运行一段时间就会提示获取数据库连接失败,用 select * from pg_stat_activity; 查看所有连接,发现有很多连接最后一次执行的SQL语句是 SELECT t.typname,t.oid FROM pg_catalog.pg_type t JOIN pg_catalog.pg_namespace n ON (t.typspace = n.oid)  WHERE n.nspname  != 'pg_toast',经确认在程序中没有任何一处执行了该SQL。

我把 SELECT t.typname,t.oid FROM pg_catalog.pg_type t JOIN pg_catalog.pg_namespace n ON (t.typspace = n.oid)  WHERE n.nspname  != 'pg_toast' 这段SQL在postgresql中执行,发现报错,不能通过。

后来经过仔细排查,原来是PostgreSQL的jdbc驱动里的一个不完善之处。


在PostgreSQL jdbc驱动的源码里,有一个PgDatabaseMetaData.java,在里边有一个getTypeInfo()方法调用了类似的SQL,PgDatabaseMetaData.java中的SQL定义如下:

    String sql;
    sql = "SELECT t.typname,t.oid FROM pg_catalog.pg_type t"
          + " JOIN pg_catalog.pg_namespace n ON (t.typnamespace = n.oid) "
          + " WHERE n.nspname  != 'pg_toast'";

    Statement stmt = connection.createStatement();
    ResultSet rs = stmt.executeQuery(sql);

该段SQL语句在我的postgresql中是可以执行的,返回的是所有类型和表名。

经过仔细比对,两个SQL有细微差别,我的环境里未关闭的连接执行的SQL中是ON (t.typspace = n.oid),而jdbc驱动中执行的是ON (t.typnamespace = n.oid),是字段名称不一样!

我用的jdbc驱动的版本是9.4.1212,而上述源码的版本是42.1.1,估计是新版本的驱动是针对较新版本的postgresql设计的,而新版本的数据库中pg_type表将原typespace字段改名为typenamespace,导致了SQL语句执行失败。

而getTypeInfo()方法中并没有在finally{}语句块中关闭statement,也许这个错误会导致后续的一些错误。


更新PostgreSQL的jdbc驱动到最新版本,连接泄露的问题没有再出现。

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
关系型数据库 MySQL
Loading class `com.mysql.jdbc.Driver‘. This is deprecated. The new driver class
Loading class `com.mysql.jdbc.Driver‘. This is deprecated. The new driver class
225 0
|
11月前
|
Java 关系型数据库 MySQL
Loading class `com.mysql.jdbc.Driver‘. This is deprecated. The new driver class is `com.mysql.cj.jdb
Loading class `com.mysql.jdbc.Driver‘. This is deprecated. The new driver class is `com.mysql.cj.jdb
122 0
|
11月前
|
存储 网络协议 Java
PostgreSQL JDBC 开发指导
Java Database Connectivity (JDBC) 是一个应用程序编程接口 (API),用于 编程语言 Java,它定义了客户端如何访问数据库。 它是Java标准版平台的一部分,提供查询和 更新数据库中的数据,并面向关系数据库。 PostgreSQL JDBC驱动程序(简称pgJDBC)允许Java程序连接到PostgreSQL®® 数据库使用标准的、独立于数据库的 Java 代码。是一个开源的JDBC驱动程序 用纯Java(类型4)编写,并使用PostgreSQL®本机网络协议进行通信。 因此,驱动程序独立于平台;编译后,驱动程序 可以在任何系统上使用。
106 0
|
Java 关系型数据库 MySQL
【JDBC】The new driver class is `com.mysql.cj.jdbc.Driver‘. The driver is automatically
【JDBC】The new driver class is `com.mysql.cj.jdbc.Driver‘. The driver is automatically
【JDBC】The new driver class is `com.mysql.cj.jdbc.Driver‘. The driver is automatically
|
关系型数据库 Java 数据库连接
使用jdbc连接本地postgreSQL的一个例子
使用jdbc连接本地postgreSQL的一个例子
175 0
|
Java 关系型数据库 MySQL
Could not load JDBC driver class [com.mysql.jdbc.Driver]
Could not load JDBC driver class [com.mysql.jdbc.Driver]
Could not load JDBC driver class [com.mysql.jdbc.Driver]
|
SQL druid Java
Java 执行 Postgresql Jdbc 类型异常时,复杂sql难定位的解决方案
Java 执行 Postgresql Jdbc 类型异常时,复杂sql难定位的解决方案
1217 0
Java 执行 Postgresql Jdbc 类型异常时,复杂sql难定位的解决方案
|
MySQL 关系型数据库 Java
离线安装jdbc driver
maven下载mysql jdbc driver地址https://mvnrepository.com/artifact/mysql/mysql-connector-java/8.0.16
1061 0
|
Java 关系型数据库 数据库连接
JDBC Driver接口连接数据库,实际开发基本不用
JDBC Driver接口连接数据库,实际开发基本不用
1258 0