oracle实例的内存(SGA和PGA)调整,优化之原理和方法 您所在的位置:网站首页 sga包含的内存结构有哪些 oracle实例的内存(SGA和PGA)调整,优化之原理和方法

oracle实例的内存(SGA和PGA)调整,优化之原理和方法

2024-07-15 16:57| 来源: 网络整理| 查看: 265

一、SGA与PGA的结构:

SGA 查看SGA: Sqlp> show sga 或 select * from v$sga; Total System Global Area  289406976 bytes Fixed Size                  1248600 bytes Variable Size             176161448 bytes Database Buffers          109051904 bytes Redo Buffers                2945024 bytes

Fixed Size:包括了数据库与实例的控制信息、状态信息、字典信息等,启动时就被固定在SGA中,不会改变。 Variable Size:包括了shard pool、large pool、java pool、stream pool、游标区和其他结构 Database Buffers:数据库中数据块缓冲的地方,是SGA中最大的地方,决定数据库性能 Redo Buffers:提供REDO缓冲的地方,在OLAP中不需要太大

V$sgastat记录了SGA的一些统计信息 V$sga_dynamic_components 保存SGA中可以手动调整的区域的一些调整记录

Shard pool: Shard_pool_size决定其大小,10g以后 自动管理 Shard_pool中数据字典和控制区结构用户无法直接控制,与用户有关的只有sql缓冲区(library cache)。 将 经常访问的过程或包用DBMS_SHARED_POOL.KEEP存储过程将该包pin在共享池中。 手工清除共享池的内容:alter system flush shard_pool;

共享池相关的几个常用的视图: V$sqlarea 记录了所有sql的统计信息,包括执行次数、物理读、逻辑读、耗费时间等 V$sqltext_with_newline 完全显示sql语句,通过hash_value来标示语句,piece排序 V$sql_plan保存了sql的执行计划,通过工具查看 V$shared_pool_advice 对共享池的预测,可以做调整SGA的参考 SGA:System Global Area是Oracle Instance的基本组成部分,在实例启动时分配;      系统全局域SGA主要由三部分构成:共享池、数据缓冲区、日志缓冲区。

(1)共享池:Shared Pool用于缓存最近被执行的SQL语句和最近被使用的数据定义,         主要包括:Library cache(共享SQL区)和Data dictionary cache(数据          字典缓冲区).共享SQL区是存放用户SQL命令的区域,数据字典缓冲区存          放数据库运行的动态信息.不管Oracle是32 bit 还是 64 bit 的,假定应用存在没有很好的使用绑定变量的情况,也不能设置 shared_pool_size 过大,通常应该控制在100M--200M,除非是 ORACLE ERP 一类的使用了很多存储过程函数、包 ,这样的很大的系统,可以考虑增大shared_pool_size,但是如果超过500M可能是危险的,达到1G几乎就会造成CPU的严重负担,系统甚至瘫痪。所以shared_pool_size 如果超过200M还命中率不高,那么应该从应用上找原因而不是一味的增加内存,shared_pool_size 过大主要增加了管理负担和latch 的开销。   (2) 缓冲区高速缓存:Database Buffer Cache用于缓存从数据文件中检索出来的数据  块,可以大大提高查询和更新数据的性能,通常可以尽可能的大。 Oracle把从data buffer中获得的数据库叫cache hit,把从磁盘获得的脚cache miss 数据缓冲 区中的数据块通过脏列表(dirty list)和LRU列表(LRU list)来管理。  Data buffer可细分为:default pool、keep pool、recycle pool对应的参数为db_cache_size、 db_keep_cache_size 、db_recycle_size分别表示缓冲区大小  从9i开始oracle支持不同块大小的 表空间,相应的可以为不同块大小的表空间指定不同块大小的数据缓冲区,不同块大小的数据缓冲区可以用相应的db_nk_cache_size来指定,其中 n可以是2、4、6、16或32  V$db_cache_advice 对数据缓冲区的预测,可以做调整data buffer的参考  V$bh、 x$bh记录了数据块在data buffer中缓冲的情况,通过这个视图可以找系统中的热点块。通过下面语句找系统中top 10 热点快所在的热点对象:

Select /*+ rule*/ owner,object_name from dba_objects Where data_object_id in (select obj from (select obj from x$bh order by tch desc) Where rownumAlter system set pga_aggregate_target=1000m scope=both;     从9i开始,sga_max_size参数设置SGA 的内存大小,不能动态修改 从10g开始,指定了sga_target参数后,所有的SGA组件如:shared pool、 data buffer、 large pool都不用手工指定了,Oracle会自动管理。这一特性就是自动共享内存管理ASMM。如果设置了sga_target=0,就自动关闭自动共享内 存管理功能。Sga_target大小不能超过sga_max_size的大小。    在Oracle 10g中引入了自动SGA内存管理特性,DBA可以设定SGA_TARGET告诉Oracle可用的SGA内存为多大,由Oracle根据系统负载来动态调整各组件大小,相应的数定会保存在控制文件中,使数据库重启后也记得各组件大小。

需要注意一下几点: 要使用自动SGA内存管理,STATISTICS_LEVEL参数必须设为TYPICAL或ALL,系统自动收集相应的信息用来动态调整SGA设定。

可以设定某个组件的值,Oracle SGA使用此值为该组件的最小大小 可动态调整的参数: DB_CACHE_SIZE,SHARED_POOL_SIZE,LARGE_POOL_SIZE,JAVA_POOL_SIZE。

需手动设置的参数: LOG_BUFFER,STREAMS_POOL,DB_NK_CACHE_SIZE,DB_KEEP_CACHE_SIZE,DB_RECYCLE_CACHE_SIZE。

手动管理SGA:

alter system set sga_max_size=1600M  scope=spfile;需重启数据库生效 Alter system set sga_target=2000m; Alter system set db_cache_size=1000m; Alter system set shared_pool=200m; Alter system set sga_target=0---------关闭自动共享内存管理ASMM

11G以后sga+pga整个内存可以自动管理AMM,相关 参数memory_max_target  memory_target.设置好这两个参数后就不用关心SGA和PGA了

Alter system set memory_target=3000m SCOPE=SPFILE; Alter system set memory_max_target=4000M SCOPE=SPFILE;   ALTER SYSTEM SET PGA_AGGREGATE_TARGET=0 SCOPE=SPFILE; ALTER SYSTEM SET SGA_TARGET=0 SCOPE=SPFILE; 11g手动内存管理: Alter system set memory_target=3000m; Alter system set sga_target=2000m; Alter system set pga_aggregate_target=1000m; Alter system set memory_target=0;---------关闭自动内存管理AMM

二、分析与调整:

1、系统全局域: SGA与操作系统、内存大小、cpu、同时登录的用户数有关。可占OS系统物理内存的1/2到1/3,当然,如果服务器上只有oracle的话,可以分配的更大一些,如果还有其他服务,如IIS等,那就要分的小一些。      1、共享池:   修改共享池的大小,ALTER SYSTEM SET SHARED_POOL_SIZE = 64M;   查看共享SQL区的使用率:  select(sum(pins-reloads))/sum(pins) "Library cache" from v$librarycache; 这个使用率应该在90%以上,否则需要增加共享池的大小。   查看数据字典缓冲区的使用率: select (sum(gets-getmisses-usage-fixed))/sum(gets) "Data dictionary cache" from v$rowcache; 这个使用率也应该在90%以上,否则需要增加共享池的大小。       2、缓冲区高速缓存:它的大小要根据数据量来决定,在OLTP系统中要求data buffer 的命中率在95%以上. SGA=((db_block_buffers * block size+shared_pool_size+large_pool_size+java_pool_size+log_buffers)+1MB 查看数据库数据缓冲区的使用情况:

 SELECT name,value FROM v$sysstat order by name WHERE name IN(''DB BLOCK GETS'',''CONSISTENT GETS'',''PHYSICAL READS'');   计算出来数据缓冲区的使用命中率=1-(physical reads/(db block gets+consistent gets)),这个命中率应该在90%以上,否则需要增加数据缓冲区的大小。 SQL>select sum(pins) "请求存取数",sum(reloads) "不命中数",sum(reloads)/sum(pins) from v$librarycache     其中,pins,显示在库高速缓存中执行的次数;reload,显示在执行阶段库高速缓存不命中的数目,一般 sum(reloads)/sum(pins)的值应接近于零.如果大于1%就应该增加shared_pool_size的值, 来提高数据字典高速缓存可用的内存数量,减少不命中数.   通过动态性能表v$rowcache来查询数据字典高速缓存的活动:   select sum(gets) "请求存取数",sum(getmisses) "不命中数" from v$rowcache;     其中,gets,显示请求相应项的总数; getmisses,显示造成高速缓存不命中的数据请求数.     Hit ratio与wait events: SQL>select value from $pgastat where name =''cache hit percentage'';  Hit ratio与wait events是此消彼涨,在执行类似于 SQL>select col1,col2,.. from tab1 a where exists (select 1 from tab2 where a.col3 = b.col3) where ....  的语句的时候,如果tab1的记录很多的话,你会发现系统的hit ratio会有很大的提高,wait events是否会改观呢.

   3、日志缓冲区   SELECT name, value  FROM v$sysstat WHERE name IN (''redo entries'',''redo log space requests'') 查看日志缓冲区的使用情况。 查询出的结果可以计算出日志缓冲区的申请失败率:       申请失败率=requests/entries,申请失败率应该接近于0,否则说明日志缓冲区开设太小,需要增加ORACLE数据库的日志缓冲区。

   4、大型池: 可以减轻共享池的负担;可以为备份、恢复等操作来使用;不使用LRU算法来管理 其大小由数据库的‘共享模式/db模式’如果是共享模式的话,要分配的大一些  指定Large Pool的大小, ALTER SYSTEM SET LARGE_POOL_SIZE=64M      5、Java池:   在安装和使用Java的情况下使用

三.如何估算PGA,SGA的大小,配置数据库服务器的内存 ORACLE给的建议是: 一个数据库服务器,分80%的内存给数据库,20%的内存给操作系统. OLTP系统  PGA=(Total Memory)*80%*20%。余下SGA。 DSS系统 PGA=(Total Memory)*80%*70%。 余下SGA。 混合系统 PGA=(Total Memory)*80%*50%。余下SGA。   PGA: SQL> select * from v$pgastat;  NAME                                                                  VALUE UNIT ---------------------------------------------------------------- ---------- ------------ aggregate PGA target parameter                                    104857600 bytes   -----这个值等于参数PGA_AGGREGATE_TARGET的值,如果此值为0,表示禁用了PGA自动管理。 aggregate PGA auto target                                          75220992 bytes       -----表示PGA还能提供多少内存给自动运行模式,通常这个值接近pga_aggregate_target-total pga inuse. global memory bound                                                20971520 bytes  -----工作区执行的最大值,如果这个值小于1M,马上增加PGA大小 total PGA inuse                                                    30167040 bytes  -----当前分配PGA的总大小,这个值有可能大于PGA,如果PGA设置太小.这个值接近 total PGA allocated                                                52124672 bytes  -----工作区花费的总大小 maximum PGA allocated                                              67066880 bytes total freeable PGA memory                                                 0 bytes         ----没有了空闲的PGA process count                                                            23                    ----当前一个有23个process max processes count                                                      25  PGA memory freed back to OS                                               0 bytes total PGA used for auto workareas                                   8891392 bytes maximum PGA used for auto workareas                                22263808 bytes total PGA used for manual workareas                                       0 bytes                  ---为0自动管理 maximum PGA used for manual workareas                                     0 bytes            ---为0自动管理 over allocation count                                                     0         如果PGA设置太小,导致PGA有时大于PGA_AGGREGATE_TARGET的值,此处为0,说明PGA没有扩展大于TARGET的值,如 果此值出现过,那么增加PGA大小。 bytes processed                                                   124434432 bytes extra bytes read/written                                                  0 bytes cache hit percentage                                                    100 percent  ---命中率为100%,如果太小增加PGA  recompute count (total)                                                6651  19 rows selected

SQL> select max(pga_used_mem)/1024/1024 M from v$process;   ----当前一个process消耗最大的内存  M ---------- 9.12815189  SQL> select min(pga_used_mem)/1024/1024 M from v$process where pga_used_mem>0; ---process消耗最少内存  M ---------- 0.19186878  SQL> select max(pga_used_mem)/1024/1024 M from v$process ;    ----process曾经消耗的最大内存  M ---------- 9.12815189  SQL> select sum(pga_used_mem)/1024/1024 from v$process;   ----当前process一共消耗的PGA  SUM(PGA_USED_MEM)/1024/1024 --------------------------- 28.8192501068115

如何设置PGA呢?我们可以在压力测试阶段,模拟一下系统的运行,然后运行  select (select sum(pga_used_mem)/1024/1024 from v$process) /(select count(*) from v$process) from dual; 得到一个process大约占用了多少的内存,然后估算系统一共会有多少连接,比如一共有500个连接,  如果processes=450,那么Sessions=1.1*process +5=500,,再乘以一个process需要消耗的内存,就能大约估算出PGA需要设置多大。  最好将PGA设置的值比计算出的值大一点,PGA值设定好后,就可以根据系统的性质,如果系统为OLTP,那么总的内存可以设置为 PGA/0.16,最后也能估算出SGA的大小

下面摘抄eygle的关于一个process能够分配的最大内存(串行操作)的规则:  10gR1之前,对于串行操作(非并行)一个process能够分配的最大的内存为 min(5%pga_aggregate_target,100m)  10gR2之后,对于串行操作(非并行)一个process能够分配的最大内存有如下规则:  如果pga_aggregate_target1%有两种可能,一种是library cache空间不足,一种是sql中引用的对象不合法。

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

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

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

6)保留大的对象在shared pool中。大的对象是造成内存碎片的主要原因,为了腾出空间许多小对象需要移出内存,从而影响了用户的性能。因此需要将一些常用的大的对象保留在shared pool中,下列对象需要保留在shared pool中: a. 经常使用的存储过程; b. 经常操作的表上的已编译的触发器 c. Sequence,因为Sequence移出shared pool后可能产生号码丢失。 查找没有保存在library cache中的大对象: Select * from v$db_object_cache where sharable_mem>10000 and type in ('PACKAGE','PROCEDURE','FUNCTION','PACKAGE BODY') and kept='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 and length(sql_text)>500;

8)Dictionary cache的 优化  避免出现Dictionary cache的misses,或者misses的数量保持稳定,只能通过调整shared_pool_size来间接调整dictionary cache的大小。 Percent misses应该很低:大部分应该低于2%,合计应该低于15% Select sum(getmisses)/sum(gets) from v$rowcache; 若超过15%,增加shared_pool_size的值。

2、Buffer Cache

1)granule大小的设置,db_cache_size以字节为单位定义了default buffer pool的大小。 如果SGA=50M,对于一般的java存储过程,缺省的20M已经够用了。

3)检查是否需要调整DBWn Select total_waits from v$system_event where event=’free buffer waits’;



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有