首先谈谈自动共享内存(ASMM)
自动共享内存是10g的一个新特性,它可以使SGA自动来管理,给DBA对内存管理带来了好处。用户可能面对这样的情况:数据库在白天需要处理大量的OLTP任务,这些任务需要大量的Buffere Cache内存,而在夜间系统则可能需要运行大量的批处理任务,这些任务又需要大量的Large Pool内存,为了让系统在有限的资源下高效运行,在oracle10g的自动共享内存管理(Automatic Shared Memory Management, ASMM)可以实现上面的需求,当运行OLTP任务时,BufferCache会获取大部分内存以达到良好的性能;当需要运行DSS批处理任务或者RMAN备份时,内存会自动转移给Large Pool, 以便并行查询和备份获得更多的内存资源,以使业务系统更快,更有效地得以执行。
在Oracle10g的内存管理中,使用了一个新的初始化参数SGA_TARGET, 通过指定这个参数,就可以让Oracle自动管理SGA中大多数的内存分配。SGA_TARGET是一个动态参数,但是设置此参数大小时,不能超过SGA_MAX_SIZE所设定的大小。如果试图修改SGA_GARGET超过SGA_MAX_SIZE,那么系统会给出错误信息:如图01所示:
在使用自动共享内存管理时,可以自动分配的内存区包括:
BufferCache
SharedPool
Java Pool
Large Pool
要启动自动共享内存,需要将参数SGA_TARGET设置为非0值,自动共享内存需要将统计参数STATISTICS_LEVEL设置为TYPICAL或者ALL(注意:一定不能改为BASIC, 这也是本篇内容所要说的问题)。
在启动自动共享内存管理时,Oracle会在引入了一个新的后台进程MMAN(MEMORY MANAGER), 该进程会依据操作系统的内存管理信息,动态地实现ASMM, 这样就和统计信息参数statistics_level有关系了,当把此参数设置为TYPICAL或者ALL时,系统会自动不断的收集统计信息,提供给后台进程MMAN, MMAN进程依据这些信息来动态的调整内存组件大小,如果把statistics_level参数设置为BASIC, 那么Oracle只会收集很小一部分基本信息,如果数据库停掉的话,再次启动将不能正常启动了,可以看下如下实验:
此时,我们想要通过alter日志来分析不能启动的原因,这个就有点难度了,如果statistics_level是在比较早的时候修改的,在alter日志中记录也很靠前的,而此时在alter日志中也没有记录数据库启动时的信息,因为数据库还没有启动到nomount, 没有记录任何相关数据库启动的信息。
要解决此问题,我们可以尝试一步步来启动数据库,先启动到nomount, 用spfile启动不了,就选择pfile来启动,重新生成spfile文件。然后再启动到mount状态,再去打开数据库。这就需要我们做DBA的注意了,一定记着备份,不管是数据文件、控制文件、参数文件、归档日志等等,一定记得多备份一份出来。
其实此问题在OCP考题中也出现过,不过考察的不是10g的sga_target,而是11g的memory_garget(自动内存管理),其实质都是一样的,可以看下下面一题:
通过我上面的分析,不难得出,此题答案应该选择B. 也就是说statistics_level的设置与memory_garget(11g中的自动内存管理)之间是有关系的,当statistics_level设置为typical或者all时,memory_garget可以设置为非0值,使用自动内存管理。如果statistics_level设置为basic, memory_garget就不能设置为非0值了,也就不能使用自动内存管理了的!