ORACLE内存调整的真相

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

我画个图让大家清楚认识下内存分配法

ORACLE内存调整的真相

第一个问题

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的块。

ORACLE内存调整的真相

这里DB_CACHE_SIZE 不是指整个数据缓存区,而是默认缓存区,并且是默认块的缓冲区。其他KEEP RECYCLE DB_NK_CACHE_SIZE 直接从SGA分配内存

select * from V$sga_dynamic_components;

ORACLE内存调整的真相

从这个视图上看到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的时代了。

上一篇:MTK 添加与APK通信的property


下一篇:设计模式之策略+工厂(简化if判断)