然后很快从同事那里得到了反馈,说调整了sga为200M之后数据库貌似起不来了。如果是这样的情况,也是意料之中,报错信息是:
ORA-27102:
out of memory
Linux-x86_64 Error: 12: Cannot allocate memory
其实27102的错误如果系统级的报错是
ORA-27102: out of memory
Linux-x86_64 Error: 28: No space left on device
那么和内核参数shmall和shmmax关联要大一些,而目前的是 Linux-x86_64 Error: 12: Cannot allocate memory其实另有原因,但是当时也没有多想。就让同事继续提供free -m的结果
[oracle@dev_mobileBI dbs]$ free -m
total used free shared buffers cached
Mem: 5709 4762 946 0 39 3365
内核参数的值如下:
kernel.shmmax = 2147483648
kernel.shmall = 536870912
其实这个时候看,剩余内存还多,shmmax尽管有些小,但是完全是可以支持200M的SGA的。
所以这个内核参数的修改也是一种方式,但不是解决这个问题的根本。
我们就回到了参数文件上,这个时候和同事重新审视这个文件,把SGA改为原值,仍然启动失败,报27012的错误。
这个时候感觉问题就比较蹊跷,数据库停了之后重启竟然就报错,其它参数的设置都恢复了原来的值还是启动报错。
这个时候感觉是参数文件哪里出现了问题,所幸这个环境的定制参数也不多,我们可以理一理创建数据库的一个环节,手工建库,其实在10g中只要保留4个参数就可以了,11g3个,即db_name,control_files,sga_target(或者其他的内存组件参数),所以就把参数文件改为最简单的方式,启动到nomount,就可以了。
从这个情况可以推理出来应该是在当前的参数文件中存在着一些参数的限制导致启动失败。
参数文件的设置大体是下面的样子:
mbidev.__oracle_base='/home/U01/app/oracle'#ORACLE_BASE set from environment
*.audit_file_dest='/home/U01/app/oracle/admin/mbidev/adump'
*.audit_trail='db'
*.compatible='11.2.0.0.0'
*.control_files='/home/U01/app/oracle/oradata/mbidev/control01.ctl',/oradata/mbidev/control03.ctl'
*.db_block_size=8192
*.db_domain=''
*.db_name='mbidev'
*.db_recovery_file_dest='/home/U01/app/oracle/fast_recovery_area'
*.db_recovery_file_dest_size=10737418240
*.diagnostic_dest='/home/U01/app/oracle'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=mbidevXDB)'
*.lock_sga=TRUE
*.open_cursors=300
*.pre_page_sga=TRUE
*.processes=300
*.remote_login_passwordfile='EXCLUSIVE'
*.undo_tablespace='UNDOTBS1'
所以检查了一圈,印象中也没有很特别的参数,所以就采用了排除法,先从自己熟悉的参数开始缩减,排除了domain,remote_login_password,compatible,audit的参数
那么接下来就是不大熟悉的参数了,有两个pre_page_sga和lock_sga,经过排除,发现最后的症结在于参数lock_sga
如果去掉这个参数设置,数据库就能够正常启动,经过验证,发现默认值为false
这个时候,我们不能太偏离问题的方向,我们需要调整SGA,这个时候问题已经解决了,我们先处理SGA的部分,至于lock_sga的部分可以暂时放一放回头再来深究为什么有这种情况。
所以调整SGA之后,发现内核参数shmmax,shmall还是有一些问题,经过调整,就达到了开发同学的预期目标。
我们再来看一下lock_sga的奇怪问题,这个参数默认值为false,如果设置为true,可以保证整个sga被锁定在物理内存中,可以防止sga被换出到swap中,还有辅助的参数pre_page_sga来保证在数据库初始化的时候把sga都放入内存中。
而为什么这个参数设置为true,会有27102的错误呢,其实和系统的资源配置有关。可以通过ulimit -a查看相关的信息
默认locked memory为32KB,肯定无法满足,所以我们需要设置memlock
$ ulimit -a|grep lock
max locked memory (kbytes, -l) unlimited
file locks (-x) unlimited
比如对oracle用户设置较高的资源使用权限。
oracle soft memlock unlimited
oracle hard memlock unlimited
这个时候设置lock_sga和pre_page_sga为true,启动就没有任何问题了,不过确实能够明显感受到启动的时候还是很迟缓的。这两个参数在有些优化场景中还是有一席之地,但是相对来说使用范围还是有限。