【问题分类】资源管理 / 内存泄露风险
【关键词】YAS-00103、stmt未关闭、open cursor、share pool、内存耗尽
一、问题现象
在某客户业务中,系统运行过程中频繁报出如下错误:
YAS-00103 no free block in sql main pool part 0
YAS-00105 out of memory to allocate hash table of size = 256
报错时伴随业务功能异常、部分SQL无法正常执行,严重影响使用。
二、影响版本
该问题出现在 YashanDB 22.2.4.1 版本中。
三、问题影响与风险
直接影响数据库的 SQL 执行能力,可能导致大量 SQL 报错无法下发;
长期不处理,可能拖垮 share pool,影响其他正常连接。
四、问题根因分析
现象表现:
错误提示表明 SQL主内存池空间不足,即“sql main pool part 0”无可用块;
根本原因在于:业务代码中创建 stmt(prepare/execute)后未调用 close 释放资源。
背景知识:
在 YashanDB 中,每条 SQL 在执行时会生成一个 stmt 对象,生命周期如下:
typedef enum EnAnlStmtStatus {
STMT_STATUS_IDLE = 0. // 已执行但未释放
STMT_STATUS_PREPARE = 1.
STMT_STATUS_EXECUTE = 2.
STMT_STATUS_FETCH = 3.
STMT_STATUS_FREE = 4 // 已释放,可复用
} AnlStmtStatus;
当 stmt 执行完毕但未显式 close 时,它就会停留在 idle 状态,无法自动复用。
此外:
cursor 不会在 SQL 执行完后销毁;
cursor 生命周期 = session 生命周期;
每个 session 的最大 open cursor 数由 OPEN_CURSORS 控制;
所有未释放 stmt 长期占用 share_pool 空间,最终导致 pool 空间枯竭。
五、问题复现方式(示例)
1.连续 prepare/execute 多条 SQL,不执行 stmt.close;
2.session 不断保持连接,cursor 不释放;
3.触发 SQL pool 内存耗尽,产生 YAS-00103 报错。
六、定位方法与排查建议
查看资源使用情况:
v$global_mpool:查看 SQL Pool 使用情况;
v$open_cursor:查看 session 当前所有打开 stmt 状态;
观察是否存在大量 STMT_STATUS_IDLE 的游标未释放。
配置参数确认:
OPEN_CURSORS:单 session 可打开最大 cursor 数;
SHARE_POOL_SIZE:若太小,内存更容易被锁死资源占满。
七、解决与规避建议
彻底解决:在应用中显式调用stmt.close()释放资源
示例:
Statement stmt = conn.prepareStatement(sql);
try {
stmt.execute();
} finally {
stmt.close(); // 非常关键
}
临时规避: 调高 SHARE_POOL_SIZE 参数,扩大内存缓冲; 示例命令:
ALTER SYSTEM SET SHARE_POOL_SIZE = xxx SCOPE = SPFILE;
最后防线:
如果无法控制应用层,可通过定期断开 idle session 来释放资源(如启用连接池 maxIdleTime);
或监控 v$open_cursor 状态,定期告警处理未释放资源。
八、经验总结
忘记关闭 stmt,是高频 SQL 报错与内存耗尽的重要诱因;
应用层规范编码、数据库端资源参数配置、运维监控三者需协同;
遇到类似 YAS-00103 报错,应优先排查 cursor 未释放情况,而非简单调大内存。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。