怎么样管理Oracle的内存

来源:互联网 发布:富通贷网络贷款 编辑:程序博客网 时间:2024/04/27 21:23

怎么样管理Oracle的内存

1、管理共享池
共享池的管理一直也是颇有争议的一个话题,每个版本不一样,具体管理方式也大不一样(关键是算法不一样,结构还是基本一样)。共享池的内部管理方式,我们可以通过如下的dump来分析:
SQL> alter session set events 'immediate trace name heapdump level 2';
通过分析跟踪文件,其实可以发现,在8i/9i的管理中,都是通过extent、bucket与chunk来管理共享池。在物理空间管理上,共享池划分为多个extent,每个extent中包含很多对应的chunk。在空闲空间的管理上,则采用freelist的方式管理,8i共有11(0-10)个bucket空闲列表,而9i则有255(0-254)个bucket空闲列表,每个bucket管理的chunk的大小不一样,当申请空间时,则到对应的bucket去申请空闲的chunk,如果没有,则转到下一个bucket,分裂一个大的chunk为已用的chunk与另外一个小的空闲chunk,放到对应的空闲bucket中。
如果我们想清理共享池,可以采用如下的命令:
SQL>alter system flush shared_pool

而共享池中,我们比较关心的则是library cache的管理,因为这部分是进行语句分析与cache的重要部分。我们可以用如下的命令来dump library cache:
SQL> alter session set events 'immediate trace name LIBRARY_CACHE level LL';
其中LL代表Level级别,对于9.2.0及以后版本,不同Level含义如下:
Level =1 ,转储Library cache统计信息
Level =2 ,转储hash table概要
Level =4 ,转储Library cache对象,只包含基本信息
Level =8 ,转储Library cache对象,包含详细信息(包括child references,pin waiters等)
Level =16,增加heap sizes信息
Level =32,增加heap信息
Library cache由一个hash表组成,而hash表是一个由hash buckets组成的数组,每个hash bucket都是包含library cache handle的一个双向链表(每个hash bucket中可能包含多个library cache handle),每个Library Cache Handle指向Library Cache Object(如SQL),含对象名,namespace,时间戳,引用列表,锁定对象及pin对象列表等。另外Library Cache Handle指向Library Cache Object和一个引用列表。
我们解释一个简单的软分析过程,SQL语句经过hash之后,被对应到相应的hash bucket,然后在bucket中查找对应的library cache handle,然后在library cache handle对应的引用列表中检查依赖关系等等,最后根据heap descriptor,指向相应的heap memory。这个heap memory包含的就是Diana Tree,P-Code,Source Code,Shared Cursor Context area等重要数据,也就是我们通常所说的,解析过的SQL及执行计划树,真正到这里以后,sql才得以共享.也就真正的避免了硬解析

"library cache pin" 是用来管理library cache的并发访问的,pin一个object会引起相应的heap被载入内存中(如果此前没有被加载),Pins可以在三个模式下获得:NULL,SHARE,EXCLUSIVE,可以认为pin是一种特定形式的锁,当Library Cache Pin等待事件出现时,通常说明该Pin被其他用户已非兼容模式持有。
以下语句可以获得library cache pin的被等待的session信息

代码:



SELECT a
.SID, a.username, a.program, b.addr, b.kglpnadr, b.kglpnuse,
       
b.kglpnses, b.kglpnhdl, b.kglpnlck, b.kglpnmod, b.
kglpnreq
  FROM v$session a
,
x$kglpn b
WHERE a
.saddr = b.
kglpnuse
   
AND b.kglpnmod <>
0
   
AND b.kglpnhdl IN (
SELECT p1raw
                        FROM v$session_wait
                       WHERE event LIKE
'library%'
)
.


以下语句可以获得被等待的session正在执行的语句:

代码:



SELECT sql_text
  FROM v$sqlarea
WHERE
(v$sqlarea.address, v$sqlarea.hash_value) IN (
          
SELECT sql_address,
sql_hash_value
            FROM v$session
           WHERE SID IN
(
                    
SELECT SID
                      FROM v$session a
,
x$kglpn b
                     WHERE a
.saddr = b.
kglpnuse
                       
AND b.kglpnmod <>
0
                       
AND b.kglpnhdl IN (
SELECT p1raw
                                FROM v$session_wait
                                WHERE event LIKE
'library%'
)))
.


2、管理data buffer
oracle的data buffer默认只有default pool,实际上,data buffer在9i中可以分为db_cache_size,db_keep_cache_size与db_recycle_cache_size,而且db_cache_size还可以根据块大小划分db_2k_cache_size,4k/8k/16k/32k等不同的buffer区域。对于9i以前版本,则由对应的db_block_buffers, buffer_pool_keep, buffer_pool_recycle等参数决定。
这些参数可以通过如下命令来修改
SQL> alter system set db_keep_cache_size = xxxx scope = both;
一般而言,如果不是特殊指定,所有对象都是存放在default pool中,并且按照特定的LRU算法工作,如果要指定一个对象要keep或者是recycle pool,可以通过如下的语法指定。
SQL>alter table table_name storage(buffer_pool keep);
最后,如果想知道对象处于什么pool中,简单的可以在user_segments中查询获得。
SQL> select t.segment_name,t.buffer_pool from user_segments t;

如果想计算一个对象在data buffer中占用了多少空间(块),则可以采用如下方法

代码:



SELECT DATA_OBJECT_ID
, OBJECT_TYPE
  FROM DBA_OBJECTS
WHERE OBJECT_NAME
= UPPER('xxx'
);

SELECT COUNT(*)
BUFFERS
  FROM V$BH
WHERE objd
= xxx
;
.


data buffer也可以被清空,在Oracle9i里,Oracle提供了一个内部事件,用以强制刷新Buffer Cache,其语法为:
SQL>alter session set events 'immediate trace name flush_cache level 1';
或者:
SQL>alter session set events = 'immediate trace name flush_cache';
类似的也可以使用alter system系统级设置:
SQL>alter system set events = 'immediate trace name flush_cache';
在Oracle10g中,Oracle提供一个新的特性,可以通过如下命令刷新Buffer Cache:
SQL>alter system flush buffer_cache;

另外,oracle 9i可以支持在sga_max_size设置的范围内,在线调整不同的内存区大小。在oracle 10g中,内存管理又有了新的变化,oracle默认将自动管理内存的分配,而不需要手工干预共享池与data buffer的大小。


原创粉丝点击