ORACLE如何分配内存,如何调整内存这个问题,对于新手来说确实困难。其实这个事情很简单的而已,只不过思维会被混乱了。尤其是网文一大堆的情况下。很少人去耐心看官方文档,尤其是英文文档!
为什么会发生这样的情况呢? 小仙我认为主要是东西方思维方式不一样而已。西方人是从局部到整体,而我们东方人喜欢大观局,战略层面上看。是从上往下看而已。
ORACLE 数据库是从8I 开始到如今的12C,自然前面还有7,6,5,4,3,2,1。以前的不重要,目前中国市场上运行的数据库版本是8I,9I,10G,11G,12C。用得最多的是11G,10G。从10G开始ORACLE公司开始用户友好化了,尤其是DBA管理工作开始自动化,在内存方面可以SGA自动管理,PGA也自动管理了。不用像9I那样,人工分配SGA里面的 SHARD_POOL,DATA_BUFFER,LOG_BUFFER等各种池的大小。
到了11G 来个MEMORY_TARGET 整个内存一起管理了。这样就方便ORACLE的使用,让ORACLE数据库得到更多的用户,尤其是开发人员来说,安装和使用特方便了。
12C 完善了MEMORY_TARGE 整个内存分配工作,完全交给ORACLE自己打理了。只要告诉它该占多少系统内存就行了。
是不是很爽啊??
对开发人员来说自然是,对DBA来说,要进步深入就难了,需要钻研下去。因为默认的并不很好!
第一 我们从12C 往回说
show parameter target
memory_max_target big integer 800M
memory_target big integer 800M
pga_aggregate_target big integer 0
sga_target big integer 0
show parameter max_size
sga_max_size big integer 800M
SQL> show parameter pga
NAME TYPE VALUE
pga_aggregate_limit big integer 2G
pga_aggregate_target big integer 0
我画个图让大家清楚认识下内存分配法
第一个问题
memory_max_target
memory_target
这两个参数 设定ORACLE使用整个内存多少? 比如说32G物理内存,ORACLE使用800MB内存。
一般来说 使用80%。内存大的话比如256GB 可以达到90%。如果你上面还跑OEM,建议就降低些70%。
第二 MEMROY 管制
PGA和SGA 也就是说PGA+SGA不能超过MEMORY设定的大小。
PGA和SGA之间如何分配?
如果是OLTP 那么SGA多占些
如果是DSS 也就是统计类型比较多 PGA就多占些 OLAP,OLHP。
第三个问题 MAX_TARGET 和 TARGET 的区别
memory_max_target
memory_target
sga_target
sga_max_size
MAX_SIZE 说明该参数最大上限,TARGET实际分配内存的目标值。自然目标值是不可以大于最大上限值的。
第四问题 PGA 是后来加强管控的。
LIMIT和TARGET 跟第三个是一个道理的。
pga_aggregate_limit big integer 2G
pga_aggregate_target big integer 0
因此PGA_AGGREATE_limit+SGA_MAX_SIZE=MEMORY_MAX_TARGET
11G和10G PGA 不受控制,只受系统物理内存大小的限制。虽然有了PGA_AGGREGATE_TARGET 这个参数。它只是参考值,不起什么卵用的。在12C就得到了控制。
第五个问题 0值和非0值 也就是自动调整和手工调整的区别
0 值有时表示自动调整,有时表示非自动调整。
memory_max_target,memory_target 设置0值 就是放弃自动内存调整。
sga_target ,sga_max_size 设置0 表示接受自动调整。
困惑就在这里。什么AMM MMA? 复杂得很!我们不必纠结这些
类似下面的说法
1:sga_target和pga_aggregate_target已经设置大小
如果Oracle中 已经设置了参数sga_target和pga_aggregate_target,
则这两个参数将各自被分配为最小值最为它们的目标值。
Memory_Target =SGA_TARGET+PGA_AGGREGATE_TARGET ,大小和
memory_max_size一致。
2:sga_target 设置大小,pga_aggregate_target 没有设置大小
那么pga_aggregate_target初始化值=memory_target-sga_target
3:sga_target 没有设置大小,pga_aggregate_target 设置大小
那么sga_target初始化值=memory_target-pga_aggregate_target
4:sga_target 和pga_aggregate_target 都没有设置大小Oracle 11g
中对这种sga_target和pga_aggregate_target都没有设定大小的情况下,Oracle将对这两个值没有最小值和默认值。Oracle将根据数据库运行状况进行分配大小。
是不是很困惑啊? 我们不要让ORACLE默认设置,全自动管理,也不要退回手工分配和管理。采用我们中国人思维中庸之法。
就是把所有的0都改成有值。比如说 系统32GB内存
80%给ORACLE 那么 memory_max_size=32GB*0.8=25.6GB 约等于26GB
80%给SGA 26*0.8=21GB PGA=5GB
NAME TYPE VALUE
memory_max_target big integer 26GB
memory_target big integer 20GB
sga_target big integer 15GB
sga_max_size big integer 21GB
pga_aggregate_limit big integer 5G
pga_aggregate_target big integer 2G
这样设置就让ORACLE有个对各个内存有个基础值,又给ORACLE自动调整的空间,以及最高限制的值。其实我一般会设置TARGET跟MAX一样的值,不让PGA和SGA相互之间内存借用。
NAME TYPE VALUE
memory_max_target big integer 26GB
memory_target big integer 26GB
sga_target big integer 21GB
sga_max_size big integer 21GB
pga_aggregate_limit big integer 5G
pga_aggregate_target big integer 5G
同理SGA内部 共享池和数据缓存池 也可以设定个基础值,也就是最小值,
SGA由如下组成
SGA=SHARD_POOL_SIZE+DB_CACHE_SIZE+RESULT_CACHE_SIZE
+large pool+java pool+redo log buffer+streams_pool_size+db_Nk_cache_size
在这里SGA内部分配的话,我小仙一般设置个共享池和数据缓存的值
SHARD_POOL_SIZE 9GB
DB_CACHE_SIZE 9GB
java pool =50MB
剩余的3GB 让SGA自动去分配,共享池如果不够用会向剩余的池挤压索要内存。
这里LOG BUFFER 在11G是不可以设定值的,在10G可以人工设定值。
共享池内部组成
shared_pool_reserved_size big integer 9M
shared_pool_size big integer 0
result_cache_max_result integer 5
result_cache_max_size big integer 2M
result_cache_mode string MANUAL
在这里 我们设置 shared_pool_reserved_size=1GB,记住RESULT_CACHE是在共享池里面分配内存
数据缓存池
SQL> show parameter cache
NAME TYPE VALUE
db_16k_cache_size big integer 0
db_2k_cache_size big integer 0
db_32k_cache_size big integer 52M
db_4k_cache_size big integer 0
db_8k_cache_size big integer 0
db_cache_size big integer 0
db_keep_cache_size big integer 0
db_recycle_cache_size big integer 0
这里我们看到了好多CACHE,这在11G后开始使用的CACHE参数
10G以前是BUFFER
buffer_pool_keep string
buffer_pool_recycle string
db_block_buffers integer 0
log_buffer integer 2199552
请注意这是一组
db_cache_size big integer 0
db_keep_cache_size big integer 0
db_recycle_cache_size big integer 0
DB_CACHE_SIZE 是默认块的缓存区,一般是8K的块。
这里DB_CACHE_SIZE 不是指整个数据缓存区,而是默认缓存区,并且是默认块的缓冲区。其他KEEP RECYCLE DB_NK_CACHE_SIZE 直接从SGA分配内存
select * from V$sga_dynamic_components;
从这个视图上看到SGA可自动调节的内存组件。
也就是说上面KEEP RECYCLE DB_NK_CACHE_SIZE 分配内存的时候需要注意内存溢出
我用11G做的实验 设置了MEMORY_TARGET=MEMORY_MAX_TARTET=
memory_max_target big integer 352M
memory_target big integer 352M
SQL> alter system set db_keep_cache_size=50M scope=spfile;
系统已更改。
SQL> alter system set db_keep_cache_size=10M scope=spfile;
系统已更改。
SQL> alter system set db_recycle_cache_size=10M scope=spfile;
系统已更改。
SQL> alter system set db_32k_cache_size=10M scope=spfile;
系统已更改。
alter system set db_16k_cache_size=100m scope=spfile;
SQL> alter system set db_4k_cache_size=10M scope=spfile;
ORACLE 例程已经关闭。
SQL> startup nomount
ORA-00838: Specified value of MEMORY_TARGET is too small, needs to be at least 452M
我本来设置了SGA_MAX_SIZE=0,SGA_TARTGE=0 自己不断地自我调高。
看来11G 无法回到10G,9I的时代了。