一直都想总结一下oracle内存调整方面的知识,最近正好优化一个数据库内存参数,查找一些资料而且google不少下。如今记录下来,作下备份。php
1、概述:
oracle 的内存能够按照共享和私有的角度分为系统全局区和进程全局区,也就是 SGA和 PGA(process global area or private global area)。对于 SGA 区域内的内存来讲,是共享的全局的,在 UNIX 上,必须为 oracle 设置共享内存段(能够是一个或者多个),由于 oracle 在UNIX 上是多进程;而在
WINDOWS 上 oracle 是单进程(多个线程),因此不用设置共享内存段。PGA 是属于进程(线程)私有的区域。在 oracle 使用共享
服务器模式下(MTS),PGA中的一部分,也就是 UGA 会被放入共享内存 large_pool_size 中。
发张图oracle内存架构组成,按照图上面的显示能够一目了然关键的参数和参数名称:
对于 SGA 部分,咱们经过 sqlplus 中查询能够看到:
SQL> select * from v$sga;
NAME VALUE
---------- --------------------
Fixed Size 454032
Variable Size 109051904
Database Buffers 385875968
Redo Buffers 667648
Fixed Size:
oracle 的不一样平台和不一样版本下可能不同,但对于肯定环境是一个固定的值,里面存储了 SGA 各部分组件的信息,能够看做引导创建 SGA 的区域。
Variable Size :
包含了 shared_pool_size、java_pool_size、large_pool_size 等内存设置
Database Buffers :
指数 据缓 冲区:
在 8i 中包 含 db_block_buffer*db_block_size、buffer_pool_keep、buffer_pool_recycle 三 部 份内 存 。
在 9i 中 包 含 db_cache_size 、db_keep_cache_size、db_recycle_cache_size、db_nk_cache_size。
Redo Buffers :
指日志缓冲区,log_buffer。在这里要额外说明一点的是,对于 v$parameter、v$sgastat、v$sga 查询值可能不同。v$parameter 里面的值,是指用户在初
始化参数文件里面设置的值,v$sgastat 是 oracle 实际分配的日志缓冲区大小(由于缓冲区的分配值其实是离散的,也不是以 block 为最小单位进行分配的),
v$sga 里面查询的值,是在 oracle 分配了日志缓冲区后,为了保护日志缓冲区,设置了一些保护页,一般咱们会发现保护页大小大约是 11k(不一样环境可能不同)。
2、SGA内参数及设置:
2.1 Log_buffer
对于日志缓冲区的大小设置,一般我以为没有过多的建议,由于参考 LGWR 写的触发条件以后,咱们会发现一般超过 3M 意义不是很大。做为一个正式系统,
可能考虑先设置这部分为 log_buffer=3—5M 大小,而后针对具体状况再调整。
log_buffer是Redo log的buffer。
所以在这里必需要了解Redo Log的触发事件(LGWR)
一、当redo log buffer的容量达到1/3
二、设定的写redo log时间间隔到达,通常为3秒钟。
三、redo log buffer中重作日志容量到达1M
一、log_buffer中的内容满1/3,缓存刷新一次。
三、log_buffer中的数据到达1M,缓存刷新一次。
2.2 Large_pool_size
对于大缓冲池的设置,假如不使用 MTS,建议在 20—30M 足够了。这部分主要用来保存并行查询时候的一些信息,还有就是 RMAN 在备份的时候可能会使用到。
若是设置了MTS,则因为 UGA 部分要移入这里,则须要具体根据
server process 数量和相关会话内存参数的设置来综合考虑这部分大小的设置。
2.3 Java_pool_size
假如数据库没有使用
JAVA,咱们一般认为保留 10—20M 大小足够。事实上能够更少,甚至最少只须要 32k,但具体跟
安装数据库的时候的组件相关(好比 http server)。
2.4 Shared_pool_size
Shared_pool_size
的开销一般应该维持在
300M 之内。除非系统使用了大量的存储过程、函数、包,
好比 oracle erp 这样的应用,
可
能会达到 500M 甚至更高。
因而咱们假定一个 1G 内存的系统,可能考虑
设置该参数为 100M,
2G 的系统考虑设置为 150M,8G 的
系统能够考虑设置为 200—300M
2.5SGA_MAX_SIZE
SGA区包括了各类缓冲区和内存池,而大部分均可以经过特定的参数来指定他们的大小。可是,做为一个昂贵的资源,一个系统的物理内存大小是有限。
尽管对于CPU的内存寻址来讲,是无需关系实际的物理内存大小的(关于这一点,后面会作详细的介绍),可是过多的使用虚拟内存致使page in/out,
会大大影响系统的性能,甚至可能会致使系统crash。因此须要有一个参数来控制SGA使用虚拟内存的最大大小,这个参数就是SGA_MAX_SIZE。当实例启动后,
各个内存区只分配实例所须要的最小大小,在随后的运行过程当中,再根据须要扩展他们的大小,而他们的总和大小受到了SGA_MAX_SIZE的限制。
对于OLTP系统,参考:
系统内存html |
SGA_MAX_SIZE值java |
1Gweb |
400-500Msql |
2G数据库 |
1Gwindows |
4G缓存 |
2500M服务器 |
8G架构 |
5G |
2.6 PRE_PAGE_SGA
oracle实例启动时,会只载入各个内存区最小的大小。而其余SGA内存只做为虚拟内存分配,
只有当进程touch到相应的页时,才会置换到物理内存中。
但咱们也许但愿实例一启动后,全部SGA
都分配到物理内存。这时就能够经过设置PRE_PAGE_SGA参数来达到目的了。这个参数的默认值
为FALSE,
即不将所有SGA置入物理内存中。当设置为TRUE时,实例启动会将所有SGA置入物理
内存中。它可使实例启动达到它的最大性能状态,可是,
启动时间也会更长(由于为了使全部SGA
都置入物理内存中,oracle进程须要touch全部的SGA页)。
2.7 LOCK_SGA
为了保证SGA都被锁定在物理内存中,而没必要页入/页出,能够经过参数LOCK_SGA来控制。
这个参数默认值为FALSE,当指定为TRUE时,
能够将所有SGA都锁定在物理内存中。固然,
有些系统不支持内存锁定,这个参数也就无效了。
2.8 SGA_TARGET
这里要介绍的时Oracle10g中引入的一个很是重要的参数。在10g以前,SGA的各个内存区
的大小都须要经过各自的参数指定,
而且都没法超过参数指定大小的值,
尽管他们之和可能并
没有达到SGA的最大限制。此外,一旦分配后,各个区的内存只能给本区使用,
相互之间是不能共享的。
拿SGA中两个最重要的
内存区Buffer Cache
和Shared Pool来讲,它们两个对实例的性能影响最大,
可是就有这样的
矛盾存在:在内存资源有限的状况下,某些时候数据被cache的需求很是大,
为了提升buffer hit,
就须要增长Buffer Cache,但因为SGA有限,
只能从其余区“抢”过来——如缩小Shared Pool,
增长Buffer Cache;而有时又有大块的PLSQL代码被解析驻入内存中,
致使Shared Pool不足,
甚至出现4031错误,
又须要扩大Shared Pool,这时可能又须要人为干预,从Buffer Cache中将内存夺回来。
有了这个新的特性后,SGA中的这种内存矛盾就迎刃而解了。这一特性被称为自动共享内存管理
(Automatic Shared Memory Management ASMM)。
而控制这一特性的,
也就仅仅是这一个参数SGA_TARGE。
设置这个参数后,你就不须要为每一个内存区来指定大小了。SGA_TARGET指定了SGA可使用
的最大内存大小,
而SGA中各个内存的
大小由Oracle自行控制,不须要人为指定。Oracle能够随时调节各个区域的大小,
使之达到系
统性能最佳状态的个
最合理大小,而且控制他们之和在SGA_TARGET指定的
值以内。
一旦给SGA_TARGET指定值后
(默认为0,即没有启动ASMM),就自动启动了ASMM特性。
3、oracle 内存调优办法
当项目的生产环境出现性能问题,咱们如何经过判断那些参数须要调整呢?
3.1 检查ORACLE实例的Library Cache命中率:
标准:通常是大于99%
检查方式:select 1-(sum(reloads)/sum(pins)) "Library cache Hit Ratio" from v$librarycache;
处理措施:
若是Library cache Hit Ratio的值低于99%,应调高shared_pool_size的大小。经过sqlplus链接数据库执行以下命令,调整shared_pool_size的大小:
SQL>alter system flush shared_pool;
SQL>alter system set shared_pool_size=设定值 scope=spfile;
3.2 检查ORACLE实例的Data Buffer(数据缓冲区)命中率:
标准:通常是大于90%
检查方式:
select 1 - (phy.value / (cur.value + con.value)) "HIT RATIO"
from v$sysstat cur, v$sysstat con, v$sysstat phy
where cur.name = 'db block gets'
and con.name = 'consistent gets'
and phy.name = 'physical reads';
处理措施:
若是HIT RATIO的值低于90%,应调高db_cache_size的大小。经过sqlplus链接数据库执行以下命令,
调整db_cache_size的大小
SQL>alter system set db_cache_size=设定值 scope=spfile
3.3 检查ORACLE实例的Dictionary Cache命中率:
select 1 - (sum(getmisses) / sum(gets)) "Data Dictionary Hit Ratio"
若是Data Dictionary Hit Ratio的值低于95%,应调高shared_pool_size的大小。经过sqlplus链接数据库执行以下命令,调整shared_pool_size的大小:
SQL>alter system flush shared_pool;
SQL>alter system set shared_pool_size=设定值 scope=spfile;
3.4 检查ORACLE实例的Log Buffer命中率:
select (req.value * 5000) / entries.value "Ratio"
from v$sysstat req, v$sysstat entries
where req.name = 'redo log space requests'
and entries.name = 'redo entries';
若是Ratio高于1%,应调高log_buffer的大小。经过sqlplus链接数据库执行以下命令,调整log_buffer的大小:
SQL>alter system set log_buffer=设定值 scope=spfile;
3.5 检查undo_retention:
标准:undo_retention 的值必须大于max(maxquerylen)的值
col undo_retention format a30
select value "undo_retention" from v$parameter where name='undo_retention';
select max(maxquerylen) From v$undostat Where begin_time>sysdate-(1/4);
若是不知足要求,须要调高undo_retention 的值。经过sqlplus 链接数据库执行以下命
SQL>alter system set undo_retention= 设定值 scope=spfile;
注:
32bit 和 64bit 的问题
对于 oracle 来讲,存在着 32bit 与 64bit 的问题。这个问题影响到的主要是 SGA 的大小。在 32bit 的数据库下,一般 oracle 只能使用不超过 1.7G 的内存,即便咱们拥有 12G 的内存,可是咱们却只能使用 1.7G,这是一个莫大的遗憾。假如咱们安装 64bit 的数据库,咱们就可使用很大的内存,咱们几乎不可能达到上限。可是 64bit 的数据库必须安装在 64bit 的操做系统上,惋惜目前 windows 上只能安装 32bit 的数据库,咱们经过下面的方式能够查看数据库是 32bit 仍是 64bit
可是在特定的操做系统下,可能提供了必定的手段,使得咱们可使用超过 1.7G 的内存,达到 2G 以上甚至更多。