SGA即系统全局区域,是一组共享的内存结构,包含一个数据库实例的相关数据和控制信息,在实例启动时自动分配关闭是自动回收。从10G开始,oracle提供了SGA的自动管理
(AUTOMATIC SHARED MEMORY MANAGEMENT ,ASSM)新特性。就是不需要手动设置shared pool ,buffer cacher等,只设置一个总的sga大小即可。oracle自动调整大小。
show parameter sga_target 查询的value 为0即表示ASSM管理的方式,安装11G是默认开启自动管理的。
ASSM的启用:
启用ASSM需要将statistics_level设置成typical或all,该参数的级别有三个:
1、basic:收集基本的统计信息
2、typical:收集大部分的统计信息,数据库默认设置
3、all:收集全部统计信息
alter system set statistics_level=all;
或者 alter session set statistics_level=all;
在启用ASSM后,如手动指定某一组值,则该值为该组件的最小值。例如手动设置了sga_target=8G,shared_pool_size=1g,则在assm自动调整sga时,保证shared pool的最小值为1g。关于sga_max_size指定内存中可以分配给sga的最大值,不允许动态调整,是一个固定值;sga_target是一个动态参数,其最大值为sga_max_size。
SGA包含的组件:共享池(shared pool);数据库缓冲区高速缓存(database buffer cache);日志缓冲区(redo buffer cache);大池;Java池;流池等。
SGA相关视图:
v$sga:V$SGA这个视图包括了SGA的的总体情况,只包含两个字段:name(SGA内存区名字)和value(内存区的值,单位为字节)。它的结果和show sga的结果一致。
v$sgastat:10g之前用于查看各SGA组件大小。V$SGAINFO的作用基本和V$SGA一样,只不过把Variable size的部分更细化了一步
v$sgainfo:10g及10g之后才有的。用于查看SGA组件大小更简便。
v$sga_dynamic_components:这个视图记录了SGA各个动态内存区的情况,它的统计信息是基于已经完成了的,针对SGA动态内存区大小调整的操作。
v$sga_dynamic_free_memory:这个视图只有一个字段就是用来表示SGA当前可以用于调整各个组件的剩余大小。
v$sga_target_advice:该视图可用于建议SGA大小设置是否合理。
SELECT a.sga_size,--sga期望大小
a.sga_size_factor,--期望sga大小与实际sga大小的百分比
a.estd_db_time,--sga设置为期望的大小后,其dbtime消耗期望的变化
a.estd_db_time_factor,--修改sga为期望大小后,dbtime消耗的变化与修改前的变化百分比
a.estd_physical_reads--修改前后物理读的差值
FROM v$sga_target_advice a;
I)不能单看库高速缓存命中率的大小,结合v$librarycache中的reloads来分析。如果reloads值比较大,表明许多sql语句在老化退出后又被
重新装入库池。若sql语句是因为没有使用绑定变量导致reloads值变大,可修改该sql采用绑定变量的方式;若sql语句无法使用绑定变量,
则可考虑将sql语句用dbms_shared_pool中的keep过程将需要钉在库池中的对象钉住,用unkeep过程释放。
sys.dbms_shared_pool.keep(name => ,flag => )--Name是需要固定的对象的名称,flag是要固定的对象的类型
II)dbms_shared_pool说明:
1)默认下该包没安装,可利用$ORACLE_HOME/rdbms/admin目录下的dbmspool.sql脚本来安装(sys用户执行),其他用户需要sys用户授权后
才可使用。
2)对于固定在共享池中的对象,当共享池空间不足的时候,ORACLE不会释放这些对象以获取创建新的项目所需要的空间,甚至刷新共享池的时候,
这些对象也不会被清除。
3)dbms_shared_pool包的keep和unkeep过程中的flag的取值:
固定SQL的keep示例:dbms_shared_pool.keep(‘address,hash_value‘,‘C‘),其中SQL语句的ADDRESS和HASH_VALUE可以在V$SQLAREA中找到;
对于函数、过程和包示例如下:dbms_shared_pool.keep(‘name‘,‘P‘)。
注:如果采用该过程将程序固定到共享池后,刷新缓冲区(alter system flush shared_pool)也不会清除,必须使用unkeep过程清除。
4.1.3 调优库高速缓存
优化库高速缓存的目的是重用以前分析过的或执行过的代码。最简单的方法就是使用绑定变量,减少硬分析。
4.1.3.1 游标共享cursor_sharing参数的使用,使之使用绑定变量
cursor_sharing参数有三个值:
SIMILAR:只在认为绑定变量不会对优化产生负面影响时才使用绑定变量。
FORCE:强制在所有情况下使用绑定变量。
EXACT:默认情况下为该值
ORACLE建议使用CURSOR_SHARING=SIMILAR,因为使用CURSOR_SHARING=FORCE有可能使执行计划变坏。但实际上CURSOR_SHARING=FORCE
对执行计划的好处要远远大于坏处。在观察到由于不使用绑定变量而导致大量硬分析时,通过把默认的CURSOR_SHARING=EXACT改成CURSOR_SHARING=FORCE
可极大的改善性能。可在init.ora或spfile中更改这个参数,也可使用alter system 或alter session 动态的执行更改。
4.1.3.2 硬分析语句的查询与改进
查看硬分析语句
select s.sid, s.value "execute counts", t.value "hard parse"
from v$sesstat s, v$sesstat t
where s.sid = t.sid
and s.statistic# in
(select statistic# from v$statname where name = ‘execute count‘)
and t.statistic# in
(select statistic# from v$statname where name = ‘parse count (hard)‘)
order by t.value desc;
将硬分析语句采用绑定变量方式或者直接将该sql固定到缓存中。
4.1.3.3 减少软分析,降低库高速缓存闩锁争用
通过以下措施可将软分析保持为最低:
1)设置 SESSION_CACHED_CURSORS
SESSION_CACHED_CURSORS,就是说的是一个session可以缓存多少个cursor,让后续相同的SQL语句不再打开游标,从而避免软解析的过程来提高性能。
(绑定变量是解决硬解析的问题),软解析同硬解析一样,比较消耗资源.所以这个参数非常重要。
当一个cursor关闭之后,oracle会检查这个cursor的request次数是否超过3次,如果超过了三次,就会放入session cursor cache list的MRU端,
这样在下次打算parse一个sql时,它会先去pga内搜索session cursor cache list,如果找到那么会把这个cursor脱离list,然后当关闭的时候再把这个
cursor加到MRU端. session_cached_cursor提供了快速软分析的功能,提供了比soft parse更高的性能。session cursor cache的管理也是使用LRU。
session_cached_cursors这个参数是控制session cursor cache的大小的。session_cached_cursors定义了session cursor cache中存储的
cursor的个数。这个值越大,则会消耗的内存越多。
另外检查这个参数是否设置的合理,可以从两个statistic来检查。
SQL> select name,value from v$sysstat where name like ‘%cursor%‘;
NAME VALUE
---------------------------------------------------------------- ----------
opened cursors cumulative 17889
opened cursors current 34
session cursor cache hits 16481
session cursor cache count 777
cursor authentications 294
SQL>select name,value from v$sysstat where name like ‘%parse%‘;
NAME VALUE
---------------------------------------------------------------- ----------
parse time cpu 331
parse time elapsed 2021
parse count (total) 12134
parse count (hard) 1355
parse count (failures) 3
session cursor cache hits 和parse count(total) 就是总的parse次数中,在session cursor cache中找到的次数,所占比例越高,性能越好。
如果比例比较低,并且有剩余内存的话,可以考虑加大该参数。
Oracle 9i及以前,该参数缺省是0,10G上缺省是20。
open_cursors 是充许打开的游标的数量
session_cached_cursors 是充许放入缓存的游标的数量
2)在应用程序预编译器中设置 HOLD_CURSOR
HOLD_CURSOR=YES|NO;缺省值为NO。
当执行SQL操纵语句时,其相关的光标被连到光标高速缓冲存储器中的一项上,该项又被依次连接到ORACLE专用的SQL区域上,该区域存储处理该语句
所需的信息。
当HOLD_CURSOR=NO时,在ORACLE执行完SQL语句或关闭光标后,预编译程序直接撤去该链,释放分析块和分配给专用SQL区域的内存,并把该链标为可再
使用。这时另一个SQL语句就又可使用该链来指向光标高速缓冲存储器的项了。
当HOLD_CURSOR=YES时,该链被保留,预编译程序不再使用它。这对经常使用的SQL语句是有用的。
如果RELEASE_CURSOR=no(默认 no),HOLD_CURSOR=yes(默认为no),当ORACLE执行完SQL语句,为private SQL AREA分配的内存空间被保留,
cursor和private SQL AREA之间的link也被保留,预编译程序不再使用它,同样可以通过这个指针直接在private SQL AREA获得语句。
注意:RELEASE_CURSOR=YES优先于HOLD_CURSOR=YES;HOLD_CURSOR=NO优先于RELEASE_CURSOR=NO。
3)设置 CURSOR_SPACE_FOR_TIME 默认为false 废弃
该参数本意是通过设置为true可以保证游标在关闭前不能重新分配游标。
但是注意,该参数已废弃。
4.1.3.4 修改share_pool大小
查看库缓存命中率大小,若大小,可试着加大share_pool。
4.2 数据字典缓冲区
--查看数据字典缓冲区的使用率(应该在90%以上,否则需要增加共享池的大小)
select (sum(gets-getmisses-usage-fixed))/sum(gets) "Data dictionary cache" from v$rowcache;
二、数据缓冲区
show parameter db_cache_size
--修改一些DB_CACHE相关参数
alter system set db_cache_size=100m; --默认池(所有段块一般都在这个池)
alter system set db_keep_cache_size=12m;--保持池(访问非常频繁的段可放置该池,防止在默认池老化)
alter system set db_recycle_cace_size=16m;--回收池(访问很随机的大段一般可放于该池)
--查看db_cache命中率
select name, value
from v$sysstat
where name in (‘db block gets from cache‘, ‘consistent gets from cache‘,
‘physical reads cache‘);
db_cache命中率算法
db_cache命中率=1-(physical reads cache/(db block gets from cache+consistent gets from cache)) --命中率应该在90%以上,否则需要增加数据缓冲区的大小
--采用v$buffer_pool_statistics视图推导缓冲区高速缓存的命中率
SELECT name,
physical_reads,
db_block_gets,
consistent_gets,
1 - (physical_reads / (db_block_gets + consistent_gets)) Hitratio
FROM v$buffer_pool_statistics;
--v$db_cache_advice视图用于建议缓冲区高速缓存设置
SELECT size_for_estimate "size",
buffers_for_estimate "buffers",
estd_physical_read_factor "read_factor",
estd_physical_reads "reads"
FROM v$db_cache_advice
WHERE NAME = ‘DEFAULT‘
AND block_size =
(SELECT VALUE FROM v$parameter WHERE NAME = ‘db_block_size‘);
注:对于常用的小表可以将其保存在keep池,这样就不会因为缓冲区满而被清出。
alter table table_name storage(buffer_pool keep) 。
三、重做日志缓冲区
Redo Log Buffer是SGA中一段保存数据库修改信息的缓存。这些信息被存储在重做条目(Redo Entry)中.重做条目中包含了由于INSERT、UPDATE、
DELETE、CREATE、ALTER或DROP所做的修改操作而需要对数据库重新组织或重做的必须信息。在必要时,重做条目还可以用于数据库恢复。
重做条目是Oracle数据库进程从用户内存中拷贝到Redo Log Buffer中去的。重做条目在内存中是连续相连的。后台进程LGWR负责将Redo Log Buffer中
的信息写入到磁盘上活动的重做日志文件(Redo Log File)或文件组中去的。
参数LOG_BUFFER决定了Redo Log Buffer的大小。它的默认值是512K(一般这个大小都是足够的),最大可以到4G。当系统中存在很多的大事务或者
事务数量非常多时,可能会导致日志文件IO增加,降低性能。这时就可以考虑增加LOG_BUFFER。
但是,Redo Log Buffer的实际大小并不是LOB_BUFFER的设定大小。为了保护Redo Log Buffer,oracle为它增加了保护页(一般为11K):
SQL> show parameter log_buffer
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
log_buffer integer 7024640
SQL> select * from v$sgastat where name = ‘log_buffer‘;
POOL NAME BYTES
------------ -------------------------- ----------
log_buffer 7135232
调整操作
alter system set log_buffer=3500000 scope=spfile;
四、大池(用于减轻共享池的负担,当有大规模的I/O操作或者备份恢复操作,或者是共享服务器进程)
其主要大小由参数large_pool_size决定
show parameter large_pool_size;
大池是SGA中的一块可选内存池,根据需要时配置。在以下情况下需要配置大池:
用于共享服务(Shared Server MTS方式中)的会话内存和Oracle分布式事务处理的Oracle XA接口
使用并行查询(Parallel Query Option PQO)时
IO服务进程
Oracle备份和恢复操作(启用了RMAN时)
通过从大池中分配会话内存给共享服务、Oracle XA或并行查询,oracle可以使用共享池主要来缓存共享SQL,以防止由于共享SQL缓存收缩导致的性能
消耗。此外,为Oracle备份和恢复操作、IO服务进程和并行查询分配的内存一般都是几百K,这么大的内存段从大池比从共享池更容易分配得到。
参数LARGE_POOL_SIZE设置大池的大小(alter system set large_pool_size=10M)。大池是属于SGA的可变区(Variable Area)的,它不属于共享池。
对于大池的访问,是受到 large memory latch 保护的。大池中只有两种内存段:空闲(free)和可空闲(freeable)内存段。它没有可重建
(recreatable)内存段,因此也不用LRU链表来管理(这和其他内存区的管理不同)。大池最大大小为4G。
为了防止大池中产生碎片,隐含参数 _LARGE_POOL_MIN_ALLOC 设置了大池中内存段的最小大小,默认值是16K(同样,不建议修改隐含参数)。
此外,large pool是没有LRU链表的。
五、JAVA池(使用java语言,java命令分析时需要使用)
其主要大小由参数java_pool_size决定
show parameter java_pool_size;
Java池也是SGA中的一块可选内存区,它也属于SGA中的可变区。
Java池的内存是用于存储所有会话中特定Java代码和JVM中数据。Java池的使用方式依赖与Oracle服务的运行模式。
Java池的大小由参数JAVA_POOL_SIZE设置(alter system set java_pool_size=10M;)。Java Pool最大可到1G。
在Oracle 10g以后,提供了一个新的建议器——Java池建议器——来辅助DBA调整Java池大小。建议器的统计数据可以通过视图
V$JAVA_POOL_ADVICE来查询。
六、流池
流池是Oracle 10g中新增加的。是为了增加对流(流复制是Oracle 9iR2中引入的一个非常吸引人的特性,支持异构数据库之间的复制。10g中得到了
完善)的支持。
流池也是可选内存区,属于SGA中的可变区。它的大小可以通过参数 STREAMS_POOL_SIZE 来指定。如果没有被指定,oracle会在第一次使用流时自动创
建。如果设置了SGA_TARGET参数,Oracle会从SGA中分配内存给流池;如果没有指定SGA_TARGET,则从buffer cache中转换一部分内存过来给流池。转换
的大小是共享池大小的10%。
Oracle同样为流池提供了一个建议器——流池建议器。建议器的统计数据可以通过视图V$STREAMS_POOL_ADVICE查询。
本文参考了大神的总结https://www.cnblogs.com/oracle-dba/articles/3641935.html。
原文:https://www.cnblogs.com/magic-dw/p/14947773.html