oracle SGA的查询与调整

来源:互联网 发布:Js each 编辑:程序博客网 时间:2024/04/28 15:28

Oracle SGA主要由数据高整缓冲池(database buffer cache),共享池(sharedpool),日志池(redo log buffer),大池(large pool),java池(java pool)组成

 

共享池部分由库高速缓存、字典高速缓存及其他一些用户和服务器会话信息组成

 

共享池(Shared pool)

Shared pool的优化应该放在优先考虑,因为一个cache miss在shared pool中发生比在databuffer中发生导致的成本更高,由于dictionary数据一般比librarycache中的数据在内存中保存的时间长,所以关键是library cache的优化。

 

Gets:(parse)在namespace中查找对象的次数;

Pins:(execution)在namespace中读取或执行对象的次数;

Reloads:(reparse)在执行阶段library cache misses的次数,导致sql需要重新解析。

 

 

可通过查询v$shared_pool_advice视图获得关于shared pool的建议信息

SQL> select SHARED_POOL_SIZE_FOR_ESTIMATEspsfe,SHARED_POOL_SIZE_FACTORspsf,ESTD_LC_SIZE,ESTD_LC_MEMORY_OBJECTS elmo,ESTD_LC_TIME_SAVEDelts,ESTD_LC_TIME_SAVED_FACTOR eltsf,ESTD_LC_MEMORY_OBJECT_HITSemoh

from v$shared_pool_advice;

 

 

    SPSFE      SPSFESTD_LC_SIZE      ELMO      ELTS     ELTSF      EMOH

---------- ---------- ------------ ---------- ---------- --------------------

       48        .6                1066        83     .9881      5865

       56        .7          14      2180        84              5933

       64        .8          14      2180        84              5933

       72        .9          14      2180        84              5933

       80                  14      2180        84              5933

       88       1.1          14      2180        84              5933

       96       1.2          14      2180        84              5933

      104       1.3          14      2180        84              5933

      112       1.4          14      2180        84              5933

      120       1.5          14      2180        84              5933

      128       1.6          14      2180        84              5933

 

    SPSFE      SPSFESTD_LC_SIZE      ELMO      ELTS     ELTSF      EMOH

---------- ---------- ------------ ---------- ---------- --------------------

      136       1.7          14      2180        84              5933

      144       1.8          14      2180        84              5933

      152       1.9          14      2180        84              5933

      160                  14      2180        84              5933

 

Alter system set shared_pool_size=56 scope=spfile

 

 

库高速缓存(Library Cache)

库商速缓存中包含私用和共享SQL区和PL/SQL区。调整SGA的重要问题是确保库高速缓存足够大,以使ORACLE能在共享池中保持分析和执行语句,提高语句分析和执行效率,降低资源消耗。通过比较LibraryCache的命中率来决定它的大小。

 

1) 检查v$librarycache中sqlarea的gethitratio是否超过90%,如果未超过90%,应该检查应用代码,提高应用代码的效率。

 

SQL>select gethitratio from v$librarycache where namespace='SQLAREA';

 

2)v$librarycache中reloads/pins的比率应该小于1%,如果大于1%,应该增加参数shared_pool_size的值。

 

select sum(pins),sum(reloads),sum(reloads)/sum(pins) hits fromv$librarycache;

 

reloads/pins>1%有两种可能,一种是library cache空间不足,一种是sql中引用的对象不合法。

 

select (sum(pins - reloads)) / sum(pins) "LIB CACHE" fromv$librarycache;

 

library cache hit ratio > 85%

 

library cache空间不足,增大share_pool_size(10g)

SQL>alter system set share_pool_size=’’spoce=memory/spfile/both

 

3)shared pool reserved size一般是shared poolsize的10%,不能超过50%。V$shared_pool_reserved中的requestmisses=0或没有持续增长,或者free_memory大于shared pool reservedsize的50%,表明shared pool reserved size过大,可以压缩。

 

4)将大的匿名pl/sql代码块转换成小的匿名pl/sql代码块调用存储过程。

 

5)从9i开始,可以将execution plan与sql语句一起保存在librarycache中,方便进行性能诊断。从v$sql_plan中可以看到execution plans。

 

6)保留大的对象在sharedpool中。大的对象是造成内存碎片的主要原因,为了腾出空间许多小对象需要移出内存,从而影响了用户的性能。因此需要将一些常用的大的对象保留在sharedpool中,下列对象需要保留在shared pool中:

 

a.   经常使用的存储过程;

b.   经常操作的表上的已编译的触发器

c.   Sequence,因为Sequence移出shared pool后可能产生号码丢失。

 

查找没有保存在library cache中的大对象:

 

SQL>select * from v$db_object_cache where sharable_mem>10000and type in ('PACKAGE','PROCEDURE','FUNCTION','PACKAGE BODY') andkept='NO'

 

将这些对象保存在library cache中:

Execute dbms_shared_pool.keep(‘package_name’);

 

对应脚本:dbmspool.sql

 

7)查找是否存在过大的匿名pl/sql代码块。两种解决方案:

 

   A.转换成小的匿名块调用存储过程

   B.将其保留在shared pool中

 

查找是否存在过大的匿名pl/sql块:

select sql_text from v$sqlarea where command_type=47 andlength(sql_text)>500

 

调整数据字典高速缓存(Dictionary Cache)

数据字典高速缓存包括了有关数据库的结构、用户、实体信息等。数据字典的命中率对系统有很大的影响。命中率的计算中,getmisses表示失败次数,gets表示成功次数。

 

查询V$ROWCACHE表:

SQL> select (1-sum(getmisses)/(sum(gets)+sum(getmisses)))*100from v$rowcache;

or

select (sum(gets - getmisses - usage -fixed)) / sum(gets) "ROW CACHE" from v$rowcache;

 

dictionary cache hit ratio > 95%

 

如果该值>90%,说明命中率合适。否则,应增大共享池的大小。

 

避免出现Dictionarycache的misses,或者misses的数量保持稳定,只能通过调整shared_pool_size来间接调整dictionarycache的大小。

 

Percent misses应该很低:大部分应该低于2%,合计应该低于15%

select sum(getmisses)/sum(gets) from v$rowcache;

若超过15%,增加shared_pool_size的值。

 

 

调整数据库缓冲区高速缓存

Oracle在运行期间向数据库高速缓存读写数据,高速缓存命中表示信息已在内存中,高速缓存失败意味着ORACLE必需进行磁盘I/O。保持高速缓存失败率最小的关键是确保高速缓存的大小。初始化参数db_block_buffers控制数据库缓冲区高速缓存的大小。可通过查询V$SYSSTAT命中率,以确定是否应当增加db_block_buffers的值。

 

SQL> select name,value from v$sysstat where name in ('dbblockgets','consistent gets','physical reads');

or

= 1 - physical reads /logical reads = 1 - (physical reads / (dbblock gets + consistent gets))  select1-(a.value/(b.value+c.value)) from v$sysstat a,v$sysstat b,v$sysstat c where a.name='physical reads' and b.name='db blockgets' and c.name='consistent gets';

 

 

通过查询结果

  命中率=1-physical reads/( db block gets +consistent gets)

如果命中率<0.6~0.7,则应增大db_block_buffers。

 

1)granule大小的设置,db_cache_size以字节为单位定义了default buffer pool的大小。

 

如果SGA<128M,granule=4M,否则granule=16M,即需要调整sga的时候以granule为单位增加大小,并且sga的大小应该是granule的整数倍。

 

2) 根据v$db_cache_advice调整buffer cache的大小

 

selectsize_for_estimate,buffers_for_estimate,estd_physical_read_factor,estd_physical_reads

from v$db_cache_advice

where name='DEFAULT' AND advice_status='ON' AND block_size=

(select value from v$parameter where name ='db_block_size')

 

estd_physical_read_factor<=1

 

3) 统计buffer cache的cache hit ratio>90%,如果低于90%,可以用下列方案解决:

 

增加buffer cache的值;

使用多个buffer pool;

Cache table;

 

为 sorting and parallel reads 建独立的buffer cache;

 

select name,value

from v$sysstat

where name in('session logical reads','physical reads','physicalreads direct','physical reads direct(lob)');

 

Cache hit ratio=1-(physical reads-physical reads direct-physicalreads direct (lob))/session logicalreads;  

select 1-(phy.value-dir.value-lob.value)/log.value

from v$sysstat log,v$sysstat phy,v$sysstat dir,v$sysstat lob

where log.name='session logical reads' and phy.name='physicalreads' and dir.name='physical reads direct' and lob.name='physicalreads direct(lob)';

 

影响cache hit ratio的因素:

 

全表扫描;应用设计;大表的随机访问;cache hits的不均衡分布

 

4)表空间使用自动空间管理,消除了自由空间列表的需求,可以减少数据库的竞争

 

 

3、其他SGA对象

redo log buffer

对应的参数是log_buffer,缺省值与 OS相关,一般是500K。检查v$session_wait中是否存在log bufferwait,v$sysstat中是否存在redo buffer allocation retries

 

A、检查是否存在log buffer wait:

 

select * from v$session_wait where event='log buffer wait';

 

如果出现等待,一是可以增加log buffer的大小,也可以通过将log 文件移到访问速度更快的磁盘来解决。

 

B、select name,value from v$sysstat where name in('redo bufferallocation retries','redo entries');

 

Redo buffer allocation retries接近0,小于redo entries的1%,如果一直在增长,表明进程已经不得不等待redo buffer的空间。如果Redo buffer allocationretries过大,增加log_buffer的值。

 

C、检查日志文件上是否存在磁盘IO竞争现象

 

select event,total_waits,time_waited,average_wait fromv$system_event where event like 'log file switch completion%';

 

如果存在竞争,可以考虑将log文件转移到独立的、更快的存储设备上或增大log文件。

 

D、检查点的设置是否合理

检查alert.log文件中,是否存在‘checkpoint not complete’;

 

select event,total_waits,time_waited,average_wait fromv$system_event where event like 'log file switch%';

如果存在等待,调整log_checkpoint_interval、log_checkpoint_timeout的设置。

E、检查log archiver的工作

 

select event,total_waits,time_waited,average_wait fromv$system_event where event like ‘log file switch (arch%’;

 

如果存在等待,检查保存归档日志的存储设备是否已满,增加日志文件组,调整log_archive_max_processes。

 

 

F、DB_block_checksum=true,因此增加了性能负担。(为了保证数据的一致性,oracle的写数据的时候加一个checksum在block上,在读数据的时候对checksum进行验证)

 

 

在设置日志缓冲区时,可以参考下面这个建议的公式来计算:1.5×(平均每个事务所产生的重做记录大小×每秒提交的事务数量)。

 

首先先找到总事务量是多少:

select a.value as trancount 
from v$sysstat a,v$statname b
where a.statistic# = b.statistic# and b.name = 'user commits';

然后,找到系统总共的运行时间: 
select trunc(sysdate - startup_time)*24*60*60 as seconds fromv$instance;

 

第三,找到所产生的所有重做记录大小:

select value as redoblocks from v$sysstat where name = 'redo blockswritten';

 

最后,我们可以分别计算公式中的值:平均每个事务所产生的重做记录大小=redoblocks/trancount;每秒提交的事务数量=trancount/seconds。这样,最后所建议的日志缓冲区的大小可以写为: 
1.5* (redoblocks/trancount)* (trancount/seconds)

 

java pool

 

对于大的应用,java_pool_size应>=50M,对于一般的java存储过程,缺省的20M已经够用了。

 

检查是否需要调整DBWn  (按CPU的个数来调整db_writer_processes)

 

select total_waits from v$system_event where event=’free bufferwaits’;

0 0
原创粉丝点击