ORA-12518错误本质是PGA内存耗尽,非监听器故障;需查v$pgastat和v$process定位高消耗进程,可临时调高pga_aggregate_target或杀 rogue 进程,长期应启用连接池并避免隐式PGA泄漏。
ORA-12518 错误本质是 PGA 不够用,不是监听器坏了
这个错误表面看是监听器拒绝连接,实际根本原因是 oracle 实例无法为新会话分配 pga 内存。监听器只是“代为转达”失败——它尝试调用 oracle 进程启动服务进程(如 ora_p000_<sid></sid>),但实例内部因 pga 耗尽而返回失败,监听器就抛出 ora-12518。别急着重启监听器或改 listener.ora,那没用。
查 PGA 使用是否真爆了:用 v$pgastat 和 v$process
连上数据库(用已有连接,比如 sqlplus / as sysdba),立刻查两个视图:
-
SELECT * FROM v$pgastat WHERE name IN ('total PGA allocated', 'total PGA used mem', 'maximum PGA allocated');—— 如果total PGA allocated接近甚至超过pga_aggregate_target,就是硬顶上了 -
SELECT program, pga_used_mem, pga_alloc_mem FROM v$process ORDER BY pga_used_mem DESC FETCH FIRST 5 ROWS ONLY;—— 看是不是几个大查询/导出进程吃光了 PGA,常见凶手是oracle@... (J000)(job)、oracle@... (DW00)(data pump)或长事务排序
临时缓解:调高 pga_aggregate_target 或杀掉 rogue 进程
这是最快速见效的两招,但得看环境是否允许:
- 如果实例内存充足,且
sga_target没占满物理内存,可在线增大:ALTER SYSTEM SET pga_aggregate_target = 2G SCOPE=BOTH;(注意单位是字节,2G表示 2 GB) - 如果发现某个
PROGRAM占用pga_used_mem超过 500MB 且无业务必要,记下其spid,用kill -9 <spid></spid>(Linux)或orakill <sid><spid></spid></sid>(Windows)干掉它;别用ALTER SYSTEM KILL SESSION,它不释放 PGA,只断连接 - 警惕隐式 PGA 消耗:PL/SQL 中大集合(
TYPE t_tab IS TABLE OF ...)循环填充、未限制BULK COLLECT LIMIT,都可能单次分配数百 MB
长期规避:别让 PGA 成为连接瓶颈
ORA-12518 多发于应用频繁建连、又不做连接复用的场景。关键不在“加内存”,而在“控源头”:
- 确认应用是否启用了连接池(如 UCP、HikariCP),并设置了合理
maxPoolSize;裸用DriverManager.getConnection()每次新建连接,PGA 开销翻倍 - 检查是否有隐式游标泄漏:没 close 的
ResultSet、没 close 的Statement,在 Oracle JDBC 驱动中可能导致服务进程不释放 PGA - 避免在存储过程中用
DBMS_SQL动态执行大量语句——每次解析都额外吃 PGA;改用静态 SQL 或绑定变量批量处理 -
pga_aggregate_target不是越大越好:设太高会导致操作系统 swap,反而触发 OOM killer 杀oracle进程;建议初始值设为物理内存的 20%~25%,再根据v$pgastat的bytes processed和cache hit percentage微调
真正难处理的是那些“看起来正常但累积吃光 PGA”的小进程——它们不报错、不超时,只默默把内存占满。这时候必须结合 AWR 报告里的 PGA Memory Advisory 部分,而不是只盯实时视图。

















