问题场景

某企业在运行 Java 应用时出现如下数据库错误提示:

YAS-04003: maximum number of open cursors is 1000

导致业务无法正常运作。
image.png

适用范围

所有版本的 YashanDB 都可能受到此类问题影响。

根本原因

该问题源于 Druid 数据库连接池对 PreparedStatement 的缓存机制。具体配置如下:

share-prepared-statements: true
pool-prepared-statements: true
max-open-prepared-statements: 100

这些设置会使得 JDBC 层的 PreparedStatement 被持续缓存,而 YashanDB 会将每一个未释放的 Statement 视为一个活动游标。一旦累计打开游标数量超过数据库默认配置的 OPEN_CURSORS 上限,就会抛出上述异常。

解决方案

有两种思路可选:

① 调整数据库参数:增大 OPEN_CURSORS 的取值上限。

② 优化 Druid 配置:

将 share-prepared-statements 设置为 false
将 pool-prepared-statements 设置为 false
设置 max-open-prepared-statements = -1 表示不缓存

排查手段

可以通过以下语句查看当前打开的游标内容:

select b.sql_text
from vopencursora a, vsql b
where a.sql_id = b.sql_id;

结合 v$session 来判断是哪些业务会话未释放资源。

经验建议

当使用 Java 框架并搭配数据库中间件时,需要注意连接池与数据库行为之间的配合策略。合理调整缓存策略是避免资源泄露、提高系统稳定性的关键。


数据库砖家
1 声望0 粉丝