Oracle “解决ORA-4031问题”;无法分配x字节的共享内存“;

Oracle “解决ORA-4031问题”;无法分配x字节的共享内存“;,oracle,memory-management,oracle10g,Oracle,Memory Management,Oracle10g,我需要一些关于如何诊断和解决这个问题的建议。我不知道这是一个简单的服务器设置问题还是一个应用程序设计问题(或两者兼而有之) 此Oracle XE数据库每隔几个月报告一次或两次ORA-4031错误。它并不一致地指向sga的任何特定部分。最近的一个例子是: ORA-04031:无法分配8208字节的共享内存(“大池”、“未知对象”、“排序子范围”、“排序键”) 当这个错误出现时,如果用户不断刷新,点击不同的链接,他们通常会在不同的时间得到更多的此类错误,然后很快他们会得到“404NotFound”页

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

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

ORA-04031:无法分配8208字节的共享内存(“大池”、“未知对象”、“排序子范围”、“排序键”)

当这个错误出现时,如果用户不断刷新,点击不同的链接,他们通常会在不同的时间得到更多的此类错误,然后很快他们会得到“404NotFound”页面错误

重新启动数据库通常会解决一段时间的问题,然后大约一个月后,它会再次出现,但很少出现在程序中的同一位置(即,它似乎没有链接到代码的任何特定部分)(上面的示例错误是从一个Apex页面引发的,该页面从表中排序5000多行)

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

我正在Oracle Enterprise Linux 5上运行Oracle XE 10.2.0.1.0,内存为512MB。服务器仅运行数据库、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

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

不要忘记碎片。 如果你有很多流量,你的池可能会被分割,即使你有几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);
选择
“0(错误
解决方案:由nepasoft nepal提供
  • 一,-

    ps -ef|grep oracle
    
  • 2.-找到斯蒙并杀了pid

  • 3.-

    SQL> startup mount
    ORACLE instance started.
    
    Total System Global Area 4831838208 bytes
    Fixed Size                  2027320 bytes
    Variable Size            4764729544 bytes
    Database Buffers           50331648 bytes
    Redo Buffers               14749696 bytes
    Database mounted.
    
  • 4.-

    SQL> alter system set shared_pool_size=100M scope=spfile;
    
    System altered.
    
  • 五,-

    SQL> shutdown immediate
    
    ORA-01109: database not open
    Database dismounted.
    ORACLE instance shut down.
    
  • 六,-

    SQL> startup
    ORACLE instance started.
    
    Total System Global Area 4831838208 bytes
    Fixed Size                  2027320 bytes
    Variable Size            4764729544 bytes
    Database Buffers           50331648 bytes
    Redo Buffers               14749696 bytes
    Database mounted.
    Database opened.
    
  • 7.-

    SQL> create pfile from spfile;
    
    File created.
    

解决了

这是Oracle错误,共享池内存泄漏,很可能是db管理了大量分区。
解决方案:我认为修补程序不存在,请咨询oracle支持部门。您可以尝试使用Subpool或en(de)able AMM…

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

  • ps-ef | grep-oracle
  • 找到smon并杀死pid
  • SQL>启动装载
  • SQL>从spfile创建pfile;
  • 重新启动数据库将刷新您的池,这解决了效果而不是问题


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

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

    上面链接中的一些片段:

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

    “神谕的方式 共享池(一种非常重要的共享内存数据结构) operates基于使用绑定变量的开发人员。”


    “绑定变量非常重要——我无论如何都不能夸大它们的重要性。”

    听起来很合理,我会尝试一下。我已经为大型游泳池设置了最小规模,并将sga_目标提高到与sga_最大规模相同的水平。我会看看情况如何,谢谢。我会接受这个答案,因为我认为这是最好的建议,尽管测试这一点需要一个月左右的时间才能确定错误是否再次发生。好吧,已经一年了现在,到目前为止,我们在4月/5月的正常活动峰值没有产生任何内存错误或服务器停机。看起来不错:)+1用于查询。下次我遇到这些错误时,我会再次使用它,看看这是否是问题所在。谢谢OS:Solaris DB:oracle 10gum,您认为设置我的共享池大小将如何解决我的问题-特别是考虑到它已经是104857600(请阅读问题)这一事实,请查看此链接其他信息:顺便说一句,大池大小为0(即由ASMM自动管理)对于您提到的数据库配置和其他进程,512M的RAM似乎很低。top或vmstat等工具在操作系统级别上告诉您有关内存的什么信息?top表示512MB的大部分内存正在使用中,例如,目前报告的可用内存为25-40 MB。我不熟悉vmstat,但它报告:swpd=20916 free=40768 buff=8444 cache=341248欢迎使用OS。谢谢你为这个问题提供了答案,但是请注意,这个问题已经有5年了,而且已经回答了,说明的和你差不多。干杯和快乐编码:)这个答案很可能会帮助其他有类似症状的人。FWIW在我的例子中,我使用的是Apex,而不是Java,并且大部分已经使用了绑定变量。谢谢
    SQL> create pfile from spfile;
    
    File created.