如何诊断 ORA-4030 错误
你可能在日志文件中或者屏幕上看到这个错误: ORA-04030 'out of process memory when trying to allocate %s bytes (%s,%s)'
该错误意味着 Oracle Server 进程无法从操作系统分配更多内存。该内存由 PGA(Program Global Area)组成,其内容取决于服务器配置。对于专用的服务器进程,内存包含堆栈以及用于保存用户会话数据、游标信息和排序区的 UGA(User Global Area)。在多线程配置中(共享服务器),UGA 被分配在 SGA(System Global Area)中,所以在这种配置下 UGA 不是造成 ORA-4030 错误的原因。
因此,ORA-4030 表示进程需要更多内存(堆栈 UGA 或 PGA)来执行其任务。
由于发生了这个错误,您因此无法从操作系统分配内存。这个错误可能是进程本身导致的,例如进程需要过多的内存,或者一些其他原因导致操作系统内存被耗尽,例如 SGA 太大或系统虚拟内存(物理内存 + 交换空间)中要容纳的进程过多。许多操作系统会对单个进程能够获取的内存量加以限制,以便自我保护。所以我们就会有下列问题:
是否仍然有足够的可用内存?
是否设置了操作系统限制?
是否设置了 Oracle 限制?
哪个进程需要的内存过多?
如何收集有关进程实际正在执行的任务的信息?
下面我们将讨论这些内容。
要回答这个问题,我们需要使用操作系统特定的工具来检查内存使用情况。
OpenVMS 系统:show memory 会提供关于物理内存和页面文件使用情况的信息:
Physical Memory Usage (pages): Total Free In Use Modified
Main Memory (256.00Mb) 32768 24849 7500 419
.....
Paging File Usage (blocks): Free Reservable Total
DISK$BOBBIEAXPSYS:[SYS0.SYSEXE]SWAPFILE.SYS 30720 30720 39936
DISK$BOBBIEAXPSYS:[SYS0.SYSEXE]PAGEFILE.SYS 226160 201088 249984
DISK$BOBBIE_USER3:[SYS0.PAGEFILE]PAGEFILE.SYS 462224 405296 499968
作为一般准则,页面文件中的可用空间总和应不低于整个空间总和的一半。
交换文件应几乎不使用,可用空间的大小应大致等于总空间的大小。
Windows 系统:在“任务管理器”的性能选项卡中检查内存使用情况。
Unix 系统:每种 unix 系统通常都有自己的工具来检查系统上的全局内存使用情况,如 top、vmstat……并且在不同的 OS 上,内存管理的运作方式各不相同。
top 通常会显示物理内存和交换空间的统计信息
swapon -s 显示交换空间使用情况
vmstat 显示可用物理内存
Linux 上的 top 输出示例:
top - 10:17:09 up 1:27, 4 users, load average: 0.07, 0.12, 0.05
Tasks: 110 total, 4 running, 105 sleeping, 0 stopped, 1 zombie
Cpu(s): 0.3% user, 1.6% system, 0.0% nice, 98.0% idle
Mem: 1033012k total, 452520k used, 580492k free, 59440k buffers
Swap: 1052248k total, 0k used, 1052248k free, 169192k cached
.....
如果有足够的内存可用,请检查操作系统是否存在强制限制。如果内存已被耗尽,我们就需要找出内存被用到了哪些地方。
如果似乎仍剩余大量的虚拟内存,那么有可能是我们需要使用的内存量是不被允许的。下面的步骤可以用来检查由操作系统实施的限制。
OpenVMS 系统:若要检查您可以使用的物理内存量,请使用授权工具来检查 working set 配额和页面文件配额。请参阅 OpenVMS 部分,了解使用了哪些配额以及如何修改配额。根据进程类型以及启动的方式,其所用的配额可能不是 Oracle中的那部分配额。show process/id=/quota 会显示某个进程还剩余多少配额。
UAF> show oracle7
Username: ORACLE7 Owner: Oracle7 DBA
Account: SUPPORT UIC: [200,2] ([SUPPORT,ORACLE7])
CLI: DCL Tables: DCLTABLES
Default: DISK$BOBBIE_USER1:[ORACLE7]
LGICMD: LOGIN
Flags:
Primary days: Mon Tue Wed Thu Fri
Secondary days: Sat Sun
No access restrictions
Expiration: (none) Pwdminimum: 6 Login Fails: 0
Pwdlifetime: (none) Pwdchange: 3-DEC-1997 15:38
Last Login: 27-MAY-2003 14:54 (interactive), 26-MAY-2003 16:15 (non-interactive)
Maxjobs: 0 Fillm: 1200 Bytlm: 180000
Maxacctjobs: 0 Shrfillm: 0 Pbytlm: 0
Maxdetach: 0 BIOlm: 500 JTquota: 8192
Prclm: 20 DIOlm: 500 WSdef: 2500
Prio: 4 ASTlm: 4000 WSquo: 4096
Queprio: 0 TQElm: 4000 WSextent: 30000
CPU: (none) Enqlm: 18000 Pgflquo: 750000
Authorized Privileges: .....
$ sho proc/id=20200139/quota
24-JUN-2003 12:30:54.39 User: ORACLE7 Process ID: 20200139
Node: BOBBIE Process name: "ORA_BOB901_PMON"
Process Quotas:
Account name: SUPPORT
CPU limit: Infinite Direct I/O limit: 100
Buffered I/O byte count quota: 9994816 Buffered I/O limit: 100
Timer queue entry quota: 99 Open file quota: 29997
Paging file quota: 145968 Subprocess quota: 10
Default page fault cluster: 64 AST quota: 496
Enqueue quota: 49995 Shared file limit: 0
Max detached processes: 0 Max active jobs:
Unix 系统:使用 limit/ulimit shell builtin 命令。请注意,unlimited 的不一定意味着不受限制,实际也可能是基于历史原因的限制,例如 2Gb。推荐基于真实需要的量进行设置:
Linux 输出示例:
aroelant@aroelant-be:~> ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
file size (blocks, -f) unlimited
max locked memory (kbytes, -l) unlimited
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
stack size (kbytes, -s) unlimited
cpu time (seconds, -t) unlimited
max user processes (-u) 7168
virtual memory (kbytes, -v) unlimited
有的问题可能是因为限制设置得过低造成的,所以需要进行相应的增加。也有的问题可能是由于我们需要使用的太多造成的。
请注意:其他 OS 参数设置(例如 maxuproc)可能会导致问题
例如,”ORA-4030 (QERHJ HASH-JOI,KLLCQAS:KLLSLTBA)”
Status: 92,Closed, Not a Bug
***来自于 bug - "Increased MAXUPROC from 1000 to 2000, restarted the listener and ORA-4030 errors were resolved"
从 Oracle Version 9i 开始我们引入了参数 PGA_AGGREGATE_TARGET,该参数尝试限制一个实例可以分配的 PGA 总量。“Automatic PGA Memory Managment”部分提供了关于此问题的更多信息。以下查询可用于查找分配给所有会话的 PGA 区的内存总量:
SQL> select
sum(value)/1024/1024 Mb
from
v$sesstat s, v$statname n
where
n.STATISTIC# = s.STATISTIC# and
name = 'session pga memory';
一些操作会需要大量的进程内存,例如大型的 PL/SQL 表或大量的排序操作。在这些情况下,在出现错误 ORA-4030 之前,进程将会运行一段时间,所以我们有希望在这段时间内能找出内存分配的位置和原因。您可以使用以下查询来查找从 Oracle 角度看来所用于 Oracle 进程的 PGA 和 UGA 大小。
SQL> col name format a30
SQL> select
sid,name,value
from
v$statname n,v$sesstat s
where
n.STATISTIC# = s.STATISTIC# and
name like 'session%memory%'
order by 3 asc;
此查询会显示列表中最占内存的进程。
通常,从操作系统的角度来确认进程内存使用情况,是一个好办法。毕竟,使用过多内存的不一定是 Oracle Server 进程。通常,对于服务器进程而言,Oracle 和操作系统之间基本都可以就内存的使用情况达成一致。通过以下命令,您可以查找操作系统中进程的内存使用情况。
SQL> select
sum(bytes)/1024/1024 Mb
from (
select
bytes
from
v$sgastat
union
select
value bytes
from
v$sesstat s, v$statname n
where
n.STATISTIC# = s.STATISTIC# and
n.name = 'session pga memory'
);
MB
----------
517.296406
在我的系统中,这个值要比通过任务管理器所看到的 VM值小约 30 Mb。
当您确定 Oracle 就是那个正在大量使用内存的进程时,此查询会显示使用内存最多的会话
这部分将只讨论 Oracle Server 进程。通过前面介绍的方法,您应该可以确定一个或多个 Oracle Server 进程导致了内存消耗。请记住,并非总是出现 ORA-4030 的进程导致了内存消耗,这个进程可能只是无法申请到需要的内存而已。
对于不断增加内存使用的进程,我们可以在其运行时进行查看以下方面的信息:
SQL> select
sql_text
from
v$sqlarea a, v$session s
where a.address = s.sql_address and
s.sid =;
SQL> select PID from v$process p, v$session s where p.addr=s.paddr and sid=;
SQL> oradebug setorapid
SQL> oradebug unlimit
SQL> oradebug dump errorstack 3
SQL> oradebug dump heapdump 536870917
SQL> oradebug tracefile_name (shows the path and filename information)
SQL> oradebug close_trace
如果问题间歇出现或某一进程由于报错太快而导致无法进行检查,且这个进程最有可能是内存消耗的原因,那么,在进程发生错误时我们可以使用以下事件来获取 heapdump:
SQL> alter session set events '4030 trace name heapdump level 536870917';
或者在数据库初始化文件中设置此事件并重新启动实例。
- init.ora: event="4030 trace name heapdump level 536870917"
- spfile: 运行: SQL> ALTER SYSTEM SET EVENT='4030 trace name heapdump level 536870917' scope=spfile;
对于 低于 9.2.0.5 的版本,请使用级别 5,而非级别 536870917。
Oracle技术支持工程师可使用该heapdump查找过多内存分配的原因。
如上所述,一些操作需要大量的内存。对于排序问题,减少 SORT_AREA_SIZE 会有所帮助。Oracle Server 进程会将 PGA 中的 SORT_AREA_SIZE 字节分配给排序操作。如果完成搜索需要更多内存,服务器进程将会使用temporary segment。这意味着,减少 SORT_AREA_SIZE 会对需要大量排序操作的查询性能产生影响。
对于 9i 及更高版本,通过将参数 WORKAREA_SIZE_POLICY 设置为 AUTO,以及在初始化文件中指定 PGA_AGGREGATE_TARGET 的大小,即可启用自动 SQL 执行内存管理功能。使用自动 PGA 内存管理将有助于减少发生 ORA-4030 错误的可能性。请注意,OpenVMS 操作系统在Oracle 9i版本上不支持 PGA_AGGREGATE_TARGET,但是在 Oracle 10g 版本上是支持的。有关更多详细信息,请参阅以下文档:
"Performance Issues After Increasing Workload",
"Automatic PGA Memory Managment",
"Top Oracle 9i init.ora Parameters Affecting Performance"
PL/SQL 程序也可分配大量内存,因此可能需要重写应用程序的某些部分。尽管 PL/SQL 表非常容易使用,但它确实需要在 PGA 中分配内存。
查看 optimizer 策略,一些访问路径可能会因排序操作、较多行上的函数使用等原因而需要更多内存。
在某些操作系统上(例如 Microsoft Windows),可能要降低 SGA 的大小以便于 PGA 获得更大的内存。
确保您的操作系统和 Oracle 限制设置合理。
确保有足够的可用内存(物理内存和交换空间)。
Provide assistance in resolving ORA-4030 errors on UNIX systems.
This document is useful for DBA's and System Administrators tasked with resolving an ORA-4030 error.
***Checked for relevance 17-Aug-2014***
The ORA-4030 error is caused when an Oracle process(while doing work on behalf of a client program) requests additional memory from the operating system, but the operating system cannot accommodate the request. This can occur because the operating system does not have enough physical memory or swap available for the process, the OS is configured to limit the amount of memory available for UNIX processes or an actual Oracle BUG has been encountered.
文档内容
症状 |
更改 |
原因 |
解决方案 |
参考 |
您运行了一个 PL/SQL package 或者 procedure,当进程使用了 4GB 的内存时总是会遇到 ORA-4030 异常。 _PGA_MAX_SIZE 和 PGA_AGGREGATE_TARGET 已经设置到一个大于 4GB 的值了,但是当 4GB 内存被使用时相同的错误仍然持续报出。
错误看起来类似于:
- 或者 -
升级数据库到 11.2.0.1 或更高的版本.
通过 trace 文件也能够确认进程被限制在 4GB 的大小。
从 OS 角度来看,这些错误的出现通常是因为 map 条目耗尽造成的。
每个进程仅仅有 65536 个 memory map 条目。
在 trace 中内存的分配或者错误可能包括(但不仅限于):
在 OS 或者在数据库层面来改变上限:
缺省 realfree allocator pagesize 是 64KB(65536),这样 64K 的条目能接纳 4GB 的内存。使用 256kB (262144),限制将会增大到 16GB。
In this Document
Goal |
Solution |
Why is the following error raised:
Why doesn't PGA_AGGREGATE_TARGET limit the processes' memory in this case?
Why doesn't _PGA_MAX_SIZE help either?
The memory allocation type "pl/sql vc2" is used when Oracle needs to allocate memory for a local variable in PL/SQL code. Some examples of PL/SQL local variables are as follows:
The problem can typically occur if:
The cause of the ORA-4030 error is usually a PL/SQL coding issue, as very larger amounts of data should really be stored in a table, or in the case of an infinite loop, the procedure call needs to have a limit.
The reason why neither PGA_AGGREGATE_TARGET nor _PGA_MAX_SIZE has any impact, is because PL/SQL local variables are not managed by the regular Oracle memory heaps. PL/SQL local variables are just like other programming languages' local variables and should adhere to good coding practices. Their size is only limited by the operating system memory limits.
About Me
...............................................................................................................................
● 本文整理自网络
● 本文在itpub(http://blog.itpub.net/26736162)、博客园(http://www.cnblogs.com/lhrbest)和个人微信公众号(xiaomaimiaolhr)上有同步更新
● 本文itpub地址:http://blog.itpub.net/26736162/abstract/1/
● 本文博客园地址:http://www.cnblogs.com/lhrbest
● 本文pdf版及小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/
● 数据库笔试面试题库及解答:http://blog.itpub.net/26736162/viewspace-2134706/
● QQ群:230161599 微信群:私聊
● 联系我请加QQ好友(646634621),注明添加缘由
● 于 2017-04-28 09:00 ~ 2017-04-30 22:00 在魔都完成
● 文章内容来源于小麦苗的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解
● 版权所有,欢迎分享本文,转载请保留出处
...............................................................................................................................
拿起手机使用微信客户端扫描下边的左边图片来关注小麦苗的微信公众号:xiaomaimiaolhr,扫描右边的二维码加入小麦苗的QQ群,学习最实用的数据库技术。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26736162/viewspace-2138387/,如需转载,请注明出处,否则将追究法律责任。