分析和解决ora-4030错误


分析和解决ora-4030错误

ORA-4030意味着什么?

这个错误意味着oracle服务器进程不能从操作系统获得更多的内存。这里的内存指的是PGA(程序全局区)以及由配置决定的它的子项。对于专用的服务器进程,内存包括堆栈区、UGA(用户全局区)。UGA包括用户会话数据、游标信息和排序区。在多线程配置中(共享服务器),UGA处于SGA(系统全局区)中,它不会造成ora-4030错误。

因此,ora-4030意味着进程需要更多的内存(堆栈、UGA或者PGA)来执行它的工作。

是什么引起了这个错误?

这个错误表示操作系统不能分配足够的内存。这个错误可能是你的进程本身引起的,例如你的进程需要太多的内存,或者其它的原因引起操作系统内存枯竭,例如SGA区分得太大或者太多的进程竞争系统虚拟内存(物理内存+交换分区)。许多操作系统会限制某个进程获得的内存以保证系统稳定。

请按以下步骤检查你的系统:

· 是否仍有足够的内存供分配?

· 操作系统是否有限制?

· Oracle数据库是否有限制?

· 哪一个进程需要过多的内存?

· 如何收集那个(需要过多内存的)进程正在做什么的信息?

这些将在下一节里讨论。

进一步讨论主题:

· 避免此类错误的一般建议

· 参考

是否仍有足够的内存供分配?

要回答这个问题,我们需要使用操作系统特定的工具来检测内存使用情况。

1.OpenVMS系统:显示那些能告诉你物理内存和页面文件使用情况的信息。

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 2261 60201088 249984 DISK$BOBBIE_USER3:[SYS0.PAGEFILE]PAGEFILE.SYS 462224 405296 499968

作为一般的原则,页面文件中的空闲容量总量应该不低于总容量的一半。交换文件应该几乎不使用,空闲的容量应该几乎和总容量一样。

1.Windows系统:在任务管理器中查看内存使用情况。

2.Unix系统:每一个Unix系统都有自己的工具来检测全部内存的使用情况,例如top,vmstat…..,并且每一个系统都有所不同。

o top常用来显示物理内存和交换空间的情况。

o swapon –s 显示交换空间使用情况

o vmstat 显示空闲物理内存情况

Sample top output on Linux:

在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

.....

如果有足够的内存,那么请检查一下是否操作系统有强制限制。如果内存被耗尽了,我们就要找出这些内存被用在了哪里。

操作系统是否有限制?

如果仍有充足的虚拟内存剩余,可能是我们不能使用申请使用的那部分内存。请检查操作系统是否有限制。

1.OpenVMS系统:要检查你能使用的物理内存的总量,请检查工作(页面)区配额(working set quotas)和页面文件配额(pagefile quota)。请查询OpenVMS使用指南确定配额情况和如何修改它们。根据使用进程的不同以及启动它们方式的不同,配额使用将不同于oracle的统计。Process/id=

  1<process id="">/quota将显示对于一个特定的进程还有多少剩余配额可使用。   
  2  
  3  
  4  
  5UAF&gt; show oracle7   
  6  
  7  
  8  
  9Username: ORACLE7 Owner: Oracle7 DBA   
 10  
 11  
 12  
 13Account: SUPPORT UIC: [200,2] ([SUPPORT,ORACLE7])   
 14  
 15  
 16  
 17CLI: DCL Tables: DCLTABLES   
 18  
 19  
 20  
 21Default: DISK$BOBBIE_USER1:[ORACLE7]   
 22  
 23  
 24  
 25LGICMD: LOGINFlags:   
 26  
 27  
 28  
 29Primary days: Mon Tue Wed Thu Fri   
 30  
 31  
 32  
 33Secondary days: Sat Sun   
 34  
 35  
 36  
 37No access restrictions   
 38  
 39  
 40  
 41Expiration: (none) Pwdminimum: 6 Login Fails: 0   
 42  
 43  
 44  
 45Pwdlifetime: (none) Pwdchange: 3-DEC-1997 15:38   
 46  
 47  
 48  
 49Last Login: 27-MAY-2003 14:54 (interactive), 26-MAY-2003 16:15 (non-interactive)   
 50  
 51  
 52  
 53Maxjobs: 0 Fillm: 1200 Bytlm: 180000   
 54  
 55  
 56  
 57Maxacctjobs:0 Shrfillm: 0 Pbytlm: 0   
 58  
 59  
 60  
 61Maxdetach: 0 BIOlm: 500 JTquota: 8192   
 62  
 63  
 64  
 65Prclm: 20 DIOlm: 500 WSdef: 2500   
 66  
 67  
 68  
 69Prio: 4 ASTlm: 4000 WSquo: 4096   
 70  
 71  
 72  
 73Queprio:0 TQElm: 4000 WSextent: 30000   
 74  
 75  
 76  
 77CPU: (none) Enqlm: 18000 Pgflquo: 750000   
 78  
 79  
 80  
 81Authorized Privileges: .....   
 82  
 83  
 84  
 85$ sho proc/id=20200139/quota   
 86  
 87  
 88  
 8924-JUN-2003 12:30:54.39 User: ORACLE7 Process ID: 20200139   
 90  
 91  
 92  
 93Node: BOBBIE Process name: "ORA_BOB901_PMON"   
 94  
 95  
 96  
 97Process Quotas:   
 98  
 99  
100  
101Account name: SUPPORT   
102  
103  
104  
105CPU limit: Infinite Direct I/O limit:100   
106  
107  
108  
109Buffered I/O byte count quota: 9994816 Buffered I/O limit: 100   
110  
111  
112  
113Timer queue entry quota: 99 Open file quota:29997   
114  
115  
116  
117Paging file quota: 145968 Subprocess quota: 10   
118  
119  
120  
121Default page fault cluster:64 AST quota: 496   
122  
123  
124  
125Enqueue quota: 49995 Shared file limit: 0   
126  
127  
128  
129Max detached processes: 0 Max active jobs: 0   
130  
131  
132  
1332.Windows系统:在微软的windows操作系统上,oracle进程集作为一个进程的许多线程来运行。地址空间不能超过2GB(包括堆栈、PGA、SGA)。这个限制可以突破到3GB或更高。(请看oracle文档<note:46001.1>)。关于oracle数据库和Windows NT内存结构的情况,请查询技术公告板。Oracle进程使用的总的内存情况(不包括进程堆栈和代码)可以用query查看。   
134  
135  
136  
1373.Unix系统:使用内置的shell命令: limit/ulimit。注意那些unlimited的不一定意味着无限制,而是可能有着老系统的限制,例如2GB。   
138  
139  
140  
141Linux系统上输出的一个例子:   
142  
143  
144  
145aroelant@aroelant-be:~&gt; ulimit -a   
146  
147  
148  
149core file size(blocks, -c) 0   
150  
151  
152  
153data seg size(kbytes, -d) unlimited   
154  
155  
156  
157file size(blocks, -f) unlimited   
158  
159  
160  
161max locked memory(kbytes, -l) unlimited   
162  
163  
164  
165max memory size(kbytes, -m) unlimited   
166  
167  
168  
169open files(-n) 1024   
170  
171  
172  
173pipe size(512 bytes, -p) 8   
174  
175  
176  
177stack size(kbytes, -s) unlimited   
178  
179  
180  
181cpu time(seconds, -t) unlimited   
182  
183  
184  
185max user processes(-u) 7168   
186  
187  
188  
189virtual memory(kbytes, -v) unlimited   
190  
191  
192  
193有可能是内存限制定得太小了,需要增大它。也可能是我们需索得太多   
194  
195  
196  
197Oracle数据库是否有限制?   
198  
199  
200  
201从oracle 9i以后,有一个参数决定一个oracle实例可以分配到PGA总量。<note:223730.1>"Automatic PGA Memory Managment in 9i"提供了更多关于这方面的信息。下面的查询可以用来找出分配给所有会话的PGA区域的内存总量。   
202  
203  
204  
205SQL&gt; select sum(value)/1024/1024 Mb from v$sesstat s, v$statname n   
206  
207  
208  
209Where n.STATISTIC# = s.STATISTIC# and name =’session pga memory’;   
210  
211  
212  
213哪一个进程需要过多的内存? 某些操作需要大量的内存例如巨大PL/SQL表或者大量的排序操作。在这种情况下,在返回ora-4030错误之前进程将运行一段时间。希望我们可以找出内存被分配给哪个进程以及为什么被分配。你可以使用如下的查询查出oracle数据库PGA和UGA的运行情况。   
214  
215  
216  
217SQL&gt;col name format a30SQL&gt;select sid,name,value from v$statname n,v$sesstat s   
218  
219  
220  
221where n.STATISTIC# = s.STATISTIC# and name like 'session%memory%' order by 3 asc;   
222  
223  
224  
225这个查询将显示列表中的对内存“饥饿”的进程。从操作系统角度来看,确定进程的内存使用量也是一个好主意。总之,不大可能是oracle数据库的服务器进程使用了过多的内存。一般地,对于服务器进程来说,oracle数据库和操作系统之间或多或少的可以就内存的使用达成一致。下面的命令允许你从操作系统的角度找出进程的内存使用量。   
226  
227  
228  
2291.OpenVMS系统:“show system”命令给出进程和资源的使用情况的概览。那些频繁调用页面失败的进程常常消耗了大量的虚拟内存。“page”列指出物理内存的使用情况。“show process/continious”(原文如此,我怀疑是continuous)命令则给出物理内存(工作页面区)和虚拟内存的使用情况。   
230  
231  
232  
233$ show system/page   
234  
235  
236  
237OpenVMS V7.2-1 on node BOBBIE 13-JUN-2003 09:56:30.44 Uptime 17 18:58:18   
238  
239  
240  
241Pid Process Name State Pri I/O CPU Page flts Pages   
242  
243  
244  
24520200101 SWAPPER HIB 16 0 0 00:00:02.45 0 0   
246  
247  
248  
24920200106 CLUSTER_SERVER HIB 13 104 0 00:00:00.03 87 104   
250  
251  
252  
25320200107 CONFIGURE HIB 10 21 0 00:00:00.06 77 17   
254  
255  
256  
257$ sho process/id=xxx/cont:   
258  
259  
260  
261Process AROELANT 10:00:53   
262  
263  
264  
265State CUR Working set 131   
266  
267  
268  
269Cur/base priority 6/4 Virtual pages 11714   
270  
271  
272  
273Current PC 800D9B28 CPU time 0 00:00:01.28   
274  
275  
276  
277Current PSL 00000003 Direct I/O 178   
278  
279  
280  
281Current user SP 7A5227F0 Buffered I/O 962   
282  
283  
284  
285PID 20200469 Page faults 1312   
286  
287  
288  
289UIC [SUPPORT,AROELANT] Event flags C0000003 C0000000   
290  
291  
292  
2932.Windows系统:对于微软的windows操作系统来说,oracle进程集作为一个进程的许多线程来运行。到目前为止,我还没有找到一个方法来查看某个线程的内存使用情况。然而我们可以检查出oracle是否对操作系统分配的内存感到满意。从操作系统的角度来看,我们可以使用任务管理器。调出任务管理器,点击“查看”按钮,选择“选择列”,在弹出的窗口中在“虚拟内存大小”前打上勾。oracle.exe进程使用的虚拟内存大小( VM size)应该和SGA、PGA和进程堆栈以及代码使用的内存总量相匹配。下面的查询命令可以给出oracle使用的内存量,然而,这不包括进程堆栈以及代码使用的内存量。   
294  
295  
296  
297select 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   
298  
299  
300  
301\----------517.296406   
302  
303  
304  
305在我的系统上,任务管理器中显示的虚拟内存大小比上面的查询出的内存使用量多大约30MB。当你确认是oracle使用了这个内存,这个查询将给出哪一个会话用得最多。   
306  
307  
308  
3093.Unix系统:“top”工具是一个很有用的工具,你能够定制显示和排序的列。“ps”命令在大多数系统中可以使用,但也有些不能。例如,在Linux上,“ps -AF --sort resident”将列出所有的进程最近的最大常驻内存集(resident set)(注二)。你也可参考<note:174555.1> "UNIX: Determining the Size of an Oracle Process".   
310  
311  
312  
313如何收集那个(需要过多内存的)进程正在做什么的信息?   
314  
315  
316  
317本节将只讨论oracle服务器进程。使用前面几节介绍的方法,你应该可以判定一个或多个oracle服务器进程造成了内存资源的枯竭。记住并不总是由于进程造成了内存资源的枯竭从而导致ORA-4030错误。这个错误仅仅意味着进程不能获得它需要的内存资源。   
318  
319  
320  
321如果进程不断增长对内存的需求,我们可以在它运行的时候查看一下它的情况。   
322  
323  
324  
325o 你可以用下面的查询语句在v$sql_area表中查询有什么进程正在执行中。   
326  
327  
328  
329SQL&gt; select sql_text from v$sql_area a, v$session s   
330  
331  
332  
333where a.address = s.sql_address and s.sid = <sid>;   
334  
335  
336  
337o We can force a heapdump and have it examined by oracle support services。(这句不知如何译)   
338  
339  
340  
341SQL&gt; oradebug unlimitSQL&gt; oradebug setorapid 10 (这是对应 oracle pid, 用“setospid”对应操作系统的进程id)SQL&gt; oradebug dump heapdump 7   
342  
343  
344  
345如果问题不再发生,或者某些进程太快而不能作这样的检查,很有可能这就是引起内存枯竭的原因。我们可以在这个进程引起这个错误时使用事件集来获得一个 heapdump.   
346  
347  
348  
349SQL&gt; alter session set events '4030 trace name heapdump level 25';   
350  
351  
352  
353或者在数据库的init.ora文件中设置这个事件。<note:21234.1> EVENT: 10261 "Limit the size of the PGA heap" 这个dump能帮助Oracle Support分析并找出引起过多的内存分配的原因。   
354  
355  
356  
357对于如何避免这个错误的一般建议。   
358  
359  
360  
361o 正如前面提到的一样,某些操作会需要大量的内存。对于排序操作来说,减少SORT_AREA_SIZE可能有所帮助。Oracle服务器进程会在PGA中分配排序操作需要的SORT_AREA_SIZE字节。如果完成某个查询需要过多的内存,服务器进程将会使用临时段。这意味着,当查询需要大量的排序操作时,更少的SORT_AREA_SIZE可以使得执行更紧凑。   
362  
363  
364  
365o 对于9i或更高版本的oracle数据库,可以设备参数WORKAREA_SIZE_POLICY为AUTO来打开自动SQL execution内存管理功能,也可以在初始化文件中指定PGA_AGGREGATE_TARGET的大小。   
366  
367  
368  
369<note:262946.1> "Performance Issues After Increasing Workload", <note:223730.1> "Automatic PGA Memory Managment in 9i", <note:223299.1> "Top Oracle 9i init.ora Parameters Affecting Performance"   
370  
371  
372  
373o PL/SQL例程也可能会需要大量内存,因此有必要在你的应用程序中重写这部分查询代码。如果某个PL/SQL表经常被使用,它确实会在PGA中分配一块内存。   
374  
375  
376  
377o 再看一下优化策略,由于排序操作可能某些访问路径会需要太多的内存,函数调用返回过多的行等等……   
378  
379  
380  
381o 在某些操作系统上,例如Microsoft windows,SGA的大小应该降低,以便于PGA获得更大的内存。   
382  
383  
384  
385o 确信你的操作系统和oracle数据库的内存限制是适度的。   
386  
387  
388  
389o 确信有足够的内存(物理内存和交换空间)。   
390  
391  
392  
393参考   
394  
395  
396  
397General:   
398  
399  
400  
401<note:237899.1> Resolving ORA-4030 Errors After Upgrading   
402  
403  
404  
405NT:   
406  
407  
408  
409<note:116076.1> Tackling ORA-4030 on WindowsNT   
410  
411  
412  
413<note:46001.1> Oracle Database and the Windows NT memory architecture, Technical Bulletin   
414  
415  
416  
417Unix:   
418  
419  
420  
421<note:199746.1> How to Resolve ORA-4030 Errors on UNIX (unix specific but general enough for some suggestions)   
422  
423  
424  
425UNIX: Determining the Size of an Oracle Process   
426  
427  
428  
429  
430  
431  
432  
433VMS:   
434  
435  
436  
437<note:67033.1> Background process quotas <note:68663.1> Dedicated server process quotas (SQL*Net V2.3.3, V8.0.X)<note:70671.1> Process quotas for Bequeath connections (V7, V8)<note:68849.1> Bequeath listener process quotas (V7, V8)<note:68226.1> Listener process quotas (SQL*Net V2.3.3, V8.0.X)   
438  
439  
440  
441  
442  
443  
444  
445@ Internal:   
446  
447  
448  
449@ <note:21234.1> EVENT: 10261 "Limit the size of the PGA heap"   
450  
451  
452  
453@ This event is very usefull. It will cause the process to dump information when the PGA grows above the specified limit   
454  
455  
456  
457  
458  
459  
460  
461本人注一:工作(页面)区(working set):1.为避免过多的调页所必须激活的用户页面的集合。2.为避免系统失效,调页所需要的实存容量。   
462  
463  
464  
465本人注二:常驻内存集(resident set):在虚存系统中,任一时候都存在于主存储器内的某个程序的页面 或程序段的全部。</note:21234.1></note:68226.1></note:68849.1></note:70671.1></note:68663.1></note:67033.1></note:199746.1></note:46001.1></note:116076.1></note:237899.1></note:223299.1></note:223730.1></note:262946.1></note:21234.1></sid></note:174555.1></note:223730.1></note:46001.1></process>
Published At
Categories with 数据库类
Tagged with
comments powered by Disqus