ToB企服应用市场:ToB评测及商务社交产业平台

标题: PostgreSQL(十二)报错:Tried to send an out-of-range integer as a 2-b [打印本页]

作者: 大连全瓷种植牙齿制作中心    时间: 2024-7-17 03:04
标题: PostgreSQL(十二)报错:Tried to send an out-of-range integer as a 2-b
一、报错场景

今天写了一个历史数据处理步伐,在开发环境、测试环境都可以正常实行,但是放到生产环境上就不可,报了一个如许的错误:

意思大概是:当把数据发送给后端的时间,出现了一个 I/O 异常。
完备报错截图如下:
顺着日记中异常栈信息往下看,可以看到下面有一处具体的报错原因:

意思大概是:出现了一个IO异常,实验发送一个二进制 int 类型数值时,当前数值超出了大小限定:5100
  1. Caused by: java.io.IOException: Tried to send an out-of-range integer as a 2-byte value: 51000
  2.         at org.postgresql.core.PGStream.sendInteger2(PGStream.java:359)
  3.         at org.postgresql.core.v3.QueryExecutorImpl.sendParse(QueryExecutorImpl.java:1604)
  4.         at org.postgresql.core.v3.QueryExecutorImpl.sendOneQuery(QueryExecutorImpl.java:1929)
  5.         at org.postgresql.core.v3.QueryExecutorImpl.sendQuery(QueryExecutorImpl.java:1487)
  6.         at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:347)
  7.         ... 140 common frames omitted
复制代码

二、源码分析

我们根据报错提示,找到源码对应的位置,该源码位于 postgresql 依赖中,Maven坐标如下:
  1. <!--postgresql 数据库驱动依赖 -->
  2. <dependency>
  3.     <groupId>org.postgresql</groupId>
  4.     <artifactId>postgresql</artifactId>
  5.     <version>42.6.0</version>
  6.     <scope>runtime</scope>
  7. </dependency>
复制代码
源码位置如下:
可以看到这里有一个大小限定,Short.MAX_VALUE 对应的就是 Short 类型的最大值,为 32767。也就是说,在 PostgreSQL 中,如果参数的数量超过 32767 之后,就会抛出 Tried to send an out-of-range integer 这个异常。

三、实际原因(更加复杂)

原理都懂,但是细想的话还是有以下两个问题:
于是我们继续根据上面的异常栈信息进行排查,针对第2层栈信息在当地打断点调试。
  1. Caused by: java.io.IOException: Tried to send an out-of-range integer as a 2-byte value: 51000
  2.         at org.postgresql.core.PGStream.sendInteger2(PGStream.java:359)
  3.         at org.postgresql.core.v3.QueryExecutorImpl.sendParse(QueryExecutorImpl.java:1604)
  4.         at org.postgresql.core.v3.QueryExecutorImpl.sendOneQuery(QueryExecutorImpl.java:1929)
  5.         at org.postgresql.core.v3.QueryExecutorImpl.sendQuery(QueryExecutorImpl.java:1487)
  6.         at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:347)
  7.         ... 140 common frames omitted
复制代码
首先找到第二层栈信息对应的源码位置,并在当地进行debug:
这里我当地调试的时间,是传了 11 个参数,但是在第二层断点中入参却变成了 352 个,这是为什么呢?
不要慌,其实这里的 queryUtf8 变量中存储的就是我们的 SQL 了,我们直接检察下这个变量的字符串即可:
终于,找到罪魁罪魁了,由于项目中集成了 ShrdingJDBC,导致实行 SQL 的时间会自动拼接分表 SQL 并进行 UNION ALL,导致入参个数猛增几十倍。所以:

51000 远远超出 32767 的限定,所以抛出 IO 异常。

四、解决思路

可以根据以下两种情况,分别进行解决:
整理完毕,完结撒花~




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4