Skip to content

未分类 - 5. page

SubPool技术及优势:
从Oracle 9i开始,Shared Pool可以被分割为多个子缓冲池(SubPool)进行管理,以提高并发性,减少竞争。
Shared Pool的每个SubPool可以被看作是一个Mini Shared Pool,拥有自己独立的Free List、内存结构以及LRU List、shared pool latch。同时Oracle提供多个Latch对各个子缓冲池进行管理,从而避免单个Latch的竞争(Shared Pool Reserved Area同样进行分割管理)。从10G开始,每个SubPool由4个SUB PARTITION组成。
SubPool的个数和大小
每四个CPU分配一个SubPool,最多可以有7个。Shared Pool Latch也就从原来的一个增加到现在的7个。
在Oracle 9i中,每个SubPool至少为128MB。
10G-10.2.0.3,每个SubPool至少为256MB
10.2.0.3之后,最少为512M。
_kghdsidx_count 隐含参数:ORACLE启动时,优化根据此参数设置SubPool数量。
SubPool缺点:
从ORACL 10G开始,ORACLE进程在某个SubPool中请求内存失败,会到下一个SubPool中请求—过小的SubPool碎片问题可能更严重–ORA-4031出现机率更大。
过多的SubPool还会带来更高的管理协调成本。
比如以下错误就是与SubPool相关:
ORA-04031: unable to allocate 4216 bytes of shared memory
(“shared pool”,”unknown object”,”sga heap(2,0)”,”library cache”)
共享池大小的判断
LRU链表分两条:transient LRU(瞬时LRU)、 RECURRENT(周期LRU)。Chunk在第一次使用时,被放入瞬时LRU,第二次使用时,会被移至周期LRU。

DSI中建议用如下SQL统计LRU和相关信息:
select KGHLUTRN transient,KGHLURCR recurrent ,KGHLUFSH Flush_chunk_number, KGHLUOPS Pin_or_release_operations from X$KGHLU;
–查询出的是自数据库启动以来的,执行ALTER SYSTEM FLUSH SHARED_POOL不会清零。
其中:
TRANSIENT,瞬时LRU链长度。
RECURRENT,周期LRU链长度。
FLUSH_CHUNK_NUMBER,Flush Chunk数。
PIN_OR_RELEASE_OPERATIONS,Pin或释放Chunk操作的次数。
如果瞬时LRU链长度超过周期LRU链长度3倍,大量只用一次的Chunk堆积在LRU中,说明共享池太大了。
如果Flush Chunk数和Pin、释放Chunk操作次数的比小于1:20,说明共享池太小了。这个比例,简单点说,Oracle认为每20次操作Chunk,只有一次Flush Chunk操作,还是可以接受的。如果再低,说明共享池有点小。

######Chunk数和Pin、释放Chunk操作次数的比小于1:20,说明共享池太小了。
这一句错了吧,应该是大于20分之1(每20次操作有一次需要FLUSH CHUNK)时,如十分之1(每十次操作需要一次需要FLUSH CHUNK),说明共享池太小。
共享池一般不超过10G,5、6G即可。过大共享池需要更大管理成本
#####################################################################
结果集缓存–RESULT CACHE
DB_BUFFER只能缓存访问过的BLOCK,部分解决了物理读的问题,查询仍然需要大量的逻辑读。
物化视图提供的是查询重写的功能,对于大部分的情况,只是简化了SQL的复杂度,即使是完全满足查询的条件,物化视图的扫描也是不可避免的。
而缓存结果集——RESULT CACHE则截然不同,它缓存的是查询的结果。不在需要大量的逻辑读,不在需要任何的复杂计算,而是直接将已经缓存的结果返回。—SQL的几乎全部开销都可以避免。这些开销包括,解析时间、逻辑读、物理读和任意的通常可能会遭遇的争用。

RESULT CACHE的结果对于所有的SESSION都是可见的。
RESULT CACHE是满足一致性读的,而且当缓存表数据发生变化的时候,Oracle会自动INVALIDATE缓存结果集:
是否使用RESULT_CACHE与Oracle的执行计划无关:
RESULT CACHE忽略SQL语句的执行计划,即使执行计划发生了变化,只有最终获取的结果是一样的,Oracle仍然会使用RESULT CACHE。
注意当执行计划不同导致结果不同时,Oracle使用RESULT CACHE可能会得到不正确的结果。

对于SQL中间结果使用RESULT CACHE必须使用RESULT_CACHE提示进行强制。
RESULT CACHE功能对于下列情况是无效的:系统表和临时表;序列的NEXTVAL和CURRVAL伪列;SYSDATE、SYSTIMESTAMP等函数;所有非确定性PL/SQL函数。
RESULT_CACHE和NO_RESULT_CACHE
Oracle新增了两个HINT,RESULT_CACHE和NO_RESULT_CACHE。通过这两个提示,可以明确的指出下面的语句是否进行RESULT CACHE。

Oracle还增加了几个初始化参数来管理RESULT CACHE功能,如:RESULT_CACHE_MODE、RESULT_CACHE_MAX_SIZE等。
RESULT_CACHE_MAX_SIZE指明SGA中RESULT CACHE功能可以使用的最大的内存容量。如果这个参数设置为0,则关闭RESULT CACHE功能。
RESULT_CACHE_MODE参数设置Oracle如何使用RESULT CACHE,有三个值:MANUAL、AUTO、FORCE。
当参数值设置为MANUAL时,只有通过HINT明确提示的SQL才会读取缓存结果集。如果不加提示,那么Oracle不会利用已经缓存的结果。
对于AUTO模式,Oracle如果发现缓冲结果集已经存在,那么就会使用。但是如果缓冲结果集不存在,Oracle并不会自动进行缓冲。只有使用HINT的情况下,Oracle才会将执行的结果集缓存。
对于FORCE参数,就是会对所有的SQL进行缓存,除非明确使用NO_RESULT_CACHE提示:
result_cache_max_result设置单个sql语句占用整个RESULT CACHE缓冲区的百分比,默认5%。
RESULT_CACHE_MAX_SIZE用来设置RESULT CACHE的总体大小–不超过过SHARED_POOL_SIZE的75%

在11.2.0.4中,默认是:MANUAL
BYS@ bys3>show parameter result_cache_mode
NAME TYPE VALUE
———————————— ———– ——————————
result_cache_mode string MANUAL
Oracle提供了DBMS_RESULT_CACHE包来管理和维护RESULT CACHE。
Oracle还新增了几个关于RESULT CACHE的系统视图,用户可以看到和RESULT CACHE相关的各种信息,视图包括:V$RESULT_CACHE_DEPENDENCY、V$RESULT_CACHE_MEMORY、V$RESULT_CACHE_OBJECTS和V$RESULT_CACHE_STATISTICS等。
关于结果集缓存详见:
http://www.itpub.net/thread-846890-1-1.html
http://database.ctocio.com.cn/tips/365/8273865.shtml

共享池之五:Shared Pool子池与结果集缓存技术

字典缓冲区: dictionary cache,也叫row cache;
用于保存数据字典信息:如表空间相关信息、用户权限、objects信息、histogram信息等。
字典缓冲区在大小无法直接调整,只能通过调整共享池大小来调整字典缓冲区大小。
SYS@ bys3>select pool,name ,bytes/1024/1024 MB from v$sgastat where name like ‘row cache%’;
POOL NAME MB
———— ————————– ———-
shared pool row cache child latch .004959106
shared pool row cache 4.12324524
我的实验环境,字典缓冲区大小为4M多一点,还可以统计出row cache child latch的大小。
#####################################################################
row cache child latch

V$ROWCACHE视图可以查询保存在row cache中的对象信息。
row cache child latch的子latch个数:
SYS@ bys3>select count(name),name from v$latch_children where name like ‘row cache%’ group by name;
COUNT(NAME) NAME
———– —————————————————————-
52 row cache objects
每个子latch管理着不同的对象。
使用场景:
硬解析时需要从数据字典信息中生成执行计划,row cache信息由row cache child latch保护,所以在并发访问row cache时会引起row cache child latch竞争。

row cache child latch 常见场景:
1.DDL操作需要修改数据字典
2.SEQUENCE:原因是SEQUENCE的NEXTVAL操作对row cache objects以SSX(SHARED SUB_EXVLUSIVE)独占模式获得row cache lock. 当多个进程同时对同一SEQUENCE的NEXTVAL进行调用时会发生:latch:row cache objects等待事件。
如CACHE过小,当CACEH分配的值用完会重新获取一次CACHE,会更新seq$基表并提交—修改ROW CACHE信息,会话会一直持有SQ锁,会出现enq:sq-contention等待事件。—P2值是对象号。
NOCACHE:每次使用NEXTVAL,都要更新seq$基表并提交。
关于SEQUENCE,详见:http://blog.csdn.net/haibusuanyun/article/details/17248029#t2

3.SYS.AUDSED$: ORACLE 10.2.0.4之前SYS.AUDSED$的CACHE值为20,主要用于V$SESSION.AUDSID的取值。当出现大量并发短连接–登陆风暴,容易因SYS.AUDSED$的CACHE值过小引起会话一直持有SQ锁,出现enq:sq-contention等待事件。===解决方法:将SYS.AUDSED$的CACHE值改大。
10.2.0.4之后,SYS.AUDSED$的CACHE值默认为10000.

4.通过远程DBLINK访问的SQL在本地解析时要获取16号row cache child latch,可能会引起争用–可以在内存足够情况下增大共享池及PGA大小,增加session_cache_cursor大小—注意要重启库且要注意增大会占用更多内存。 –此案例见周亮《ORACLE DBA 实战攻略》301页。

共享池之四: row cache–字典缓冲区

Library cache结构
Library cache最主要的功能就是存放用户提交的SQL语句,SQL语句相关的解析树(解析树也就是对SQL语句中所涉及到的所有对象的展现)—>共享SQL区(shared SQL areas),私有SQL区(private SQLareas,如果配置了共享服务器),执行计划,用户提交的PL/SQL程序块(包括匿名程序块,存储过程,包,函数等)以及它们转换后能够被Oracle执行的代码等,为了对这些内存结构进行管理,library cache中还存放了很多控制结构,包括lock,pin,dependency table,11G中的mutex等。
Library cache需要解决三个问题:
(1).快速定位的问题:Library cache中对象众多,Oracle如何管理这些对象,以便服务进程可以迅速找到他们需要的信息。比如某个服务进程需要迅速定位某个SQL是否存在于Librarycache中。- –Oracle利用hash table结构来解决library cache中快速定位的问题
(2).关系依赖的问题:Library cache中的对象存在复杂的依赖关系,当某个objec失效时,可以迅速将依赖其的对象也置为失效状态。比如某个表发生了结构变化,依赖其的SQL语句需要重新解析。—LCO中 dependency table
(3).并发控制的问题:Library cache中必须有一个并发控制的机构,比如锁机制,来管理大量共享对象的并发访问和修改的问题,比如某个SQL在重新编译的同时,其所依赖的对象不能被修改。—-LATCH LOCK PIN

Library cache由一个hash表组成,hash表是由hash buckets组成的数组。
每个hash bucket都是包含library cache handle的一个双向链表。
library cache handle指向library cache object和一个引用列表。
library cache 对象进一步分为:依赖表、子表、授权表等
同一个SQL语句,HASH值相同,放在同一个library cache handle–如绑定变量,是用同一个library cache handle下不同的的子游标。不同的SQL语句,HASH值相同放在同一hash bucket的不同library cache handle。
Hash 算法
Oracle在内部管理中大量的使用到了hash,使用hash的目的就是为了快速查找和定位.
对数值进行hash运算,产生一个索引号,然后根据索引号将数值放置到相应的hash bucket中去.
根据hash运算的法则,会产生多个索引号,每一个索引号对应一个hash bucket(一个数值列).
在寻找数值的时候,将搜寻的数值进行hash,产生一个索引号,那么这个数值一定在这个索引号对应的 hash bucket中,于是直接跳转到这个hash bucket中进行遍历。这样在定位数据的时候,就能够大大的减少遍历的数量。

hash bucket:库缓存中就是使用hash bucket来管理的
1、首先根据shared_pool_size指定的尺寸来自动计算hash bucket的个数
2、每个hash bucket后面都串联着多个句柄
句柄描述了library cache里面的对象的一些属性,包括名称、标记、指向对象所处的内存地址的指针

library cache handle:—–OBJECT Handle
一个handle管理着一个library cache object,handle对LCO起到指针作用。
Library cache中所有对象的访问是通过利用library cache handle来实现的
当一个进程请求library cache object, librarycache manager就会应用一个hash 算法,从而得到一个hash 值,根据相应的hash值到相应的hash bucket中去寻找。
如果library cache object在内存中,那么这个library cache handle就会被找到。有时候,当shared pool不够大,library cache handle会保留在内存中,然而library cache heap由于内存不足被age out,这个时候我们请求的object heap就会被重载。最坏的情况下,library cache handle在内存中没有找到,这个时候就必须分配一个新的library cachehandle,同时object heap也会被加载到内存中。

###############

library cache object的结构: –LCO
见上图,主要保存SQL的实际信息,包括:
dependency table –当前LCO依赖的其它LCO信息,如SQL语句依赖的表、视图等。
1.Chile table—-保存当前LCO的子LCO信息
一个LCO会有多个子LCO—多版本问题。—一条SQL至少有一个parent cursor 和 child cursor。
存在不同版本SQL可能是:不同用户执行相同SQL文件的SQL.–也可能是BUG。

SQL语句文本一样-HASH值一样,执行计划不一样的情况有:–多版本
1.不同用户下有同名的表,不同的用户执行查询此表操作,就会出现不同执行计划。
2.绑定变量时,如果绑定变量的字符串( 详见:绑定变量分级)变化达到一定程度,执行计划也会不一样

HIGH VERSION高版本的SQL语句有多个子LCO,每个子HANDLE对应一个子LCO。—parent cursor 里对应的所有child cursor的指针都会保存在child table里面。- -parent cursor和child cursor都是用library cache object handle 存储在Library Cache里的。—结构一样
当子LCO数量很多–SQL版本数(VERSION COUNT)很高,会话扫描BUCKET时间变长,持有latch:library cache时间也变长,定位到具体的child sql cursor时间相应变长(顺序扫描HANDLE),latch:library cache争用的概念增加。
查看SQL版本信息:
BYS@ bys3>select * from (select version_count,sql_id,sql_text from v$sqlarea order by version_count desc) where rownum<5 ;

BYS@ bys3>select version_count,sql_id,sql_text from v$sqlarea where sql_text like ‘select * from bys.dept’;
VERSION_COUNT SQL_ID SQL_TEXT
————- ————- ——————————
1 f4yk5kundsxfd select * from bys.dept
2.data blocks —保存SQL语句、执行计划、执行文本等信息。
ORACLE通过地址指向存储 这些信息的HEAP /CHUNK。HEAP 6存储着SQL执行计划。
ORACLE 10.2.0.4开始可以通过dbms_shared_pool.purge 包清理HEAP 6中执行计划。
3.dependency table
指向本对象所依赖的对象,比如:select * from emp这个cursor的对象,依赖emp这个表,这里指向了emp这个表的handle。
####################################################3
通过x$kglob找出SQL语句父游标地址,并DUMP library cache,在TRACE文件中父游标的地址中找到SQL语句。
会话1
SYS@ bys3>select * from bys.dept;
SYS@ bys3>col KGLNAOBJ for a40
SYS@ bys3> select kglhdadr,kglhdpar,kglnaobj,kglobhd0 from x$kglob where kglnaobj like ‘select * from bys.dept%’;
KGLHDADR KGLHDPAR KGLNAOBJ KGLOBHD0
——– ——– —————————— ——–
23ACB574 248344B8 select * from bys.dept 242B7D1C –23ACB574子游标地址
248344B8 248344B8 select * from bys.dept 23FE4684 –248344B8父游标地址,父游标heap 0地址-其实是描述符-23FE4684

select KGLHDADR,KGLHDPAR,KGLNAOBJ,KGLOBHD0 from x$kglob where kglnaobj like ‘select * from bys.dept%’ and KGLHDADR<>KGLHDPAR ; 查出子游标
select KGLHDADR,KGLHDPAR,KGLNAOBJ,KGLOBHD0 from x$kglob where kglnaobj like ‘select * from bys.dept%’ and KGLHDADR=KGLHDPAR ; 查出父游标

SYS@ bys3> select KSMCHPTR,KSMCHCOM,KSMCHCLS,KSMCHSIZ from x$ksmsp where KSMCHPAR=’23FE4684′; –通过上一步查出的 heap 0描述符找到查看父游标所在CHUNK地址大小描述状态
KSMCHPTR KSMCHCOM KSMCHCLS KSMCHSIZ
——– —————- ——– ———-
241D3A44 KGLH0^a8dc75cd recr 4096

新打开一个会话:DUMP library cache并查找SQL语句。
SYS@ bys3>alter session set events ‘immediate trace name heapdump level 2050’;
SYS@ bys3>select value from v$diag_info where name like ‘De%’;
VALUE
—————————————————————————————————-
/u01/diag/rdbms/bys3/bys3/trace/bys3_ora_31638.trc
#################
VI中查询: 在241D3A44这个地址开始的这个 Chunk中找到了SQL语句
Chunk 241d3a44 sz= 4096 recreate “KGLH0^a8dc75cd ” latch=(nil)
ds 23fe4684 sz= 4096 ct= 1
Dump of memory from 0x241D3A44 to 0x241D4A44
241D3A40 80001001 241D2A44 00000000 [….D*.$….]
241D3A50 00000000 00000000 00000000 000A0FFF […………….]
………………

Chunk 2405e530 sz= 4096 recreate “SQLA^bf04295e ” latch=(nil)
Dump of memory from 0x2405E530 to 0x2405F530
2405E530 80001001 2405E164 2526A6EC 237A8414 [….d..$..&%..z#]
………………
2405E680 00000000 00000000 00000000 00000000 […………….]
2405E690 00000000 00000000 F4A4D8E8 735DAFAF […………..]s]
2405E6A0 00000000 00000049 2405E65C 11390064 [….I…\..$d.9.]
2405E6B0 01748F8F 18150001 407EC500 0A8A0500 [..t…….~@….]
2405E6C0 00020103 00090203 093A0000 1E070604 [……….:…..]
2405E6D0 F0836A0A A8E0F183 E036E426 83E426A8 [.j……&.6..&..]
2405E6E0 03F383F5 02030302 008E0000 00000025 […………%…]
2405E6F0 2405E6A4 110B3B04 656C6573 2A207463 […$.;..select *]
2405E700 6F726620 7962206D 65642E73 00257470 [ from bys.dept%.]
2405E710 0000003D 2405E6EC 110B3B34 0000000D [=……$4;……]
2405E720 00000801 00170040 00010369 00000018 [….@…i…….]
…………
###########################################################################

通过x$kglob找出SQL语句子游标地址及堆6地址,并DUMP library cache,在TRACE文件中查看的内容。
堆0 heap 0 –属于父游标-library cache handle,子游标里也有两个堆,堆0 存放指向堆6的地址
SYS@ bys3>select * from bys.dept;
SYS@ bys3>col KGLNAOBJ for a25
SYS@ bys3> select kglhdadr,kglhdpar,kglnaobj,KGLOBHS0,kglobhd0,KGLOBHS6,KGLOBHD6 from x$kglob where kglnaobj like ‘select * from bys.dept%’;
KGLHDADR KGLHDPAR KGLNAOBJ KGLOBHS0 KGLOBHD0 KGLOBHS6 KGLOBHD6
——– ——– ————————- ———- ——– ———- ——–
2358B76C 23D0705C select * from bys.dept 4348 2526A068 4060 243F2238
23D0705C 23D0705C select * from bys.dept 4516 23D65B44 0 00
父游标LibraryHandle 地址KGLHDPAR:23D0705C 子游标LibraryHandle地址KGLHDADR:2358B76C,
父游标堆0描述KGLOBHD0:23D65B44,子游标堆0描述:2526A068,子游标堆6描述KGLOBHD6:243F2238

这一点可以DUMP查看, alter session set events ‘immediate trace name heapdump_addr level 2,addr0x23b31e80‘; 类似以下:desc=0x23b31e80这种就可以与上面查出的KGLOBHD0字段信息对应–我这是后来增加的,没法对应上了。

******************************************************
HEAP DUMP heap name=”KGLH0^1020848″ desc=0x23b31e80
extent sz=0xff4 alt=32767 het=28 rec=9 flg=2 opc=0
parent=0x200010b4 owner=0x23b31e4c nex=(nil) xsz=0xfe4 heap=(nil)
fl2=0x26, nex=(nil), dsxvers=1, dsxflg=0x0
dsx first ext=0x240b19c4
EXTENT 0 addr=0x240b19c4
Chunk 240b19cc sz= 44 p

SYS@ bys3>select KSMCHPTR,KSMCHCOM,KSMCHCLS ,KSMCHSIZ from x$ksmsp where KSMCHPAR=’23D65B44′;
–通过上一步查出的父游标heap 0描述符找到查看父游标所在CHUNK地址大小描述状态
KSMCHPTR KSMCHCOM KSMCHCLS KSMCHSIZ
——– —————- ——– ———-
243F1D68 KGLH0^a8dc75cd recr 4096
SYS@ bys3>select KSMCHPTR,KSMCHCOM,KSMCHCLS ,KSMCHSIZ from x$ksmsp where KSMCHPAR=’2526A068′;
–通过上一步查出的子游标heap 0描述符找到查看子游标堆0所在CHUNK地址大小描述状态:
KSMCHPTR KSMCHCOM KSMCHCLS KSMCHSIZ
——– —————- ——– ———-
23FDD830 KGLH0^a8dc75cd recr 4096 –KGLH0^a8dc75cd –H0 heap 0
SYS@ bys3>select KSMCHPTR,KSMCHCOM,KSMCHCLS ,KSMCHSIZ from x$ksmsp where KSMCHPAR=’243F2238’;
–通过上一步查出的子游标heap 6描述符,找到查看子游标堆6所在CHUNK地址大小描述状态
KSMCHPTR KSMCHCOM KSMCHCLS KSMCHSIZ
——– —————- ——– ———-
23FDB830 SQLA^a8dc75cd recr 4096 –SQLA^a8dc75cd -SQL area

SYS@ bys3>col sql_text for a25
SYS@ bys3>select sql_id,hash_value,address,child_address,sql_text from v$sql where sql_text like ‘select * from bys.dept%’;
–查看SQL语句的SQL_ID,HASH_VALUE ADDRESS CHILD_AD等信息,与下面DUMP的信息对照。
SQL_ID HASH_VALUE ADDRESS CHILD_AD SQL_TEXT
————- ———- ——– ——– ————————-
f4yk5kundsxfd 2833020365 23D0705C 2358B76C select * from bys.dept
新会话DUMP
SYS@ bys3>alter session set events ‘immediate trace name library_cache level 16’;
Session altered.
level 1,转储library cache统计信息;level 2,转储hash table 概要
level 4,转储library cache对象基本信息;level 4,转储library cache对象详细信息
level 16,增加了heap sizes信息。
SYS@ bys3>select value from v$diag_info where name like ‘De%’;
VALUE
—————————————————
/u01/diag/rdbms/bys3/bys3/trace/bys3_ora_22403.trc

#########################################
Bucket: #=30157 Mutex=0x26ab5658(2e0000, 78, 0, 6)
LibraryHandle: Address=0x23d0705c Hash=a8dc75cd LockMode=0 PinMode=0 LoadLockMode=0 Status=VALD
##Address=0x23d0705c与x$kglob.KGLHDPAR父游标地址相符.Hash=a8dc75cd与x$ksmsp.KSMCHCOM相符,转换为10进制则与v$sql.HASH_VALUE相符;
ObjectName: Name=select * from bys.dept ##执行的语句内容,与x$kglob.KGLNAOBJ
FullHashValue=2cd147d1d9b8972be27a4596a8dc75cd Namespace=SQL AREA(00) Type=CURSOR(00) Identifier=2833020365 OwnerIdn=0
##Identifier=2833020365与v$sql.HASH_VALUE相符,Namespace=SQL AREA(00) SQL区域
Statistics: InvalidationCount=0 ExecutionCount=1 LoadCount=2 ActiveLocks=0 TotalLockCount=1 TotalPinCount=1
Counters: BrokenCount=1 RevocablePointer=1 KeepDependency=1 Version=0 BucketInUse=0 HandleInUse=0 HandleReferenceCount=0
Concurrency: DependencyMutex=0x23d070c4(0, 1, 0, 0) Mutex=0x23d07120(46, 39, 0, 6)
Flags=RON/PIN/TIM/PN0/DBN/[10012841]
WaitersLists:
Lock=0x23d070b4[0x23d070b4,0x23d070b4]
Pin=0x23d070a4[0x23d070a4,0x23d070a4]
LoadLock=0x23d070e8[0x23d070e8,0x23d070e8]
Timestamp: Current=01-04-2014 18:03:50 ##时间戳
HandleReference: Address=0x23d0718c Handle=(nil) Flags=[00]
ReferenceList:
Reference: Address=0x23fdcb14 Handle=0x2345e2a8 Flags=ROD[21]
LibraryObject: Address=0x243f1dc8 HeapMask=0000-0001-0001-0000 Flags=EXS[0000] Flags2=[0000] PublicFlags=[0000]
DataBlocks:
Block: #=’0′ name=KGLH0^a8dc75cd pins=0 Change=NONE
Heap=0x23d65b44 Pointer=0x243f1e1c Extent=0x243f1d84 Flags=I/-/P/A/-/-
FreedLocation=0 Alloc=1.546875 Size=3.988281 LoadTime=4405191980
ChildTable: size=’16’
Child: id=’0′ Table=0x243f2d18 Reference=0x243f2390 Handle=0x2358b76c ##子指针
Children:
Child: childNum=’0′
L ibraryHandle: Address=0x2358b76c Hash=0 LockMode=0 PinMode=0 LoadLockMode=0 Status=VALD
##子游标LibraryHandle地址Address=0x2358b76c,与x$kglob.KGLHDADR子游标地址相符
Name: Namespace=SQL AREA(00) Type=CURSOR(00)
Statistics: InvalidationCount=0 ExecutionCount=1 LoadCount=1 ActiveLocks=0 TotalLockCount=1 TotalPinCount=2
Counters: BrokenCount=1 RevocablePointer=1 KeepDependency=0 Version=0 BucketInUse=0 HandleInUse=0 HandleReferenceCount=0
Concurrency: DependencyMutex=0x2358b7d4(0, 0, 0, 0) Mutex=0x23d07120(46, 39, 0, 6)
Flags=RON/PIN/PN0/EXP/CHD/[10012111]
WaitersLists:
Lock=0x2358b7c4[0x2358b7c4,0x2358b7c4]
Pin=0x2358b7b4[0x2358b7b4,0x2358b7b4]
LoadLock=0x2358b7f8[0x2358b7f8,0x2358b7f8]
ReferenceList:
Reference: Address=0x243f2390 Handle=0x23d0705c Flags=CHL[02]
LibraryObject: Address=0x23fdd890 HeapMask=0000-0001-0001-0000 Flags=EXS[0000] Flags2=[0000] PublicFlags=[0000]
Dependencies: count=’1′ size=’16’ table=’0x23fde7a4′
Dependency: num=’0′
Reference=0x23fddcb0 Position=18 Flags=DEP[0001]
Handle=0x2433a460 Type=TABLE(02) Parent=BYS.DEPT
ReadOnlyDependencies: count=’1′ size=’16’
ReadDependency: num=’0′ Table=0x23fde7f0 Reference=0x23fddc1c Handle=0x2345e2a8 Flags=DEP/ROD/KPP[61]
Accesses: count=’1′ size=’16’
Dependency: num=’0′ Type=0009
DataBlocks:
Block: #=’0′ name=KGLH0^a8dc75cd pins=0 Change=NONE
Heap=0x2526a068 Pointer=0x23fdd8e4 Extent=0x23fdd84c Flags=I/-/-/A/-/-
#####Heap=0x2526a068子游标堆0的地址,与x$kglob.KGLOBHD0相符
FreedLocation=0 Alloc=1.382812 Size=3.964844 LoadTime=4405191980
Block: #=’6′ name=SQLA^a8dc75cd pins=0 Change=NONE
Heap=0x243f2238 Pointer=0x23fdc624 Extent=0x23fdb84c Flags=I/-/-/A/-/E
##Heap=0x243f2238这个就是子游标堆6的地址,与x$kglob.KGLOBHD6相符
FreedLocation=0 Alloc=3.785156 Size=3.964844 LoadTime=0
NamespaceDump: –子游标信息
Child Cursor: Heap0=0x23fdd8e4 Heap6=0x23fdc624 Heap0 Load Time=01-04-2014 18:03:50 Heap6 Load Time=01-04-2014 18:03:50
NamespaceDump:
Parent Cursor: sql_id=f4yk5kundsxfd parent=0x243f1e1c maxchild=1 plk=n ppn=n
##父游标,sql_id=f4yk5kundsxfd与v$sql.sql_id相符,
###############################################

DUMP SQL语句父子游标的堆0和堆6
SYS@ bys3>select kglhdadr,kglhdpar,kglnaobj,KGLOBHS0,kglobhd0,KGLOBHS6,KGLOBHD6 from x$kglob where kglnaobj like ‘select * from bys.test%’;
KGLHDADR KGLHDPAR KGLNAOBJ KGLOBHS0 KGLOBHD0 KGLOBHS6 KGLOBHD6
——– ——– ————————- ———- ——– ———- ——–
240EDA68 239948A4 select * from bys.test 4348 23B31E80 4060 245908B0
239948A4 239948A4 select * from bys.test 4500 241368BC 0 00

alter session set events ‘immediate trace name heapdump_addr level 2,addr 0x241368BC’; –使用这样的语句把父子游标的堆0、堆6全DUMP出来。

我把三个DUMP文件的开头贴一下:

父游标堆0:desc=字段与x$kglob.KGLOBHD0对应,heap name=”KGLH0^ 堆名字也表明是堆0
******************************************************
HEAP DUMP heap name=”KGLH0^1020848″ desc=0x241368bc
extent sz=0xff4 alt=32767 het=28 rec=9 flg=2 opc=0
parent=0x200010b4 owner=0x24136888 nex=(nil) xsz=0xfe4 heap=(nil)
fl2=0x26, nex=(nil), dsxvers=1, dsxflg=0x0
dsx first ext=0x245903fc
EXTENT 0 addr=0x245903fc
Chunk 24590404 sz= 44 perm “perm ” alo=44
Dump of memory from 0x24590404 to 0x24590430

子游标堆0:–我的版本是11.2.0.4,有的版本DUMP出来的heap name=”CCURSE,,比较直观说明是子游标。。这 里只能通过desc=字段与x$kglob.KGLOBHD6对应

******************************************************
HEAP DUMP heap name=”KGLH0^1020848″ desc=0x23b31e80
extent sz=0xff4 alt=32767 het=28 rec=9 flg=2 opc=0
parent=0x200010b4 owner=0x23b31e4c nex=(nil) xsz=0xfe4 heap=(nil)
fl2=0x26, nex=(nil), dsxvers=1, dsxflg=0x0
dsx first ext=0x240b19c4
EXTENT 0 addr=0x240b19c4
Chunk 240b19cc sz= 44 perm “perm ” alo=44

子游标堆6: –从DUMP名字也可以看出是存放SQL执行计划等的SQL区域。–有的版本DUMP出来这里显示的heapname=”SQL AREA,我这个11.2.0.4版本上看就这样了。。

******************************************************
HEAP DUMP heap name=”SQLA^1020848″ desc=0x245908b0
extent sz=0xff4 alt=32767 het=184 rec=0 flg=2 opc=2
parent=0x200010b4 owner=0x245907e4 nex=(nil) xsz=0xfe4 heap=(nil)
fl2=0x27, nex=(nil), dsxvers=1, dsxflg=0x0
dsx first ext=0x24b12c54
EXTENT 0 addr=0x24b12c54
Chunk 24b12c5c sz= 44 perm “perm ” alo=44

shared pool:library cache结构/library cache object的结构-dump LibraryHandle

近期遭遇了多次客户数据库无法关闭的问题了,数据库无法关闭,一般是关闭时有事务需要回滚(可能是客户端或者JOB等)或者是关闭时使用错误关闭参数(如忘加参数默认是NORMAL)或者关闭时有其它原因。

因此分享一下关闭数据库步骤的脚本,按照此脚本进行关闭数据库,基本上可以回避无法关闭问题;即使遇到无法关闭,使用kill关闭进程来关闭实例,也很少会造成数据损坏或数据丢失。

近期遇到的几次关闭问题及相应MOS链接如下:

http://blog.csdn.net/haibusuanyun/article/details/50285527
关闭数据库遇到SHUTDOWN: Active processes prevent shutdown operation
http://blog.csdn.net/haibusuanyun/article/details/47073459
关闭数据库时SHUTDOWN: waiting for active calls to complete.处理
供参考MOS文档:
Shutdown Immediate Hangs / Active Processes Prevent Shutdown (文档 ID 416658.1)
Alert Log: Shutdown Waiting for Active Calls to Complete (文档 ID 1039389.6)
What Is The Fastest Way To Cleanly Shutdown An Oracle Database? (文档 ID 386408.1)
—————————————–参考步骤如下:
一、应用停掉

二、停监听器
–对应的LOCAL=NO的进程确认是否需要KILL。
ps -ef|grep LOCAL=NO|wc -l
ps -ef|grep LOCAL=NO
lsnrctl stop

三、查看有没有JOB–如有需要确认是否可停掉
ps -ef|grep ora_j

四、查看有没有事务还未提交的–如有事务未提交确认是否需要等待事务完成
sqlplus ‘/ as sysdba’
select status,instance_name,to_char(startup_time,’yyyy/mm/dd hh24:mi:ss’) starttime from gv$instance;
select open_mode,name from v$database;
是否有大的查询在进行
select count(*) from v$transaction;
select count(*) from v$session_longops where time_remaining>0;
是否有大的事务在进行
select sum(used_ublk) from v$transaction; —如果有大量返回,参考本文最后
select START_TIME,STATUS from v$transaction;
是否有大事务正在回滚/需要在数据库OPEN时进行实例恢复
select * from v$fast_start_transactions;
select * from v$fast_start_servers;

五、手工做检查点与手动多次切换log
–确认以上问题解决完后继续:
先做一次检查点,目的是把脏数据写入数据文件,避免造成数据丢失,减小关闭启动不起来这种现象发生
alter system checkpoint;
切换一次日志:
SQL> alter system switch logfile;

再做一次检查点
alter system checkpoint;
再切换一次日志:
SQL> alter system switch logfile;

六、关机-此时关机速度会正常,有效减少HANG住之类问题。

建议执行关闭数据库命令时,重新打开一个会话窗口,重新登陆数据库进行关闭:
SQL> shutdown immediate;

关闭ORACLE数据库步骤参考

近期遇到一客户数据库关闭时遇到无法关闭的情况。
经检查是关闭前使用了sqlplus窗口直接使用host命名回到SHELL操作界面,然后又sqlplus / as sysdba登陆了数据库(具体切换了三、四次);
在之后的发出关闭命令shutdown immediate;后,命令一直HANG住;此时查看ALERT日志,有“SHUTDOWN: Active processes prevent shutdown operation”提示;
一开始以为是有活动会话没有关闭,查询ps -ef|grep LOCAL 和ps -ef|grep ora_j的进程,均无相应进程;也未配置EM–DB CONSOLE之类。

刚开始以为是遇到有活动会话导致的,数据库版本是AIX6.1+11.2.0.1单实例;
因此根据以往经验会提示出哪个进程导致SHUTDOWN无法完成,根据提示进程号进行KILL进程,就会正常关闭。
——————-
==》根据观察,在ORACLE10G及以上版本,会是如下提示:
Active call for process 12345 user ‘oracle’ program ‘oracle@abcd’
SHUTDOWN: waiting for active calls to complete.
也就是指出哪个进程引起的等待,此时kill -9 12345 进程即可。
==》但是在ORACLE 8I版本中,是不会提示哪个进程ACTIVE引起关闭进程HANG的。

在等待的过程中,耽误了10多分钟。后根据alert提示查询,结合之前工程师的操作;
问题可能是sqlplus时host到os下操作,后又sqlplus / as sysdba登陆,如此反复多次。
——-因为在发出shutdown immediate;的命令行窗口命令仍在执行状态,事实上此时可以使用CTRL+C来取消关闭命令。
本次就使用了CTRL+C来取消关闭命令,后一路exit退出,并重新使用TELNET登陆进行关闭操作,正常完成。
############
这里也是一个重要提醒,在发出shutdown immediate;的命令行窗口,最好新建的会话来执行,避免此类问题。
关库前最好将ps -ef|grep LOCAL 和ps -ef|grep ora_j的进程,是否有大事务在进行及大事务回滚在进行等问题进行确认;
确认之后切换日志、执行检查点,再关闭数据库,此时关库风险会小很多,即使遇到无法关闭去KILL进程,也相应更安全。

#################################故障时
1.无法关闭时的alert日志
Sun Dec 13 00:25:15 2015
Shutting down instance (immediate)
Stopping background process SMCO
Shutting down instance: further logons disabled
Sun Dec 13 00:25:17 2015
Stopping background process CJQ0
Stopping background process QMNC
Stopping background process MMNL
Stopping background process MMON
License high water mark = 78
Stopping Job queue slave processes, flags = 7
Job queue slave processes stopped
All dispatchers and shared servers shutdown
Sun Dec 13 00:30:21 2015
SHUTDOWN: Active processes prevent shutdown operation
Sun Dec 13 00:35:23 2015
SHUTDOWN: Active processes prevent shutdown operation
Sun Dec 13 00:40:24 2015
SHUTDOWN: Active processes prevent shutdown operation
Sun Dec 13 00:45:25 2015
SHUTDOWN: Active processes prevent shutdown operation
Sun Dec 13 00:48:31 2015

Instance shutdown cancelled

 

关闭数据库遇到SHUTDOWN: Active processes prevent shutdown operation