解析ORA-4031“无法分配x字节的共享内存”

时间:2009-06-15 01:07:20

标签: oracle memory-management oracle10g

我需要一些关于如何诊断和解决此问题的指示。我不知道这是一个简单的服务器设置问题还是应用程序设计问题(或两者兼而有之)。

每隔几个月一次或两次此Oracle XE数据库报告ORA-4031错误。它并没有始终指出sga的任何特定部分。最近的一个例子是:

ORA-04031: unable to allocate 8208 bytes of shared memory ("large pool","unknown object","sort subheap","sort key")

当出现此错误时,如果用户不断刷新,点击不同的链接,他们通常会在不同时间获得更多这类错误,然后他们很快就会收到“404 not found”页面错误。< / p>

重新启动数据库通常会解决问题一段时间,然后一个月左右再次出现,但很少在程序中的同一位置(即它似乎与代码的任何特定部分无关)(上面的示例错误来自Apex页面,该页面正在从表格中排序5000多行。

我已经尝试将sga_max_size从140M增加到256M并希望这会有所帮助。当然,我不知道这是否有帮助,因为我必须重新启动数据库才能更改设置:)

我在带有512MB RAM的Oracle Enterprise Linux 5机器上运行Oracle XE 10.2.0.1.0。服务器仅运行数据库,Oracle Apex(v3.1.2)和Apache Web服务器。我安装了几乎所有的默认参数,它运行了一年左右。我通过调整应用程序代码来解决自己的大多数问题;它没有被广泛使用,也不是一个关键业务系统。

这些是我认为可能相关的一些当前设置:

pga_aggregate_target        41,943,040
sga_max_size              268,435,456
sga_target                146,800,640
shared_pool_reserved_size   5,452,595
shared_pool_size          104,857,600

如果这里有任何帮助,那就是当前的SGA尺寸:

Total System Global Area  268435456 bytes
Fixed Size                  1258392 bytes
Variable Size             251661416 bytes
Database Buffers           12582912 bytes
Redo Buffers                2932736 bytes

6 个答案:

答案 0 :(得分:6)

即使您使用的是ASMM,也可以为大型池设置最小大小(MMAN不会将其缩小到该值以下)。 您还可以尝试固定一些对象并增加SGA_TARGET。

答案 1 :(得分:5)

不要忘记碎片。 如果您有大量流量,您的池可能会碎片化,即使您有几个MB空闲,也可能没有大于4KB的块。 使用如下查询检查最大空闲块的大小:

 select
  '0 (<140)' BUCKET, KSMCHCLS, KSMCHIDX,
  10*trunc(KSMCHSIZ/10) "From",
  count(*) "Count" ,
  max(KSMCHSIZ) "Biggest",
  trunc(avg(KSMCHSIZ)) "AvgSize",
  trunc(sum(KSMCHSIZ)) "Total"
from
  x$ksmsp
where
  KSMCHSIZ<140
and
  KSMCHCLS='free'
group by
  KSMCHCLS, KSMCHIDX, 10*trunc(KSMCHSIZ/10)
UNION ALL
select
  '1 (140-267)' BUCKET,
  KSMCHCLS,
  KSMCHIDX,
  20*trunc(KSMCHSIZ/20) ,
  count(*) ,
  max(KSMCHSIZ) ,
  trunc(avg(KSMCHSIZ)) "AvgSize",
  trunc(sum(KSMCHSIZ)) "Total"
from
  x$ksmsp
where
  KSMCHSIZ between 140 and 267
and
  KSMCHCLS='free'
group by
  KSMCHCLS, KSMCHIDX, 20*trunc(KSMCHSIZ/20)
UNION ALL
select
  '2 (268-523)' BUCKET,
  KSMCHCLS,
  KSMCHIDX,
  50*trunc(KSMCHSIZ/50) ,
  count(*) ,
  max(KSMCHSIZ) ,
  trunc(avg(KSMCHSIZ)) "AvgSize",
  trunc(sum(KSMCHSIZ)) "Total"
from
  x$ksmsp
where
  KSMCHSIZ between 268 and 523
and
  KSMCHCLS='free'
group by
  KSMCHCLS, KSMCHIDX, 50*trunc(KSMCHSIZ/50)
UNION ALL
select
  '3-5 (524-4107)' BUCKET,
  KSMCHCLS,
  KSMCHIDX,
  500*trunc(KSMCHSIZ/500) ,
  count(*) ,
  max(KSMCHSIZ) ,
  trunc(avg(KSMCHSIZ)) "AvgSize",
  trunc(sum(KSMCHSIZ)) "Total"
from
  x$ksmsp
where
  KSMCHSIZ between 524 and 4107
and
  KSMCHCLS='free'
group by
  KSMCHCLS, KSMCHIDX, 500*trunc(KSMCHSIZ/500)
UNION ALL
select
  '6+ (4108+)' BUCKET,
  KSMCHCLS,
  KSMCHIDX,
  1000*trunc(KSMCHSIZ/1000) ,
  count(*) ,
  max(KSMCHSIZ) ,
  trunc(avg(KSMCHSIZ)) "AvgSize",
  trunc(sum(KSMCHSIZ)) "Total"
from
  x$ksmsp
where
  KSMCHSIZ >= 4108
and
  KSMCHCLS='free'
group by
  KSMCHCLS, KSMCHIDX, 1000*trunc(KSMCHSIZ/1000);

Code from

答案 2 :(得分:2)

所有当前的答案都解决了症状(共享内存池耗尽),而不是问题,这可能不会在sql \ JDBC查询中使用绑定变量,即使似乎没有必要这样做。传递没有绑定变量的查询会导致Oracle每次“硬解析”查询,确定其执行计划等。

https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::p11_question_id:528893984337

以上链接中的一些片段:

“Java支持绑定变量,您的开发人员必须开始使用预准备语句并将输入绑定到其中。如果您希望系统最终扩展到超过3或4个用户 - 您现在就会这样做(修复代码)这不是要考虑的事情,这是你必须要做的事情。这样做的副作用 - 你的共享池问题几乎会消失。这就是根本原因。“

“Oracle的方式 共享池(一个非常重要的共享内存数据结构) 操作是基于使用绑定变量的开发人员。“

“绑定变量非常重要 - 我不能以任何方式塑造或形成超越它们的重要性。”

答案 3 :(得分:0)

不需要以下内容,因为它们无法解决错误:

  1. 1 ps -ef | grep oracle
  2. 找到smon并为它杀死pid
  3. SQL&GT; startup mount SQL&gt;
  4. 从spfile创建pfile;
  5. 重新启动数据库将刷新您的池并解决影响而不是问题。

    修复你的large_pool,使其不能低于某一点或添加内存并设置更高的最大内存。

答案 4 :(得分:-1)

错误: ORA-04031:无法分配4064字节的共享内存(“共享池”,“选择增量$,minvalue,m ...”,“sga heap(3,0)”,“kglsim heap”)< /强>

Solution: by nepasoft nepal

1 ps -ef | grep oracle

2找到smon并杀死它的pid

3 SQL&gt; startup mount

ORACLE实例已启动。

系统全局总面积4831838208字节 固定大小2027320字节 变量大小4764729544字节 数据库缓冲区50331648字节 重做缓冲区14749696字节 数据库已安装 SQL&GT;

4 SQL&gt; alter system set shared_pool_size = 100M scope = spfile;

系统改变了。

5 SQL&gt;立即关机

ORA-01109:数据库未打开

数据库已卸下。 ORACLE实例关闭。

6 SQL&gt;启动

ORACLE实例已启动。

系统全局总面积4831838208字节 固定大小2027320字节 变量大小4764729544字节 数据库缓冲区50331648字节 重做缓冲区14749696字节 数据库已安装 数据库已打开。

7 SQL&gt;从spfile创建pfile;

创建了文件。

解决

答案 5 :(得分:-1)

这是Oracle错误,shared_pool中的内存泄漏,很可能是db管理大量分区。 解决方案:在我看来补丁不存在,请查看oracle支持。您可以尝试使用subpools或en(de)able AMM ...