环境:
Redhat LINUX 6U5 64位+ORACLE 12.1.2.0 64位
描述:
安装了台测试库12.1.2.0 , 内存256GB,设置数据库memory_max_target、memory_target、sga_max_size 参数是 236GB,在使用inmemory功能时设置 "alter system set inmemory_size=200G scope=spfile" 后,重启库 报“ORA-04031: unable to allocate 4984 bytes of shared memory ("shared pool","unknown object","sga heap(2,0)","I/O stat latches")”
分析:
从报错信息来看是没有内存可以分析给数据库使用,但是已经分配了236G给数据库使用,为什么还报没有内存分配呢?很是疑问
1), 通过错误信息在metalink上找到如下相关问题:
链接如下:
https://support.oracle.com/epmos/faces/CommunityDisplay?resultUrl=https%3A%2F%2Fcommunity.oracle.com%2Fthread%2F3601868&_afrLoop=7034941515679&resultTitle=12c+and+inmemory_size+togheter+with+memory_target+gives+ORA-04031&commId=3601868&displayIndex=2&_afrWindowMode=0&_adf.ctrl-state=16pvs6tsxv_329
理解的大致意思是减少inmemroy_size的大小,inmemory_size 参数的大小是 memory_target大小的 的一半左右 ,执行“ alter system set inmemory_size=130G scope=spfile” 启库后一切正常。
2),但觉得既然内存这么大就要发挥它的最大效率,经过ITPUB网友指点最终解决了这个问题,原来inmemory_size不属于AMM管理,启用AMM管理内存导致SGA和inmemory_size的大小超过服务器的内存大小。
详见:http://www.itpub.net/thread-1931524-1-1.html
解决方法:
1),启用ASMM
alter system set memory_max_target=0 scope=spfile;
alter system set memory_target=0 scope=spfile;
alter system set sga_max_size=236G scope=spfile;
alter system set sga_target=236G scope=spfile;
alter system set inmemory_size=226G scope=spfile;
2),配置huge_page
a, 查看内存大小
b,将查看的内存总大小增加到limits.conf文件中
[root@etcdb ~]# cat /etc/security/limits.conf
#在最后端增加两行
oracle soft memlock 264633004
oracle hard memlock 264633004
c,执行在MOS 401749.1中下载的脚本hugepages_settings.sh
注意:执行脚本,注意这个过程中要求Oracle所有实例,包括数据库和ASM都启动、AMM关闭,以及SGA大小超过100M。
得出推荐结果
Press Enter to proceed...
Recommended setting: vm.nr_hugepages = 120836
d,将结果添加到sysctl.conf 结尾
[root@db ~]# tail -n 1 /etc/sysctl.conf
vm.nr_hugepages = 120836
e, 使用sysctl –p生效设置
f, 关闭数据库,重启服务器
g, HugePage启动检验, HugePages_Total 不等于HugePages_Free说明生效了
[root@db ~]# grep Huge /proc/meminfo
AnonHugePages: 145408 kB
HugePages_Total: 120836
HugePages_Free: 3
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
总结:
导致这个问题的原因是使用了AMM,由于SGA和PGA自动分配,有可能自动分配不合理,比如:PGA或其它pool 分配过大,导致在启库时不能分配足够多的内存空间给其它的pool,从而导致报4031错误,当然这是猜测并没有论证,事实真相还有待高手揭密。
参考来自: http://blog.itpub.net/17203031/viewspace-774843/