|
分析和解决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=<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: 0 2.Windows系统:在微软的windows操作系统上,oracle进程集作为一个进程的许多线程来运行。地址空间不能超过2GB(包括堆栈、PGA、SGA)。这个限制可以突破到3GB或更高。(请看oracle文档<NOTE:46001.1>)。关于oracle数据库和Windows NT内存结构的情况,请查询技术公告板。Oracle进程使用的总的内存情况(不包括进程堆栈和代码)可以用query查看。 3.Unix系统:使用内置的shell命令: limit/ulimit。注意那些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 有可能是内存限制定得太小了,需要增大它。也可能是我们需索得太多 Oracle数据库是否有限制? 从oracle 9i以后,有一个参数决定一个oracle实例可以分配到PGA总量。<Note:223730.1>"Automatic PGA Memory Managment in 9i"提供了更多关于这方面的信息。下面的查询可以用来找出分配给所有会话的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数据库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数据库的服务器进程使用了过多的内存。一般地,对于服务器进程来说,oracle数据库和操作系统之间或多或少的可以就内存的使用达成一致。下面的命令允许你从操作系统的角度找出进程的内存使用量。 1.OpenVMS系统:“show system”命令给出进程和资源的使用情况的概览。那些频繁调用页面失败的进程常常消耗了大量的虚拟内存。“page”列指出物理内存的使用情况。“show process/continious”(原文如此,我怀疑是continuous)命令则给出物理内存(工作页面区)和虚拟内存的使用情况。 $ show system/page OpenVMS V7.2-1 on node BOBBIE 13-JUN-2003 09:56:30.44 Uptime 17 18:58:18 Pid Process Name State Pri I/O CPU Page flts Pages 20200101 SWAPPER HIB 16 0 0 00:00:02.45 0 0 20200106 CLUSTER_SERVER HIB 13 104 0 00:00:00.03 87 104 20200107 CONFIGURE HIB 10 21 0 00:00:00.06 77 17 $ sho process/id=xxx/cont: Process AROELANT 10:00:53 State CUR Working set 131 Cur/base priority 6/4 Virtual pages 11714 Current PC 800D9B28 CPU time 0 00:00:01.28 Current PSL 00000003 Direct I/O 178 Current user SP 7A5227F0 |