在Oracle 9i以前,SGA一直是静态分配内存的,其大小事根据init.ora参数文件相关的值相加得到的,一旦分配完成以后就不能动态的修改,要修改只有修改参数文件重启实例。SGA分配的内存空间可以被所有的Oracle进程所共享。
一. Oracle 8i静态管理SGA
在Oracle 8i中需要修改SGA参数,必须修改参数文件,重启数据库之后,修改才能生效。参数文件中的相关参数为:db_block_buffers shared_pool_size large_pool_size java_pool_size log_buffer。这些参数的设置受物理内存的限制,在设置的时候需要全面考虑。
二. Oracle 9i动态管理SGA
从Oracle 9i开始,Oracle推出了SGA动态调整,意味着我们可以不通过重启实例使得SGA的修改立即生效。
在Oracle 9i中通过设置参数sga_max_size,该参数用于控制各缓冲池使用的内存总和,本质上在进程中预先分配一段虚拟地址备用,二部分配物理内存,目的是防止和进程是有地址段的冲突。可以通过show parameter sga_max_size命令查看当前的设置。在设置了改参数之后,可以通过命令alter system set 参数名=值 scope=memory完成参数的修改并使其立即生效。只要总的SGA内存设置不超过sga_max_size的设置即可(在Oracle 9iR1中,动态减小内存设置可能会触发一些bug,在繁忙的生产系统中应当慎重使用)。
当然在动态修改这些参数的时候还有如下限制:
1. 修改的内存大小必须是粒度大小的整数倍,否则会自动向上取整。
2. SGA总大小不能超出sga_max_size的值。
3. SGA最低配置为3个粒度,分别用于固定的SGA,缓冲区高速缓存,共享池。
伴随着动态SGA管理的新特性,Oracle推出了一系列内存设置建议,同时引入了一些动态性能视图,可以使用命令查看:select tname from tab where tname like '%ADVICE%';具体的特性研究大家可以自己做实验深入的了解。虽然Oracle 9i中,Oracle提供了动态修改内存的功能,但是仍建议在系统规划的时候做好设置,尽量避免在运行时动态的修改,动态的调整某些系统参数肯能会触发系统bug,从而导致oracle挂起。
三. Oracle 10g自动共享内存管理
Oracle 9i的动态SGA调整新特性虽然方便,但是仍然需要DBA去观察并修改这些设置。而Oracle 10g的自动共享内存管理(Automatic Shared Memory Management,ASSM)解放了这部分的工作。Oracle会根据当前数据库运行的任务特性自动调整SGA的分配以达到最佳性能的目的。如:在运行OLTP任务时,buffer cache会获取大部分内存以达到良好的I/O性能。当系统运行DSS批处理任务时,内存会自动转移给large pool,以便并行查询等可以获得更多的内存,更快的执行。
Oracle 10g通过初始化参数sga_target设置Oracle自动管理SGA中以下大多数的内存分配。sga_target可以动态修改,但是不能超出sga_max_size参数限制。可自动分配的内存包括:db_block_buffers shared_pool_size large_pool_size java_pool_size。而非标准block_size的cache,keep/recycle,buffer cache,redo_log cache,streem pool则还是需要手工配置
启用自动共享内存管理,需要设置sga_target为非0值,不能超出sga_max_size大小,并且statistics_level参数设置为typical或者all。
自动共享内存管理引入了一个新的后台进程MMAN(memory manager)此进程依据不间断的手机内存建议来动态调整内存组件。通过查询视图v$sga_dynamic_components可以查看到各动态组件调整的时间和类型等信息。