SGA概念
SGA(System Global Area 系统全局区域)是一组包含一个Oracle实例的数据和控制信息的共享内存结构。这句话可以说是SGA的定义。虽然简单,但其中阐述了SGA几个很重要的特性:
1、SGA的构成——数据和控制信息
2、SGA是共享的,即当有多个用户同时登录了这个实例,SGA中的信息可以被它们同时访问(当涉及到互斥的问题时,由latch和enquence控制);
3、一个SGA只服务于一个实例,也就是说,当一台机器上有多个实例运行时,每个实例都有一个自己的SGA,尽管SGA来自于OS的共享内存区,但实例之间不能相互访问对方的SGA区。
Oracle进程和一个SGA就构成了一个Oracle实例。当实例启动时,Oracle会自动从系统中分配内存给SGA,而实例关闭时,操作系统会回收这些内存。
SGA包含的组件
SGA包含的组件有:
数据缓冲(Buffer Cache)
重做日志缓冲(Redo Log Buffer)
共享池(Shared Pool)
Java池(Java Pool)
大池(Large Pool)
流池(Streams Pool --- 10g以后才有)
数据字典缓存(Data Dictionary Cache)
其他信息(如数据库和实例的状态信息)
在启动oracle的时候,会显示以下信息
SQL> startupORACLE instance started. Total System Global Area 289406976 bytesFixed Size 1248576 bytesVariable Size 117441216 bytesDatabase Buffers 163577856 bytesRedo Buffers 7139328 bytesDatabase mounted.Database opened.我曾经纠结于fixed size, variable size 到底都是什么,后来综合各方面信息,得出以下结论
fixed size : 不必太关心,是oracle自己控制的,我们无法做出太多控制,具体包含了什么,说不清楚。。。。。。。。。
virable size: 受java pool , share pool , large pool 等等的影响,但还包括其它的一些东西。比如每一个control file都会在virable size这部分占据一定的空间。
当然,上面的信息并不是只有在数据库启动时才看的到,通过下面的命令一样可以得到:
SQL> show sgaTotal System Global Area 1068937216 bytesFixed Size 2166536 bytesVariable Size 675283192 bytesDatabase Buffers 377487360 bytesRedo Buffers 14000128 bytesSQL> select * from v$sga;NAME VALUE-------------------- ----------Fixed Size 2166536Variable Size 675283192Database Buffers 377487360Redo Buffers 14000128关于SGA的几个参数
MEMORY_TARGET
这个参数是oracle 11g中用来实现SGA,PGA自动管理的。设置了之后,MEMORY_TARGET代表了SGA,PGA一共可以分配的大小,而具体每个组件的大小则要oracle自己调配。
MEMORY_MAX_TARGET
这个参数是MEMORY_TARGET的一共阀值。MEMORY_TARGET的值是可以动态调整的,但是不可以超过这个值。修改这个值需要重启数据库。
SGA_TARGET
这个参数设置后会实现自动SGA管理。但是要注意的是,如果MEMORY_TARGET的值也设置了,那么这个参数的作用就是ORACLE SGA的最小值。
SGA_MAX_TARGET
该参数是SGA_TARGET的阀值(错误,不存在这个参数其实,实际上应该是SGA_MAX_SIZE)
SGA_MAX_SIZE
手动SGA管理的时候,这个参数控制着动态调整SGA的时候最多可以给SGA多大内存。
PRE_PAGE_SGA
在oracle启动的时候,只会给各个组件非配最小的,必须的物理内存,其他的内存则作为虚拟内存非配。只有当进程需要这些内存的时候,才会把他们touch到物理内存中。通过这个参数可以在oracle启动的时候指定所有的SGA都作为物理内存非配。但是这样启动会慢些,因为启动的时候需要把所有的page都touch到物理内存中。
LOCK_SGA
使用了PRE_PAGE_SGA这个参数,把所有的SGA都touch进内存后,并不能保证这些内存page就不会被交换到虚拟内存中,这时需要LOCK_SGA这个参数把这些page lock在物理内存中。但是有些操作系统不支持内存锁定,所以这个参数就不好使。
关于SGA的重要视图
V$SGASTAT
这个视图结构如下:
SQL> desc v$sgastat Name Null? Type ----------------------------------------- -------- ---------------------------- POOL VARCHAR2(12) NAME VARCHAR2(26) BYTES NUMBERname是内存区域的名字,pool是该内存区域属于哪个pool,bytes是该内存区域的大小
例如:
POOL NAME BYTES------------ -------------------------- ----------streams pool msgtree_kgqmctx 64streams pool free memory 4197856streams pool time manager index 64streams pool KGH: NO ACCESS 4177952streams pool的 msgtree_kgqmctx内存区域大小为64.
streams pool的 free_memory内存区域大小为41978
通过下面的查询可以查出 shared pool的使用率
SQL> select s.bytes/p.value*100 from v$sgastat s, v$parameter p where s.pool='shared pool' and s.name = 'free memory' and p.name='shared_pool_size';S.BYTES/P.VALUE*100------------------- 43.7007828V$SGA_DYNAMIC_COMPONENTS
该视图记录SGA各个动态内存区的情况,记录已经完成的,对SGA动态内存区大小的调整
SQL> desc V$SGA_DYNAMIC_COMPONENTS Name Null? Type ----------------- -------- ------------ COMPONENT VARCHAR2(64) CURRENT_SIZE NUMBER MIN_SIZE NUMBER MAX_SIZE NUMBER USER_SPECIFIED_SI NUMBER ZE OPER_COUNT NUMBER LAST_OPER_TYPE VARCHAR2(13) LAST_OPER_MODE VARCHAR2(9) LAST_OPER_TIME DATE GRANULE_SIZE NUMBERCOMPONENT 内存区的名字
CURRENT_SIZE 当前大小
MIN_SIZE 实力启动后的最小值
MAX_SIZE 实例启动后的最大值
USER_SPECIFIED_S IZE用户在手动管理中指定的大小
OPER_COUNT 实力启动后调整的次数
LAST_OPER_TYPE 是增加还是减少
LAST_OPER_MODE 是auto还是manual
GRANULE_SIZE 粒度
这个视图和V$SGASTAT 有什么区别呢?
1. v$sgastat 的目的是记录SGA中各个内存区的大小,而不是变化,所以他列举的非常细,比如shared pool中的各个内存区都列出来
2. oracle内存调整是以各个池为对象调整,比如shard pool 中sql区需要多少内存,那么就给shared pool增加多少内存
总结
sga 包括
SQL> show sgaTotal System Global Area 1068937216 bytesFixed Size 2166536 bytesVariable Size 675283192 bytesDatabase Buffers 377487360 bytesRedo Buffers 14000128 bytes通过池划分包括 SQL> select distinct(component) from v$sga_dynamic_components order by component;COMPONENT--------------------------------------------------ASM Buffer CacheDEFAULT 16K buffer cacheDEFAULT 2K buffer cacheDEFAULT 32K buffer cacheDEFAULT 4K buffer cacheDEFAULT 8K buffer cacheDEFAULT buffer cacheKEEP buffer cacheRECYCLE buffer cacheShared IO Pooljava poollarge poolshared poolstreams pool14 rows selected.SQL>
不过这里不包括 redo buffer的信息,不知道是因为redo buffer 没有调整过还是就是不包括
另外v$sgastat也不包括redo和data buffer的信息
SQL> select distinct(pool) from v$sgastat;POOL------------java poolstreams poolshared poollarge pool