--Library Cahce锁挣用
Oracle引入Shared Pool就是为了帮助我们实现代码的共享和重用。
Shared Pool主要由两部分组成,一部分是库缓存(Library Cahce),另一部分是数据字典缓存(Data Dictionary Cache)。Library Cache主要用于存储SQL语句、SQL语句相关的解析树、执行计划、PL/SQL程序块(包括匿名程序块、存储过程、包、函数等)以及它们转换后能够被Oracle执行的代码等,这部分信息可以通过v$librarycache视图查询;至于DataDictionary Cache主要用于存放数据字典信息,包括表、视图等对象的结构信息,用户以及对象权限信息,这部分信息相对稳定,在Shared Pool中通过字典缓存单独存放,字典缓存的内容是按行(Row)存储的(其他数据通常按Buffer存储),所以又被称为Row Cache,其信息可以通过V$ROWCACHE查询。
Shared Pool各个部分协同工作以及与Buffer Cache的配合。如下图1:
从Oracle Database 11g开始,在Shared Pool中划出了另外一块内存用于存储SQL查询的结果集,称为ResultCache Memory。以前Shared Pool的主要功能是共享SQL,减少硬解析,从而?高性能,但是SQL共享之后,执行查询同样可能消耗大量的时间和资源,现在Oracle尝试将查询的结果集缓存起来,如果同一SQL或PL/SQL函数多次执行(特别是包含复杂运算的SQL),那么缓存的查询结果可以直接返回给用户,不需要真正去执行运算,这样就又为性能带来了极大的提升。
结果集缓存(Result Cache)是Oracle Database 11g新引入的功能,除了可以在服务器端缓存结果集(ServerResultCache)之外,还可以在客户端缓存结果集(Client Result Cache)。
服务器端的ResultCache Memory由两部分组成:
(1) SQL Query Result Cache:存储SQL查询的结果集。
(2) PL/SQL Function Result Cache:用于存储PL/SQL函数的结果集。
Oracle通过一个新引入初始化参数result_cache_max_size 来控制该Cache的大小。如果result_cache_max_size=0 则表示禁用该特性。参数result_cache_max_result 则控制单个缓存结果可以占总的ServerResult Cache大小的百分比。
初始地,数据库启动以后,Shared Pool多数是连续内存块。但是当空间分配使用以后,内存块开始被分割,碎片开始出现,Bucket列表开始变长。
Oracle请求Shared Pool空间时,首先进入相应的Bucket进行查找。如果找不到,则转向下一个非空的Bucket,获取第一个Chunk。分割这个Chunk,剩余部分会进入相应的Bucket,进一步增加碎片
最终的结果是,由于不停分割,每个Bucket上的内存块会越来越多,越来越碎小。通常Bucket 0的问题会最为显著,在这个测试数据库上,Bucket 0上的碎片已经达到9030个,而shared_pool_size设置仅为150MB。
通常如果每个Bucket上的Chunk多于2000个,就被认为是Shared Pool碎片过多。Shared Pool的碎片过多,是Shared Pool产生性能问题的主要原因。
碎片过多会导致搜索Free Lists的时间过长,而我们知道,Free Lists的管理和搜索都需要获得和持有一个非常重要的Latch,就 是Shared Pool Latch。Latch是Oracle数据库内部提供的一种低级锁,通过串行机制保护共享内存不被并发更新/修改所损坏。Latch的持有通常都非常短暂(通常微秒级),但是对于一个繁忙的数据库,这个串行机制往往会成为极大的性能瓶颈。
如果Free Lists链表过长,搜索这个Free Lists的时间就会变长,从而可能导致SharedPool Latch被长时间持有,在一个繁忙的系统中,这会引起严重的Shared PoolLatch的竞争。在Oracle 9i之前,这个重要的Shared PoolLatch只有一个,所以长时间持有将会导致严重的性能问题。
Sharedpool和PGA都是由一个Oracle的内存管理器来管理,我们称之为KGH heap manager。Heap Manager不是一个进程,而是一串代码。Heap Manager主要目的就是满足server 进程请求memory 的时候分配内存或者释放内存。Heap Manager在管理PGA的时候,Heap Manager需要和操作系统来打交道来分配或者回收内存。但是呢,在shared pool中,内存是预先分配的,Heap Manager管理所有的空闲内存。当某个进程需要分配shared pool的内存的时候,Heap Manager就满足该请求,Heap Manager也和其他ORACLE模块一起工作来回收shared pool的空闲内存。Library cache Manager 可以看做是Heap Manager的客户端,因为library cache manager是根据Heap Manager来分配内存从而存放library cache objects。Library cache Manager控制所有的library cache object,包括package/procedure, cursor, trigger等等。
Librarycache是由一个hash table组成,这个hash table又由hash bucket组成的数组构成,每个hash bucket又是由一些相互指向的library cache handle所组成,library cache object handle就指向具体的library cache object以及一些引用列表。
图2:
我们对Library cache中所有对象的访问是通过利用library cache handle来实现的,也就是说我们想要访问library cache object,我们必须先找到library cache handle。Library cache handle指向library cache object,它包含了library object的名字,命名空间,时间戳,引用列表,lock对象以及pin对象的列表信息等等。Library cache handle也被library cache用来记录哪个用户在这个这个handle上有lock,或者是哪个用户正在等待获得这个lock。那么这里我们也知道了library cache lock是发生在handle上的。
当一个进程请求library cache object,library cache manager就会应用一个hash 算法,从而得到一个hash值,根据相应的hash值到相应的hash bucket中去寻找。这里的hash算法原理与buffer cache中快速定位block的原理是一样的。如果library cache object在内存中,那么这个library cache handle就会被找到。有时候,当shared pool不够大,library cache handle会保留在内存中,然而library cache heap由于内存不足被age out,这个时候我们请求的object heap就会被重载。最坏的情况下,library cache handle在内存中没有找到,这个时候就必须分配一个新的library cache handle,同时object heap也会被加载到内存中。
LibraryCache Object是由一些独立的heap所组成,前面说了Library cache handle指向Library cache Object,其实handle是指向第一个heap,这个heap 我们就称之为heap 0。Heap 0记录了指向其他heap的指针信息。
如下图3
图4
Library cacheHandle 里保存了lock 和 pin的信息。而且在Librarycache handle和child cursor上都有lock和pin。它们称为library cache lock和library cache pin。
Librarycachelock/pin是用来控制对librarycache object的并发访问的。Lock管理并发,pin管理一致性,lock是针对于librarycache handle,而pin是针对于heap。
当我们想要访问某个librarycache object,我们首先要获得这个指向这个object的handle的lock,获得这个lock之后我们就需要pin住指向这个object的heap。
当我们对包,存储过程,函数,视图进行编译的时候,Oracle就会在这些对象的handle上面首先获得一个librarycache lock,然后再在这些对象的heap上获得pin,这样就能保证在编译的时候其它进程不会来更改这些对象的定义,或者将对象删除。
当一个session对SQL语句进行硬解析的时候,这个session就必须获得librarycache lock,这样其他session就不能够访问或者更改这个SQL所引用的对象。如果这个等待事件花了很长时间,通常表明共享池太小(由于共享池太小,需要搜索free的chunk,或者将某些可以被移出的object page out,这样要花很长时间),当然了,也有可能另外的session正在对object进行修改(比如split分区),而当前session需要引用那个table,那么这种情况下我们必须等另外的session进行完毕。
Library Cache lock有3中模式:
(1)Share(S): 当读取一个library cache object的时候获得
(2)Exclusive(X): 当创建/修改一个library cache object的时候获得
(3)Null(N): 用来确保对象依赖性
比如一个进程想要编译某个视图,那么就会获得一个共享锁,如果我们要create/drop/alter某个对象,那么就会获得exclusive lock。Null锁非常特殊,我们在任何可以执行的对象(cursor,function)上面都拥有NULL锁,我们可以随时打破这个NULL锁,当这个NULL锁被打破了,就表示这个对象被更改了,需要从新编译。
NULL锁主要的目的就是标记某个对象是否有效。比如一个SQL语句在解析的时候获得了NULL锁,如果这个SQL的对象一直在共享池中,那么这个NULL锁就会一直存在下去,当这个SQL语句所引用的表被修改之后,这个NULL锁就被打破了,因为修改这个SQL语句的时候会获得Exclusive锁,由于NULL锁被打破了,下次执行这个SQL的时候就需要重新编译。
Library Cache pin有2种模式:
(1)Share(S): 读取object heap
(2)Exclusive(X):修改object heap
当某个session想要读取object heap,就需要获得一个共享模式的pin,当某个session想要修改object heap,就需要获得排他的pin。当然了在获得pin之前必须获得lock。
在Oracle10gR2中,library cache pin被library cache mutex所取代。
Library cachelatch用来控制对library cache object的并发访问。前面已经提到,我们要访问library cacheobject之前必须获得librarycachelock, lock不是一个原子操作(原子操作就是在操作程中不会被打破的操作,很明显这里的lock可以被打破), Oracle为了保护这个lock,引入了library cache latch机制,也就是说在获得librarycachelock之前,需要先获得library cache latch,当获得library cache lock之后就释放librarycache latch。
如果某个librarycache object没有在内存中,那么这个lock就不能被获取,这个时候需要获得一个librarycache load lock latch,然后再获取一个librarycache load lock,当load lock获得之后就释放library cache load lock latch。
librarycache latch受隐含参数_KGL_LATCH_COUNT的控制,默认值为大于等于系统中CPU个数的最小素数,但是Oracle对其有一个硬性限制,该参数不能大于67。
注意:我们去查询_kgl_latch_count有时候显示为0,这是一个bug。
Oracle利用下面算法来确定library cache object handle是由哪个子latch来保护的:
latch#= mod(bucket#,#latches)
也就是说用哪个子latch去保护某个handle是根据那个handle所在的bucket号,以及总共有多少个子latch来进行hash运算得到的。
Library cache lock/pin是用来控制对library cache object的并发访问的。Lock管理并发,pin管理一致性,lock是针对于library cache handle,而pin是针对于heap。
当我们想要访问某个library cache object,我们首先要获得这个指向这个object的handle的lock,获得这个lock之后我们就需要pin住指向这个object的heap。
当我们对包,存储过程,函数,视图进行编译的时候,Oracle就会在这些对象的handle上面首先获得一个library cache lock,然后再在这些对象的heap上获得pin,这样就能保证在编译的时候其它进程不会来更改这些对象的定义,或者将对象删除。
当一个session对SQL语句进行硬解析的时候,这个session就必须获得library cache lock,这样其他session就不能够访问或者更改这个SQL所引用的对象。如果这个等待事件花了很长时间,通常表明共享池太小(由于共享池太小,需要搜索free的chunk,或者将某些可以被移出的object page out,这样要花很长时间),当然了,也有可能另外的session正在对object进行修改(比如split 分区),而当前session需要引用那个table,那么这种情况下我们必须等另外的session进行完毕。
Library Cache lock有3中模式:
l Share(S): 当读取一个library cache object的时候获得
l Exclusive(X): 当创建/修改一个librarycache object的时候获得
l Null(N): 用来确保对象依赖性
比如一个进程想要编译某个视图,那么就会获得一个共享锁,如果我们要create/drop/alter某个对象,那么就会获得exclusive lock。Null锁非常特殊,我们在任何可以执行的对象(cursor,function)上面都拥有NULL锁,我们可以随时打破这个NULL锁,当这个NULL锁被打破了,就表示这个对象被更改了,需要从新编译。NULL锁主要的目的就是标记某个对象是否有效。比如一个SQL语句在解析的时候获得了NULL 锁,如果这个SQL的对象一直在共享池中,那么这个NULL锁就会一直存在下去,当这个SQL语句所引用的表被修改之后,这个NULL锁就被打破了,因为修改这个SQL语句的时候会获得Exclusive 锁,
由于NULL锁被打破了,下次执行这个SQL的时候就需要从新编译。
Library Cache pin有2种模式:
l Share(S): 读取object heap
l Exclusive(X):修改object heap
Library Cache pin没有什么好说的,当某个session想要读取object heap,就需要获得一个共享模式的pin,当某个session想要修改object heap,就需要获得排他的pin。当然了在获得pin之前必须获得lock。
下面就是一个在Oracle10g RAC环境中的Library cache lock的案例
这个RAC环境有2个节点
Library cache latch用来控制对library cacheobject的并发访问。前面已经提到,我们要访问library cache object之前必须获得library cache lock, lock不是一个原子操作(原子操作就是在操作程中不会被打破的操作,很明显这里的lock可以被打破),Oracle为了保护这个lock,引入了library cache latch机制,也就是说在获得library cache lock之前,需要先获得librarycache latch,当获得library cache lock之后就释放library cache latch。
如果某个library cache object没有在内存中,那么这个lock就不能被获取,这个时候需要获得一个librarycache load lock latch,然后再获取一个library cache load lock,当load lock获得之后就释放librarycache load lock latch。
Library cache latch竞争还有可能是具有高version_count的SQL导致的,某个session去执行一个具有很高version_count的SQL需要pin住child cursor,而由于child cursor过多,在未pin住child cursor之前不会释放librarycache latch,这样当其他session想运行该SQL的时候就会发生library cache latch争用,那么遇到这种情况请检查cursor_sharing参数的设置,另外请查询是否遇到bug,或者由于系统中不同schema出现大量同名的表名,这样请更改设计。
在第二个案例中,由于shared pool设置过小还导致了shared pool latch处于top wait event 中的第二名。Sharedpool latch是用来干嘛的呢?Shared pool latch用来保护共享池的结构,在分配,释放共享池空间的时候就会获得该latch,那么在这个案例中,由于共享池太小,在对一个新的SQL进行硬解析的时候需要老化某些对象,为新对象腾出空间,那么这个释放空间的过程就需要获得shared pool latch。当然了,在进行硬解析,也需要获得一个shared pool latch因为硬解析需要申请分配sharedpool空间,而分配空间的时候就需要获得该latch。
MOS 的文档【122793.1】里说导致librarycache lock通常有2种原因:
(1)A DML operation that is hangingbecause the table which isaccessed is currently undergoing changes (ALTERTABLE). This may take quite along time depending on the size of the table andthe type of the modification(e.g. ALTER TABLE x MODIFY (col1 CHAR(200) on atable with thousands of records)
In this case,V$LOCK will show that the session doing the 'ALTERTABLE' with an exclusive DMLenqueue lock on the table object (LMODE=6, TYPE=TMwhere ID1 is the OBJECT_IDof the table). The waiting session however does notshow up in V$LOCK yet so inan environment with a lot of concurrent sessions theV$LOCK information will beinsufficient to track down the culprit blocking youroperation.
(2)The compilation of package willhang on Library Cache Lock andLibrary Cache Pin if any users are executing aprocedure/function defined in thesame package.
一个实例中的library cache包括了不同类型对象的描述,如:游标,索引,表,视图,过程,等等.这些对象不能在他们被使用的时候改变,他们在被使用的时候会被一种librarylocks and pins的机制锁住.一个会话中,需要使用一个对象,会在该对象上先得到一个librarylock(null, shared or exclusive模式的)这是为了,防止其他会话也访问这个对象(例如:重编译一个包或视图的时候,会加上exclusive类型的锁)或更改对象的定义.
总的来说,librarycache pin和librarycache lock都是用于sharepool的并发控制的。pin和lock都可以看作是一种锁。locks/pins会在SQL语句执行期间一直保持,在结束的时候才释放。Lock锁的等级比pin要高。
每个想使用或修改已经locked/pin的对象的SQL语句,将会等待事件'librarycache pin'或'librarycache lock'直到超时.超时,通常发生在5分钟后,然后SQL语句会出现ORA-4021的错误.如果发现死锁,则会出现ORA-4020错误。
lock主要有三种模式:Null,share(2),Exclusive(3).
在读取访问对象时,通常需要获取Null(空)模式以及share(共享)模式的锁定.
在修改对象时,需要获得Exclusive(排他)锁定.
同样pin有三种模式,Null,shared(2)和exclusive(3).
只读模式时获得共享pin,修改模式获得排他pin.
模式为shared(2)的pin会阻塞任何exclusive(3)的pin请求。
模式为shared(3)的pin也会阻塞任何exclusive(2)的pin请求。
不同的操作会对对象请求不同的lock/pin
1、所有的DDL都会对被处理的对象请求排他类型的lock和pin
2、对视图,过程,包的编译都要请求排他的lock和pin
当要对一个过程或者函数进行编译时,需要在librarycache中pin该对象。在pin该对象以前,需要获得该对象handle的锁定,如果获取失败,就会产生librarycache lock等待。如果成功获取handle的lock,则继续在librarycache中pin该对象,如果pin对象失败,则会产生librarycache pin等待。
如果是存储过程或者函数,可以这样认为:如果存在librarycachelock等待,则一定存在librarycache pin等待;反过来,如果存在librarycache pin等待,不一定会存在librarycache lock等待;
但如果是表引起的,则一般只有librarycache lock等待,则不一定存在librarycache pin。
1、在存储过程或者函数正在运行时被编译。
2、在存储过程或者函数正在运行时被对它们进行授权、或者移除权限等操作。
3、对某个表执行DDL期间,有另外的会话对该表执行DML或者DDL。
4、PL/SQL对象之间存在复杂的依赖性
每个想使用或修改已经locked/pin的对象的SQL语句,将会等待事件'librarycache pin'或'librarycache lock'直到超时.超时,通常发生在5分钟后,然后SQL语句会出现ORA-4021的错误.如果发现死锁,则会出现ORA-4020错误。
在librarycache机制的文章里提到,Librarycache Handle里保存了lock和 pin的信息。而且在Librarycache handle和childcursor上都有lock和pin。它们称为librarycache lock和librarycache pin。
常说的librarycache lock和librarycache pin是enqueue,不是latch,它们是两种DDLlock。意的是,在11gR1之前,Oracle中又存在名为librarycache lock和librarycache pin的latch。
对于这个librarycache lock是不是enqueue,在dbsnake的blog上有讨论。我这里沿用dbsnake的观点:该lock是enqueue来整理这篇blog。
在DSI 405的第二篇里有介绍EnqueueStructures。
1)错误的用户名密码:通过ASH或者SSD/hanganalyze去获取p3进行namespace分析
@$ORACLE_HOME/rdbms/admin/ashrpt.sql
2)正在执行搜集统计信息,这是大家往往会忽略的,一般会看last_ddl_time,却忽略了last_analyzed,
selectowner,object_name,object_type,to_char(last_ddl_time,'yyyy-mm-dd hh24:mi:ss')from dba_objects where object_name='EMP';
selecttable_name,to_char(last_analyzed,'yyyy-mm-dd hh24:mi:ss') from dba_tables wheretable_name='EMP';
3)错误的语句解析(failedparse)
Oracle利用Library cache lock和Library cache pin来实现并发控制,Librarycache lock是在handle上获取的,而Library cache pin则是在data heap上获取。访问对象时,首先必须获取handle上的lock,然后将访问的数据pin在内存中。lock的作用是控制进程间的并发访问,而pin的作用是保证数据一致性,防止数据在访问时被交换出去。
lock和pin的实现类似于enqueue,在每个handle上都有lock和pin的holder list和waiter list,用来保存持有该资源和等待该资源的队列。
现实情况中,我们有一个数据库中存在被应用大量频繁访问的procedure,当依赖的表发生变更时,导致该procedure失效,这时会出现大量的librarycache lock和library cache pin的等待,堵塞应用访问,造成了重大故障。出现这个问题的原因是:当procedure失效后,所有访问该对象的进程都尝试去编译,大量进程尝试获取exclusive类型的lock和pin,出现了大量的等待。后续的Oracle版本作出了改进,当出现这种情况时,只允许第一个进程尝试去编译该对象,编译通过后,所有的进程就可以并发访问,避免了大量进程同时尝试编译的情况出现。
Librarycache中相关的latch包括:shared pool latch,library cahce latch,library cache locklatch,library cache pin latch。
Sharepool latch的主要作用是分配或释放空间时使用,从Oracle9i开始,shared pool被分成了很多个subpool,由多个shared pool latch保护,Oracle开始支持更大的sharedpool。
Librarycache latch的主要作用是在hashbucket中定位handle时使用,library cache lock latch和library cache pin latch分别是获取lock和pin时,需要取得的latch。
sharedpool大小不合理,大量的硬解析以及SQL版本过多都可能导致shared pool latch和library cache latch的争用。
从Oracle10g开始,Oracle正在逐步用mutex取代library cache中的latch,cursor:pin S和cursor:pin X相当于share和exclusive类型的library cache pin,cursor:pin S wait on X则表示share方式正在等待exclusive锁定。
Bothlibrary cache lock and library cache pin are provided to access objects inthelibrary cache. Library cache lock manages concurrency betweenprocesses,whereas library cache pin manages cache coherence. Inorder to accessan object in library cache, a process must first lock thelibrary cache objecthandle, and then pin the object data heap itself. Requestsfor both librarycache lock and library cache pin will wait until granted. Thisis a possiblesource of contention, because there is no NOWAIT request mode.
Byacquiring a library cache lock on the library cache object handle, aprocesscan prevent other processes from accessing the object, or even findingout whattype it is. It can even maintain a dependency on an object withoutpreventingother processes from accessing the object. Acquiring alibrary cachelock is also the only way to locate an object in cache--a processlocates andlocks an object in a single operation.
If the process wants to actually examine or modify theobject, then it mustacquire a library cache pin on the object data heap itself(after acquiring alibrary cache lock on the library cache objecthandle). Pinning the objectcauses information about the object and its dataheaps to be loaded into memoryif they were not already there. This information is guaranteed to remain inmemory at leastuntil the pin is released. Locks and pins areexternalized inX$KGLLK and X$KGLPN, respectively.
5.1 Library cache lock有三种lockmode,分别是share、exclusive和null
Aprocess acquires a share library cache lock if it intends only to readtheobject. For example, it wants toreference the object duringcompilation. A process acquires an exclusivelibrary cache lock if it intends tocreate or modify the object.
Forexample, it wants to drop the object from the database. Null librarycachelocks are a special case. They are acquired on objects that are to beexecutedlike child cursor, procedure, function, package, or type body. You canuse themto maintain an interest on an object for a long period of time(sessionpersistency), and to detect if the object becomes invalid. You canbreak null library cache lock at any time. Thisis used as a mechanism to notifya session that an executable object is nolonger valid. If a null library cachelock is broken,and thus the object is invalidated, then it is an indication tothe user whowas holding the null library cache lock that the object needs to berecompiled.A null library cache lock is acquired during the parse phase ofSQLstatement execution and is held as long as the shared SQL area forthatstatement remains in the shared pool. A null librarycache lock does notprevent any DDL operation, and can be broken to allowconflicting DDLoperations, hence the term "breakable parse lock."A null librarycache lock on an object is broken when there is an exclusivelibrary cache pinon the object.
5.2 Library cache pin有两种lock mode,分别是share和exclusive。
Whena process pins an object data heap that is not in memory, the processcandetermine whether the data heap is to be loaded in the PGA or SGA. An objectmust be pinned in Exclusive mode if it is to bemodified. However, the processfirst will alwayspin the object in Share mode, examine it for errors andsecurity checks, andthen, if necessary, (such as needing modification) pin itin Exclusive mode.An object is never pinned in Exclusive mode if only readaccess is required. Thisis because all dependent transient objects (cursors)are invalidated (nulllocks broken) when an object is unpinned from Exclusive mode.The effect wouldbe unnecessary recompilation and reparsing of all dependentpackages,procedures, and functions.
5.3下面详细解释在修改和访问对象时,lock和pin的作用:
5.3.1修改对象:
编译SQL或PLSQL对象,获取该对象(cursor,procedure)handle上exclusive类型的lock,并且持有data heap上exclusive类型的pin,防止其他人读取和修改。同时,在该对象所依赖的对象(table)上,必须持有一个share类型的lock和pin,防止在修改的过程中,被其他进程所修改。
5.3.2访问对象:
访问SQL或PLSQL对象,获取该对象(cursor,procedure)handle上NULL类型的lock,并且持有data heap上share类型的pin,同时,在其依赖的对象(table)上持有share类型的lock和pin。如果一个procedure依赖另外一个function,那么在被依赖的function上,也需要持有share类型的lock和pin。
NULL类型的lock比较特殊,它只存在于cursor和procedure等只读对象上,它并不起到任何并发控制的作用,它更象是一个trigger,当对象失效时,通知所有访问这个cursor的进程。比如:select* from emp这个SQL,依赖emp表,当emp表发生变化时,cursor上的NULL lock被打破,所有有访问这个cursor的进程都会知道该对象已经失效。
当持有对象的library cache pin时,会在row cache中对相应的对象加锁,就是rowcache lock,阻止可能导致数据字典信息混乱的DDL发生。
这是一个很纠结的问题,既然已经有了作为enqueue的library cache lock和library cache pin,为什么在11gR1以前,Oracle里还有同名latch,而且明显这些同名latch是在被使用:
Connected to Oracle Database 10g EnterpriseEdition Release10.2.0.5.0
Connected as ipra
SQL>selectname,level#,gets,misses,sleeps,immediate_gets,immediate_misses fromv$latchwhere name like 'library%';
NAMELEVEL# GETS MISSES SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES
---------------------------------------------------------------------- ---------- ---------- -------------- ----------------
library cache 5 9221760 1608 800 259676766
library cache lock 6 13548247 5826 0 0
librarycache lock allocation 3 208273 0 0 0 0
library cache pin 6 4207462 1930 2 0
library cache hash chains 9 0 0 0 0 0
librarycache pin allocation 3 57276 0 0 0 0
librarycache load lock 5 24848 0 0 1 0
7 rowsselected
从结果里我们可以看到,对于10.2.0.5而言,Oracle存在7种跟library cache相关的latch,除了library cache hash chains latch之外,其他的跟library cache相关的latch,Oracle都有使用。
那么library cache lock latch、library cache pin latch以及大家最耳熟能详的librarycache latch等等,这些latch是做什么用的呢?也许我们可以从下面的一段文字中找到答案:
The library cache latches serialize access to the objects inthe library cache.Access to library cache objects always occurs throughlibrary cache locks.Because locking an object is not an atomicinstruction, a library cache latch isacquired before the library cache lockrequest and is released after it. Formost operations, the library cachelatches are used, and therefore they canbecome a point of contention.
If an object is not in memory, then a library cachelock cannot be acquired onit. In order to prevent multiple processes torequest the load of the sameobject simultaneously, another latch must beacquired before the load request.This is the librarycache load lock latch. The library cache load lock latch istaken andheld until a library cache load lock is allocated, then the latch isreleased. Loadingof the object is performed under the library cache load lockand not under thelibrary cache load lock latch as it may take quite a longtime.
6.1 几点关注的地方:
(1)Oracle使用上述library cache latches(包括library cache latch、library cache locklatch、library cache pin latch、library cache pin allocation latch、library cache loadlock latch)的目的是控制并发访问library cache object所需要的相关的enqueue或者是为了控制并发访问librarycache中的相关的内存结构,比如用相关的library cache lock latch控制并发获得library cache lock。这里我猜测Oracle用librarycache locklatch控制并发获得library cache lock,用library cache pin latch控制并发获得librarycachepin,用library cache load lock latch控制并发获得library cache loadlock,用library cache latch去控制并发访问librarycacheobject handle中的某些结构,如library cache object handle中的flag中的specialstatus flag (special statusflags are protected by the library cache latch.Examples of these flags indicatethat: The object is valid; The object isauthorized; The object has compilationerrors)。
(2)Librarycache load lock是另外一种enqueue。The session tries to find the librarycacheload lock for the database object so that it can load the object. Thelibrary cache load lock is always obtained in Exclusivemode, so that no otherprocess can load the same object. If the librarycache load lock is busy thesession will wait on this event until the lockbecomes available.
好了,现在我们来验证一下,还是上述10.2.0.5的环境,我将上述sql(selectname,level#,gets,misses,sleeps,immediate_gets,immediate_missesfrom v$latchwhere name like 'library%')马上再执行一遍,这是软解析,必然要获得library cache lock,不需要获得librarycache load lock,所以对应的latch应该表现为librarycache lock latch的gets增加,library cache load lock latch的gets不变:
SQL>selectname,level#,gets,misses,sleeps,immediate_gets,immediate_misses fromv$latchwhere name like 'library%';
NAMELEVEL# GETS MISSES SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES
---------------------------------------------------------------------- ---------- ---------- -------------- ----------------
librarycache 5 9222166 1608 800 2596 76766
library cache lock 6 13548760 5826 0 0
librarycache lock allocation 3 208287 0 0 0 0
library cache pin 6 4207656193 0 2 0
librarycache hash chains 9 0 0 0 0 0
librarycache pin allocation 3 57278 0 0 0 0
library cache load lock 5 248480 0 1 0
7 rowsselected
从结果里我们可以看到,library cache lock latch的gets从13548247递增到了13548760,library cache pin latch的gets从4207462递增到了4207656,但library cache loadlock latch的gets还是保持24848不变。
现在我们来让library cache load lock latch的gets发生变化,这是非常容易的事情,我们只需要执行一个需要硬解析的sql就可以了:
SQL> select * from scott.emp_temp;
EMPNO ENAME JOB MGR HIREDATE SAL COMMDEPTNO ISINSPECT
----- ---------- --------- ---------------- --------- --------------- ----------
SQL>selectname,level#,gets,misses,sleeps,immediate_gets,immediate_misses fromv$latchwhere name like 'library%';
NAMELEVEL# GETS MISSES SLEEPS IMMEDIATE_GETS IMMEDIATE_MISSES
---------------------------------------------------------------------- ---------- ---------- -------------- ----------------
librarycache 5 9223549 1608 800 2596 76766
librarycache lock 6 13550296 582 6 0 0
librarycache lock allocation 3 208348 0 0 0 0
librarycache pin 6 4208118 193 0 2 0
librarycache hash chains 9 0 0 0 0 0
librarycache pin allocation 3 57294 0 0 0 0
library cache load lock 5 248560 0 1 0
7 rowsselected
由于我们执行了一个需要硬解析的sql,导致Oracle需要获得library cache load lock以便load相关信息到这个sql的子cursor的heap 6中,而要获得librarycache load lock,必须先持有library cache load lock latch。从上述结果中我们可以看到,此时library cache loadlocklatch的gets已经发生了变化,从24848递增到了24856。
接下来我们再来看一看上述librarycachelatches的子latch情况:
SQL> show parameter cpu_count
NAME TYPE VALUE
-----------------------------------------------------------------------------
cpu_count integer 2
这里cpu的个数为2,显然上述library cachelatches的子latch应该为3:
SQL> select name,level#,gets,misses,sleeps,immediate_gets,immediate_missesfromv$latch_children where name like 'library%';
NAME LEVEL# GETS MISSES SLEEPSIMMEDIATE_GETS IMMEDIATE_MISSES
---------------------------------------------------------------------- ---------- ---------- -------------- ----------------
library cache 5 3274551 1301 94 187 0
library cache 5 2218356 116 80 933 0
library cache 5 3731320 191 626 1476 76766
library cache lock 6 5339737 362 3 0 0
library cache lock 6 6223353 194 3 0 0
library cache lock 6 1987799 26 0 0 0
library cache pin 6 1484918 184 0 0 0
library cache pin 6 891695 3 0 2 0
library cache pin 6 1831837 6 0 0 0
library cache pin allocation 3 23177 0 0 00
library cache pin allocation 3 8272 0 0 0 0
library cache pin allocation 3 25849 0 0 00
library cache lock allocation 3 75900 0 0 00
library cache lock allocation 3 28229 0 0 00
library cache lock allocation 3 104237 0 00 0
library cache hash chains 9 0 0 0 0 0
library cache hash chains 9 0 0 0 0 0
library cache hash chains 9 0 0 0 0 0
18 rows selected
注意,结果里并没有library cache load lock latch,说明library cache load locklatch没有children,它是一个solitary类型的latch。
6.2 Mutex 说明
从10.2.0.2开始,Oracle将_kks_use_mutex_pin的默认值改成了true,这意味着从10.2.0.2开始,Oracle里将再不会有针对cursor的librarycache pin等待,取而代之的是mutex等待,具体表现为cursor:pin *等待,如cursor: pin S wait on X。
这里需要我们了解的是:
(1)从10.2.0.2开始,Oracle只是用mutex替代了针对cursor的librarycache pin,这并不代表从10.2.0.2开始Oracle里就没有librarycache pin等待了。比如这个例子里的library cache pin等待就发生在10.2.0.4中:http://dbsnake.com/2010/06/solve-library-cache-pin.html
(2)Mutex和latch是互相独立,没有任何关系的:Latches and mutexes are independent mechanisms i.e. a processcanhold a latch and a mutex at the same time. In the case of processdeath,latches are always cleaned up before mutexes. There is no genericmutexdeadlock detection (unlike latches). There is no mutex/latch hierarchy.
从11gR1开始,Oracle用mutex替换了librarycache latches,并引了一个新的等待事件:librarycache: mutex *,我们来看一下这个知识点:
Connected to Oracle Database 11g EnterpriseEdition Release11.2.0.1.0
Connected as nbs
SQL>selectname,level#,gets,misses,sleeps,immediate_gets,immediate_misses fromv$latchwhere name like 'library%';
NAME LEVEL# GETS MISSES SLEEPSIMMEDIATE_GETS IMMEDIATE_MISSES
------------------------------------------------------------------------------------ ---------- ---------- -------------- ----------------
library cache load lock 5 0 0 0 0 0
SQL> selectname,level#,gets,misses,sleeps,immediate_gets,immediate_missesfromv$latch_children where name like 'library%';
NAME LEVEL# GETS MISSES SLEEPSIMMEDIATE_GETS IMMEDIATE_MISSES
------------------------------------------------------------------------------------ ---------- ---------- -------------- ----------------
从结果里我们可以看到,在11.2.0.1里,各种library cache latches都没有了,只剩下了library cache loadlocklatch,而且Oracle还没有使用这个latch,因为gets是0。
在这部分主要说明如下结论:
1、针对cursor的library cachelock的lock mode确实是null,无论该cursor所对应的sql是硬解析还是软解析;
2、 MOS上说Oracle说从10.2.0.2以后,会用mutex取代针对cursor的library cache pin,但我的测试结果是在10.2.0.5中,虽然在sql的软解析时确实已经不存在librarycache pin了,但如果是硬解析,则依然存在library cache pin;
3、 sql的软解析时,library cache pin的lock mode始终是S;
4、 sql的硬解析时,library cache pin的lock mode一般是X,但在10.2.0.1中,即使是硬解析,也存在lockmode为S的library cache pin。
这里测试所采用的方法就是event 10049,这个事件在10gR2以后,专门被用来trace librarycache lock和library cache pin。但好多朋友不太会用这个事件,我这里以一个实例的方式介绍了如何用10049事件来trace单个sql的library cache lock和library cache pin。
Connected to Oracle Database 10g EnterpriseEdition Release10.2.0.1.0
Connected as SYS
10.2.0.1中_kks_use_mutex_pin的值为false,表示Oracle不会用mutex取代针对cursor的library cache pin:
SQL> select name,value,description from sys.all_parameterswherename like '_kks%';
NAME VALUE DESCRIPTION
------------------------------------------------------------------------------------------
_kks_use_mutex_pin FALSE Turning on thiswill make KKS use mutexfor cursor pins.
注意这里的all_parameters是自己创建的视图。主要是为了方便查看隐含参数。
/* Formatted on2011/7/28 15:01:16 (QP5v5.163.1008.3004) */
CREATE VIEW all_parameters
AS
SELECT i.ksppinm name,
i.ksppdesc description,
CV.ksppstvl VALUE,
CV.ksppstdf isdefault,
DECODE (BITAND (CV.ksppstvf, 7),
1, 'MODIFIED',
4, 'SYSTEM_MOD',
'FALSE')
ismodified,
DECODE (BITAND (CV.ksppstvf, 2), 2, 'TRUE', 'FALSE') isadjusted
FROM sys.x$ksppi i,sys.x$ksppcv CV
WHERE i.inst_id = USERENV ('Instance')
AND CV.inst_id = USERENV ('Instance')
AND i.indx = CV.indx
AND i.ksppinm LIKE '/_%' ESCAPE '/'
ORDER BY REPLACE (i.ksppinm, '_', '');
Oracle参数分类和参数的查看方法
http://blog.csdn.net/tianlesoftware/article/details/5583655
SQL> select * from scott.emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMMDEPTNO
----- ---------- --------- ---------------- --------- ---------------
7981 CUIHUA 7981
7369 SMITH CLERK 7902 1980-12-17 800.00 20
7499 ALLEN SALESMAN 7698 1981-2-20 1600.00300.00 30
......省略显示部分内容
7800 JAME3 CLERK 7698 1981-12-3 950.00 30
13 rows selected
SQL> select hash_value,sql_text fromv$sqlarea where sql_textlike 'select * from scott.emp%';
HASH_VALUE SQL_TEXT
------------------------------------------------------------------------------------------
52404428 select * from scott.emp
SQL> select to_char(52404428,'XXXXXXXX')from dual;
TO_CHAR(52404428,'XXXXXXXX')
----------------------------
31FA0CC
现在我们要来trace针对上述sql的library cache pin和library cache lock,方法我之前已经说了,就是用event10049,用10049的难点在于如何确定level。
确定10049针对单个sql的level值的算法如下:
首先,10049的level可能会有如下一些值:
#define KGLTRCLCK 0x0010/* trace lock operations */
#define KGLTRCPIN 0x0020/* trace pin operations */
#define KGLTRCOBF 0x0040 /* trace objectfreeing */
#define KGLTRCINV 0x0080 /* traceinvalidations */
#define KGLDMPSTK 0x0100 /* DUMP CALL STACKWITH TRACE */
#define KGLDMPOBJ 0x0200 /* DUMP KGL OBJECTWITH TRACE */
#define KGLDMPENQ 0x0400 /* DUMP KGL ENQUEUE WITH TRACE */
#define KGLTRCHSH 0x2000/* DUMP BY HASH VALUE */
其次,我们是要针对单个sql,所以需要用到这个sql的hash value,以便将10049和这个sql联系起来,即我们一定要用到KGLTRCHSH,也就是0x2000;
另外我们是要tracelibrarycache lock和library cache pin,所以我们一定要用到KGLTRCLCK和KGLTRCPIN,即0x0010和0x0020;
最后就是我们需要把这个sql的hash value的16进制的后两个byte拿出来,作为10049的level的前缀。
从上面结果中我们可以看到,select * from scott.emp的hash value的16进制的后两个byte是0xA0CC。
另外KGLTRCHSH | KGLTRCLCK | KGLTRCPIN= 0x2000 | 0x0010 | 0x0020 = 0x2030。按照上述算法,select * from scott.emp的10049的最终level值就是0xa0cc2030,也就是2697732144:
SQL> selectto_number('a0cc2030','XXXXXXXXXXXX') from dual;
TO_NUMBER('A0CC2030','XXXXXXXX
------------------------------
2697732144
现在我们设置好10049后再执行一遍上述sql,以观察10.2.0.1下sql的软解析时library cache pin和library cache lock:
SQL> oradebug setmypid
已处理的语句
SQL> oradebug event10049 trace name context forever,level2697732144
已处理的语句
SQL> select * from scott.emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMMDEPTNO
----- ---------- --------- ---------------- --------- ---------------
7981 CUIHUA 7981
7369 SMITH CLERK 7902 1980-12-17 800.00 20
7499 ALLEN SALESMAN 7698 1981-2-20 1600.00300.00 30
......省略显示部分内容
7800 JAME3 CLERK 7698 1981-12-3 950.00 30
13 rows selected
SQL> oradebug tracefile_name
d:\oracle\admin\cuihua\udump\cuihua_ora_5808.trc
相应的trace文件(d:\oracle\admin\cuihua\udump\cuihua_ora_5808.trc)的内容为:
*** 2011-06-01 11:59:35.500
KGLTRCLCK kglget hd = 0x33938118 KGL Lock addr = 0x3174A99C mode= N
KGLTRCLCK kglget hd = 0x33938034 KGL Lock addr = 0x31716F50 mode= N
KGLTRCPIN kglpin hd = 0x33938034 KGL Pinaddr = 0x31718A28 mode =S
KGLTRCPIN kglpndl hd = 0x33938034 KGL Pinaddr = 0x31718A28 mode= S
KGLTRCLCK kgllkdl hd = 0x33938034 KGL Lockaddr = 0x31716F50 mode= N
KGLTRCLCK kgllkdl hd = 0x33938118 KGL Lockaddr = 0x3174A99C mode= N
hd = 0x33938118所对应的library cache object的name就是select * from scott.emp:
SQL> select sql_text from v$sqlareawhere address='33938118';
SQL_TEXT
--------------------------------------------------------------------------------
select * from scott.emp
hd = 0x33938034就是hd = 0x33938118的child cursor:
SQL> select kglhdadr,kglhdpar,kglnaobjfrom x$kglob wherekglhdadr='33938034';
KGLHDADR KGLHDPAR KGLNAOBJ
------------------------------------------------------------------------------------------------
33938034 33938118 select * from scott.emp
从上述trace文件中我们可以得出如下结论:
1、10.2.0.1中,sql软解析时,针对cursor的library cachelock的lock mode确实是null;
2、10.2.0.1中,sql软解析时,针对cursor的library cachepin的lock mode确实是S;
现在我们来观察10.2.0.1下sql的硬解析时librarycache pin和library cache lock:
SQL> shutdown immediate
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL> startup
ORACLE 例程已经启动。
Total System Global Area 608174080 bytes
Fixed Size 1250404 bytes
Variable Size 318770076 bytes
Database Buffers 281018368 bytes
Redo Buffers 7135232 bytes
数据库装载完毕。
数据库已经打开。
SQL> select hash_value,sql_text fromv$sqlarea where sql_textlike 'select * from scott.emp%';
HASH_VALUE SQL_TEXT
------------------------------------------------------------------------------------------
SQL> oradebug setmypid
已处理的语句
SQL> oradebug event 10049 trace namecontext forever,level2697732144
已处理的语句
SQL> select * from scott.emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMMDEPTNO
----- ---------- --------- ---------------- --------- ---------------
7981 CUIHUA 7981
7369 SMITH CLERK 7902 1980-12-17 800.00 20
7499 ALLEN SALESMAN 7698 1981-2-20 1600.00300.00 30
......省略显示部分内容
7800 JAME3 CLERK 7698 1981-12-3 950.00 30
13 rows selected
SQL> oradebug tracefile_name
d:\oracle\admin\cuihua\udump\cuihua_ora_5016.trc
相应的trace文件(d:\oracle\admin\cuihua\udump\cuihua_ora_5016.trc)的内容为:
KGLTRCLCK kglget hd = 0x206ECF90 KGL Lock addr = 0x3174E068 mode= N
KGLTRCPIN kglpin hd = 0x206ECF90 KGL Pinaddr = 0x317187C0 mode =X
KGLTRCPIN kglpndl hd = 0x206ECF90 KGL Pinaddr = 0x317187C0 mode= X
KGLTRCLCK kglget hd = 0x33B19238 KGL Lock addr = 0x3174E618 mode= N
KGLTRCPIN kglpin hd = 0x33B19238 KGL Pinaddr = 0x31717F28 mode =X
KGLTRCPIN kglpndl hd =0x33B19238 KGL Pin addr = 0x31717F28 mode= S
KGLTRCLCK kgllkdl hd = 0x33B19238 KGL Lockaddr = 0x3174E618 mode= N
KGLTRCLCK kgllkdl hd = 0x206ECF90 KGL Lockaddr = 0x3174E068 mode= N
SQL> select kglhdadr,kglhdpar,kglnaobjfrom x$kglob wherekglhdadr='33B19238';
KGLHDADR KGLHDPAR KGLNAOBJ
------------------------------------------------------------------------------------------------
33B19238 206ECF90 select * from scott.emp
从上述trace文件中我们可以得出如下结论:
1、10.2.0.1中,sql硬解析时,针对cursor的library cachelock的lock mode依然是null;
2、10.2.0.1中,sql硬解析时,针对cursor的library cachepin的lock mode一般是X,但也存在lock mode为S的library cachepin,且这个S是针对子cursor的。
Connected to Oracle Database 10g EnterpriseEdition Release10.2.0.5.0
Connected as SYS
MOS上说:从10.2.0.2开始,Oracle将_kks_use_mutex_pin的默认值改成了true,表明Oracle将用mutex替代针对cursor的library cache pin。但实际情况并不完全是这样,详情见后面的测试:
SQL> select name,value,description fromsys.all_parameterswhere name like '_kks%';
NAME VALUE DESCRIPTION
------------------------------------------------------------------------------------------
_kks_use_mutex_pin TRUE Turning on thiswill make KKS use mutexfor cursor pins.
SQL> select * from scott.emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMMDEPTNO
---------- ---------- --------- ------------------- -------------------- ----------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 30030
......省略显示部分内容
7934 MILLER CLERK 7782 23-JAN-82 1300 10
14 rows selected.
SQL> select hash_value,sql_text fromv$sqlarea where sql_textlike 'select * from scott.emp%';
HASH_VALUE SQL_TEXT
---------- --------------------------------
52404428 select * from scott.emp
SQL> oradebug setmypid
Statement processed.
SQL> oradebug event 10049 trace namecontext forever,level2697732144
Statement processed.
SQL> select * from scott.emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMMDEPTNO
---------- ---------- --------- ------------------- -------------------- ----------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 30030
......省略显示部分内容
7934 MILLER CLERK 7782 23-JAN-82 1300 10
14 rows selected.
SQL> oradebug tracefile_name
/u01/app/oracle/admin/testdb/udump/testdb_ora_1237156.trc
$ cat/u01/app/oracle/admin/testdb/udump/testdb_ora_1237156.trc
/u01/app/oracle/admin/testdb/udump/testdb_ora_1237156.trc
Oracle Database 10g Enterprise EditionRelease 10.2.0.5.0 - 64bitProduction
With the Partitioning, OLAP, Data Miningand Real ApplicationTesting options
ORACLE_HOME = /u01/app/oracle/product/10.2.0
System name: AIX
Node name: P550_03_LD
Release: 3
Version: 5
Machine: 0001DA17D600
Instance name: testdb
Redo thread mounted by this instance: 1
Oracle process number: 15
Unix process pid: 1237156, image:oracle@P550_03_LD (TNS V1-V3)
*** 2011-06-01 13:38:07.949
*** ACTION NAME:() 2011-06-01 13:38:07.944
*** MODULE NAME:(sqlplus@P550_03_LD (TNSV1-V3)) 2011-06-0113:38:07.944
*** SERVICE NAME:(SYS$USERS) 2011-06-0113:38:07.944
*** SESSION ID:(146.3) 2011-06-0113:38:07.944
KGLTRCLCK kgllkal hd= 0x700000022595c38 KGL Lock addr =0x70000001f724d78 mode = N
KGLTRCLCK kglget hd = 0x700000022595c38 KGLLock addr =0x70000001f724d78 mode = N
KGLTRCLCK kgllkal hd= 0x7000000226ec4f8 KGL Lock addr =0x70000001f74e128 mode = N
KGLTRCLCK kgllkdl hd = 0x7000000226ec4f8KGL Lock addr =0x70000001f74e128 mode = N
KGLTRCLCK kgllkdl2 hd = 0x7000000226ec4f8KGL Lock addr =0x70000001f74e128 mode = 0
KGLTRCLCK kgllkdl hd = 0x700000022595c38KGL Lock addr =0x70000001f724d78 mode = N
KGLTRCLCK kgllkdl2 hd = 0x700000022595c38KGL Lock addr =0x70000001f724d78 mode = 0
这里mode=0应该是表示调用kgllkdl2所产生的library cache lock在调用完上述方法后已经释放了。
SQL> select kglhdadr,kglhdpar,kglnaobjfrom x$kglob wherelower(kglhdadr)='07000000226ec4f8';
KGLHDADR KGLHDPAR KGLNAOBJ
----------------------------------------------------------------------------------------------------------------
07000000226EC4F80700000022595C38 select * from scott.emp
从上述trace文件中我们可以得出如下结论:
10.2.0.5中,sql软解析时,针对cursor的librarycache pin确实已经不存在;
现在我们来观察10.2.0.5下sql的硬解析时librarycache pin和library cache lock:
$ sqlplus '/ as sysdba';
SQL*Plus: Release 10.2.0.5.0 - Productionon Wed Jun 1 13:42:112011
Copyright (c) 1982, 2010, Oracle. AllRights Reserved.
Connected to:
Oracle Database 10g Enterprise EditionRelease 10.2.0.5.0 - 64bitProduction
With the Partitioning, OLAP, Data Miningand Real ApplicationTesting options
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.
Total System Global Area 314572800 bytes
Fixed Size 2096032 bytes
Variable Size 96470112 bytes
Database Buffers 209715200 bytes
Redo Buffers 6291456 bytes
Database mounted.
Database opened.
SQL> oradebug setmypid
Statement processed.
SQL> oradebug event 10049 trace namecontext forever,level2697732144
Statement processed.
SQL> select * from scott.emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMMDEPTNO
---------- ---------- --------- ------------------- -------------------- ----------
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 30030
......省略显示部分内容
7934 MILLER CLERK 7782 23-JAN-82 1300 10
14 rows selected.
SQL> oradebug tracefile_name
/u01/app/oracle/admin/testdb/udump/testdb_ora_1536246.trc
$ cat/u01/app/oracle/admin/testdb/udump/testdb_ora_1536246.trc
/u01/app/oracle/admin/testdb/udump/testdb_ora_1536246.trc
Oracle Database 10g Enterprise EditionRelease 10.2.0.5.0 - 64bitProduction
With the Partitioning, OLAP, Data Miningand Real ApplicationTesting options
ORACLE_HOME =/u01/app/oracle/product/10.2.0
System name: AIX
Node name: P550_03_LD
Release: 3
Version: 5
Machine: 0001DA17D600
Instance name: testdb
Redo thread mounted by this instance: 1
Oracle process number: 15
Unix process pid: 1536246, image:oracle@P550_03_LD (TNS V1-V3)
*** ACTION NAME:() 2011-06-01 13:42:44.913
*** MODULE NAME:(sqlplus@P550_03_LD (TNSV1-V3)) 2011-06-0113:42:44.913
*** SERVICE NAME:(SYS$USERS) 2011-06-0113:42:44.913
*** SESSION ID:(159.3) 2011-06-0113:42:44.913
DBRM(kskinitrm) cpu_count : old(0) ->new(2)
kwqmnich: current time:: 5: 42: 44
kwqmnich: instance no 0 check_only flag 1
kwqmnich: initialized job cache structure
*** 2011-06-01 13:44:13.657
KGLTRCLCK kgllkal hd= 0x7000000225ccfa8 KGL Lock addr =0x70000001f725560 mode = N
KGLTRCLCK kglget hd = 0x7000000225ccfa8 KGLLock addr =0x70000001f725560 mode = N
KGLTRCPIN kglpin hd = 0x7000000225ccfa8 KGL Pin addr =0x70000001f726378 mode= X
KGLTRCPIN kglpndl hd = 0x7000000225ccfa8 KGL Pin addr =0x70000001f726378mode = X
KGLTRCLCK kgllkal hd= 0x7000000225abf18 KGL Lock addr =0x70000001f733120 mode = N
KGLTRCLCK kglget hd = 0x7000000225abf18 KGLLock addr =0x70000001f733120 mode = N
KGLTRCPIN kglpin hd = 0x7000000225abf18 KGL Pin addr =0x70000001f726840 mode= X
KGLTRCPIN kglpndl hd = 0x7000000225abf18 KGL Pin addr =0x70000001f726840mode = X
KGLTRCLCK kgllkdl hd = 0x7000000225abf18KGL Lock addr =0x70000001f733120 mode = N
KGLTRCLCK kgllkdl2 hd = 0x7000000225abf18KGL Lock addr =0x70000001f733120 mode = 0
KGLTRCLCK kgllkdl hd = 0x7000000225ccfa8KGL Lock addr =0x70000001f725560 mode = N
KGLTRCLCK kgllkdl2 hd = 0x7000000225ccfa8KGL Lock addr =0x70000001f725560 mode = 0
SQL> select kglhdadr,kglhdpar,kglnaobjfrom x$kglob wherelower(kglhdadr)='07000000225abf18';
KGLHDADR KGLHDPAR KGLNAOBJ
----------------------------------------------------------------------------------------------------------------
07000000225ABF1807000000225CCFA8 select * from scott.emp
从上述trace文件中我们可以得出如下结论:
1、10.2.0.5中,sql硬解析时,依然存在library cache pin;
2、10.2.0.5中,sql硬解析时,针对cursor的library cachepin的lock mode始终是X;
LibraryCache是OracleSGA中Sharedpool的组成部分。Shared Pool的说明,参考之前的blog:
Oracle Shared pool详解
http://blog.csdn.net/tianlesoftware/article/details/6560956
这里重点看一下Library Cache的一个管理机制。参考了如下2篇blog,重新进行了整理:
Librarycache内部机制详解
http://www.hellodb.net/2010/07/oracle-library-cache.html
Oracle中执行计划的存储位置
http://dbsnake.com/2011/05/exe-plan-stor-location.html
(1)An area in theshared pool thatmanages information about:
--Sharedcursors (SQL and PL/SQL objects)
--Databaseobjects (tables, indexes, and so on)
(2)Initially createdto manage PL/SQLprograms and library units, therefore called library cache
(3)Scope was extendedto includeshared cursors and information about other RDBMS objects.
(1)The units ofinformation that arestored in the library cache are called objects.
(2)There are twoclasses of objects:
1)Stored objects
--Createdand dropped withexplicit SQL or PL/SQL commands
Examples:Tables, views, packages,functions
2)Transient objects
--Created atexecution time and liveonly for the duration of theinstance(or aged out)
Example:Shared and nonsharedcursors
(1)In-memoryrepresentation of anexecutable object:
SQLstatements
AnonymousPL/SQL block
PL/SQLstored procedures or functions
Javastored procedures
ObjectMethods
(2)Represented by twoor more objects:
Aparent cursor that has a name
Oneor more child cursors containing the execution plan
(1)The library cacheis a hash tablethat is accessible through an array of hash buckets.
(2)The library cachemanager (KGL)controls the access and usage of library cache objects.
(3)Memory for thelibrary cache isallocated from the shared pool.
(1).快速定位的问题:Library cache中对象众多,Oracle如何管理这些对象,以便服务进程可以迅速找到他们需要的信息。比如某个服务进程需要迅速定位某个SQL是否存在于Librarycache中。
(2).关系依赖的问题:Library cache中的对象存在复杂的依赖关系,当某个objec失效时,可以迅速将依赖其的对象也置为失效状态。比如某个表发生了结构变化,依赖其的SQL语句需要重新解析。
(3).并发控制的问题:Library cache中必须有一个并发控制的机构,比如锁机制,来管理大量共享对象的并发访问和修改的问题,比如某个SQL在重新编译的同时,其所依赖的对象不能被修改。
Oracle利用hash table结构来解决library cache中快速定位的问题,hash table就是很多hash bucket组成的数组。先看DSI 405里有几张相关的图片如上图4.
LibraryCache保存了explicitSQL, PL/SQLcommands,shared和 nonshared cursors。这些对象都保存在Hash table里,Hash table又由Hash Bucket组成。 Hash Bucket由一些Object Handle List组成,所以在Hash Bucket里查找某个对象,就是搜索这个HandleList。
6. Object Handle
在上图我们可以看到Object handle保存的信息。 Library cache handle指向library cache object(LCO, heap 0),它包含了library object的名字,命名空间,时间
戳,引用列表,lock对象以及pin对象的列表信息等等。
关于Namespace,参考我的blog:
Oracle Namespace说明
http://blog.csdn.net/tianlesoftware/article/details/6624122
所以对Library cache中所有对象的访问是通过利用library cache handle来实现的,也就是说我们想要访问library cache object,我们必须先找到librarycache handle。
因为Object handle保存了lock和pin的信息,即记录哪个用户在这个这个handle上有lock,或者是哪个用户正在等待获得这个lock。那么这里我们也知道了library cache lock是发生在handle上的。
当一个进程请求library cache object, librarycache manager就会应用一个hash 算法,从而得到一个hash值,根据相应的hash值到相应的hash bucket中去寻找。
如果library cache object在内存中,那么这个library cache handle就会被找到。有时候,当sharedpool不够大,library cache handle会保留在内存中,然而library cache heap由于内存不足被ageout,这个时候我们请求的object heap就会被重载。最坏的情况下,library cache handle在内存中没有找到,这个时候就必须分配一个新的library cachehandle,同时object heap也会被加载到内存中。
7. Library Cache Object(LCO: Heap 0)
它的结构信息如下图。这个图需要认真的去理解。
如下图5
DSI 的说明:
(1)Internally, most ofthe objectidentity is represented by structures of type kglob.
(2)These arethestructures stored in heap 0.
(3)Object structureshave thefollowing components:
Type
Name
Flags
Tables
Datablocks
LibraryCache存储SQL或者shared cursors等。这些信息就是通过Heap0这个LCO来保存的。
(1)Objects aregroupedin namespaces according to their type.
(2)Each object canonly be of onetype.
(3)All the objects ofthe same typeare in the same namespace.
(4)A namespace may beused by morethan one type.
(5)The most importantnamespace iscalled cursor (CRSR) and houses the shared SQL cursors.
(1)Library cacheobject names havethree parts:
Nameof schema
Nameof object
Nameof database link (remote objects only)
(2)The format usedisSCHEMA.NAME@DBLINK.
Forexample, [email protected]
(1)Public flags:
Arenot protected by pins or latches
Indicatein detail the type of the object
(2)Status flags:
Areprotected by pins
Indicatewhether the object is being created/dropped/altered/updated
(3)Special statusflags:
Areprotected by the library cache latch
Arerelated to object validity and authorization
(1)Dependency table
(2)Child table
(3)Translation table
(4)Authorization table
(5)Access table
(6)Read-onlydependency table
(7)Schema name table
Object Table 又分为以上7中类型。
指向本对象所依赖的对象,比如:select * from emp这个cursor的对象,依赖emp这个表,这里指向了emp这个表的handle。
指向本对象的子对象,比如某个游标的子游标。通俗点说,就是一条SQL至少有一个parent cursor和 child cursor。可能一些SQL由于某些原因无法共享childcursor,这样就会出现一个parentcursor和多个child cursor的情况。即version count很高。那么这种情况下。parent cursor里对应的所有childcursor的指针都会保存在child table里面。 Oracle是用C写的,所以这里是指针。
注意一点,parent cursor和child cursor都是用library cache object handle 存储在Library Cache里的。即他们的结构完全一样。
这个结论可以通过library cache的dump文件来证明。在后面我们会做一个测试。
Oracle高Version counts问题说明
http://blog.csdn.net/tianlesoftware/article/details/6628232
对象的授权信息。
7.5 Object Data Blocks
(1)The remainder ofanobject’s data is stored in other independent data heaps.
(2)The objectstructure contains anarray of data block structures.
(3)The datablockstructures have a pointer to a different data heap.
(4)An object structurehas room for 16data block structures but not all of them are in use.
Heap0 也仅仅保存是一个结构,它不保存实际的data。而实际data的存储Heap的指针就存放在这个DataBlocks里。这个也可以通过dump来查看。这个Data Blocks指向的Heap结构如下图:
如下图6
这里要注意的,就是我们SQL的执行计划就是存放在这个Heap 6:SQL Context 中。
Oracle SGA是oracle的内存结构,存放着oracle通过oracle进程读写的内存数据。sga分为好多组件,比如shared pool,buffer cache,redo log buffer等等。shared pool又分为library cache,datadictionary cache.
library cache是存sql语句及其分析结果的内存结构
data dictionary cache是存放数据字典的内存结构
buffer cache存的就是数据。
在上面的说明中,提到,对于多child cursor,所有的child cursor都保存在child table里,并且SQL的执行计划也保存在child cursor的Heap 6中。下面进行相关的测试,证明以上结论。
SYS@anqing1(rac1)> create table lct asselect * fromdba_objects;
Table created.
分别用SYSTEM和Dave用户执行如下SQL:
/* Formatted on 2011/7/24 15:07:20(QP5v5.163.1008.3004) */
DECLARE
x VARCHAR2 (20);
str VARCHAR2 (200);
BEGIN
x := 'I_PROXY_ROLE_DATA$_1';
str := 'select* from sys.lct where object_name=:x';
EXECUTE IMMEDIATE str USING x;
END;
/
查看SQL的versioncount信息
SYS@anqing1(rac1)> selectsql_id,version_count from v$sqlareawhere sql_text like 'select * from sys.lctwhere %';
SQL_ID VERSION_COUNT
------------- -------------
5d8tu19t1fug2 2
--查看parentcursor和 childcursor的handleaddress:
SYS@anqing1(rac1)> selectaddress,child_address from v$sql wheresql_id='5d8tu19t1fug2';
ADDRESS CHILD_AD
-------- --------
30A9DCDC 2CBA64AC
30A9DCDC 2A32C000
将library cache dump出来:
SQL> alter session set events 'immediatetrace namelibrary_cache level 11';
Session altered.
SQL> oradebug setmypid
Statement processed.
SQL> oradebug tracefile_name
/oradata/XEZF/admin/udump/xezf_ora_14041.trc
--查看trace文件:搜索30A9DCDC
BUCKET 92642:
LIBRARY OBJECT HANDLE:handle=30a9dcdcmtx=0x30a9dd90(2) cdp=2
--object handle 的内存地址
name=select * from sys.lct whereobject_name=:x
--object 的名称
hash=55555e74e494aa0356a33a0a721769e2 timestamp=07-24-201115:03:04
--hash值和timestamp
namespace=CRSRflags=RON/KGHP/TIM/PN0/SML/KST/DBN/MTX/[120100d0]
--namespace 和 flags
kkkk-dddd-llll=0000-0001-0001 lock=N pin=0latch#=1 hpc=0006hlc=0006
--Heaps loaded and kept,lock, pin, and latch modes
lwt=0x30a9dd38[0x30a9dd38,0x30a9dd38]ltm=0x30a9dd40[0x30a9dd40,0x30a9dd40]
pwt=0x30a9dd1c[0x30a9dd1c,0x30a9dd1c]ptm=0x30a9dd24[0x30a9dd24,0x30a9dd24]
ref=0x30a9dd58[0x30a9dd58,0x30a9dd58]lnd=0x30a9dd64[0x30a9dd64,0x30a9dd64]
--以上是:Linklistsof lock waiters, temporary locks, pin waiters, temporary pins andreferences
LOCK OWNERS:
lock user session count mode flags
-------- -------- -------- ----- ----------------------------
2d1a0cac 30efbd2030efbd20 2N [00]
2d10501c 30f10e7830f10e78 2N [00]
LIBRARY OBJECT: object=2aa6cf2c
--Memory address of theobject (heap 0)
type=CRSR flags=EXS[0001] pflags=[0000] status=VALDload=0
--Object type, flags, andstatus
CHILDREN: size=16
child# tablereference handle
------ -------- --------- --------
02c08c08c 2c08bd5c 2cba64ac
1 2c08c08c 2c08bec8 2a32c000
--这个就是所有child cursor的handle的内存地址
DATA BLOCKS:
data# heap pointer status pins change whr
----- -------- -------- --------- ---- ---------
0 2b8839b4 2aa6cfc4I/P/A/-/- 0NONE 00
--Object data structures(heap descriptors)
BUCKET 92642 total object count=1
查看其中一个child cursor地址,在trace里搜索:2cba64ac
LIBRARY OBJECT HANDLE: handle=2cba64acmtx=0x2cba6560(0)cdp=0
namespace=CRSR flags=RON/KGHP/PN0/EXP/[10010100]
kkkk-dddd-llll=0000-0001-0001 lock=N pin=0 latch#=1hpc=0002 hlc=0002
lwt=0x2cba6508[0x2cba6508,0x2cba6508]ltm=0x2cba6510[0x2cba6510,0x2cba6510]
pwt=0x2cba64ec[0x2cba64ec,0x2cba64ec]ptm=0x2cba64f4[0x2cba64f4,0x2cba64f4]
ref=0x2cba6528[0x2c08bd5c,0x2c08bd5c]lnd=0x2cba6534[0x2cba6534,0x2cba6534]
CHILD REFERENCES:
reference latch flags
--------- ----- -------------------
2c08bd5c 0CHL[02]
LOCK OWNERS:
lock user session count mode flags
-------- -------- -------- ----- ----------------------------
2d345160 30efbd2030efbd20 1N [00]
2d1a0bdc 30f10e7830f10e78 1N [00]
LIBRARY OBJECT: object=2c1a3280
type=CRSR flags=EXS/RIV[0201] pflags=[0000]status=VALD load=0
DEPENDENCIES: count=1 size=16
dependency# tablereference handle position flags
----------- -------- --------- ---------------- -------------------
0 2db7d838 2db7d770 2bb25644 18DEP[01]
AUTHORIZATIONS: count=1 size=16 minimumentrysize=16
00000000 30000000 00020000 00000000
ACCESSES: count=1 size=16
dependency# types
----------- -----
0 0009
SCHEMA: count=1 size=262144
0000003d
DATA BLOCKS:
data# heap pointer status pins change whr
----- -------- -------- --------- ---- ------ ---
0 2a078574 2c1a3318I/P/A/-/- 0NONE 00
6 2aa6d2542c4f9cf0I/-/A/-/E 0 NONE 00
这个结构和Heap 0的差不多。但是这个child cursor 没有name了。因为我们访问时先通过parentcursor。在到child cursor。所以parent cursor有name就可以了。
这里的Data blocks有2个: data block 0和data block 6.对应heap 0和heap 6. 关于Heap 0的说明如下:
The data block structure for a heap, stored in heap 0,contains a pointer to thefirst data block that is allocated for the heap, astatus indicator, the pinunder which the heap is loaded, and so on.
执行计划保存在Heap 6里,我们把Heap 6 dump出来,看一下:
SYS@anqing1(rac1)> alter session setevents 'immediate tracename heapdump_addr level 2,addr 0x2aa6d254';
Session altered.
--注意,这里的addr前面加了0x。
SYS@anqing1(rac1)> oradebug setmypid
Statement processed.
SYS@anqing1(rac1)> oradebugtracefile_name
/u01/app/oracle/admin/anqing/udump/anqing1_ora_1533.trc
在trace里搜索:0x2aa6d254
HEAP DUMP heapname="sql area" desc=0x2aa6d254
extent sz=0xff4 alt=32767 het=156 rec=0 flg=2opc=2
parent=0x2000002c owner=0x2aa6d1c8 nex=(nil)xsz=0xff4
EXTENT 0 addr=0x2a73d5e8
Chunk 2a73d5f0 sz= 788 free " "
Dump of memory from 0x2A73D5F0 to0x2A73D904
2A73D5F0 C0000315 00000000 2AA6D2B42AA6D2B4 [...........*...*]
2A73D600 2B10E1FC C0000051 000000002C49E55C [...+Q.......\.I,]
2A73D610 2AEA8820 00314E00 0000800400010035 [..*.N1.....5...]
2A73D620 00930024 00020001 0019003A00020074 [$.......:...t...]
2A73D630 001A0019 000200BF 007400B000500004 [..........t...P.]
2A73D640 001A0024 00BF0033 0003001200010022 [$...3......."...]
2A73D650 62000006 0000024D 2A73D6040C9D040C [...bM.....s*....]
2A73D660 00000000 2A73D8A0 0035000000240001 [......s*..5...$.]
2A73D670 00010093 003A0002 0074001900190002 [......:...t.....]
2A73D680 00BF001B 00B00002 0004007400240039 [........t...9.$.]
2A73D690 0033001B 001200BF 0022000300060001 [..3.......".....]
2A73D6A0 12021400 00010022 0A000006006B0802 [....".........k.]
2A73D6B0 03671F85 EF042C04 001C004E000C0000 [..g..,..N.......]
2A73D6C0 001D0400 001C0056 000002E0001D0040 [....V.......@...]
2A73D6D0 00B10028 000D0028 008C00260026005E [(...(...&...^.&.]
2A73D6E0 00A40026 000E000C 0E00002612011201 [&.......&.......]
2A73D6F0 00010022 AC000009 00AF0A0000010021 ["...........!...]
2A73D700 00020074 00210009 001500BF00780026 [t.....!.....&.x.]
....
dbsnake blog里的总结如下:
heap6实际上就是sql area(这个和上图中描述的heap 6是sql context不尽相同)。 Oracle把sql的执行计划存在了这个sql的子cursor的heap 6(也就是sql area)中,只不过存储的形式是编译好的二进制格式。
MOS 上的相关说明:
Parsinga cursor builds four different library cache structures, if they do notalreadyexist, within the library cache:
1、parent cursor handle
2、parent cursor object, containing the child dependency list
3、child cursor handle, inserted in the child dependency list oftheparent object
4、childcursor object, containing the compilation and run-timeexecution plan for thecompiled SQL statement.
Shared Pool 的空间分配和使用情况,可以通过一个内部视图来观察,这个视图就是X$KSMSP。
X$KSMSP的名称含义为: [K]ernal [S]torage [M]emory Management [S]GA Hea[P]其中每一行都代表着Shared Pool中的一个Chunk。以下是x$ksmsp的结构:
这个视图保存了在数据库中执行的SQL 语句和PL/SQL 块的信息。下面的SQL 语句可以显示给你带有literal 的语句或者是带有绑定变量的语句:
SELECT SUBSTR (sql_text, 1, 40) "SQL", COUNT (*),SUM (executions)"TotExecs" FROM v$sqlarea WHERE executions < 5GROUP BY SUBSTR (sql_text, 1, 40)
HAVING COUNT (*) > 30 ORDER BY 2;
注: Having 后的数值 "30" 可以根据需要调整以得到更为详细的信息。
· X$KSMLRU视图 这个固定表x$ksmlru跟踪共享池中导致其它对象换出(age out)的应用。这个固定表可以用来标记是什么导致了大的应用。如果很多对象在共享池中都被阶段性的刷新可能导致响应时间问题并且有可能在对象重载入共享池中的时候导致库高速缓冲闩竞争问题。关于这个x$ksmlru表的一个不寻常的地方就是如果有人从表中选取内容这个表的内容就会被擦除。这样这个固定表只存储曾经发生的最大的分配。这个值在选择后被重新设定这样接下来的大的分配可以被标记,即使它们不如先前的分配过的大。因为这样的重置,在查询提交后的结果不可以再次得到,从表中的输出的结果应该小心的保存。监视这个固定表运行如下操作:
SELECT * FROM X$KSMLRU WHEREksmlrsiz > 0;
· 这个表只可以用SYS用户登录进行查询。
· X$KSMSP视图 (类似堆Heapdump信息)使用这个视图能找出当前分配的空闲空间,有助于理解共享池碎片的程度。如我们在前面的描述,查找为游标分配的足够的大块内存的第一个地方是空闲列表( free list)。下面的语句显示了空闲列表中的大块内存:
SELECT '0 (<140)' bucket, ksmchcls, 10 * TRUNC (ksmchsiz / 10) "From",
COUNT (*) "Count", MAX (ksmchsiz) "Biggest",
TRUNC (AVG (ksmchsiz)) "AvgSize", TRUNC (SUM (ksmchsiz))"Total"
FROM x$ksmsp WHERE ksmchsiz < 140 AND ksmchcls = 'free'
GROUP BY ksmchcls, 10 * TRUNC (ksmchsiz / 10)
UNION ALL
SELECT '1 (140-267)' bucket, ksmchcls, 20 * TRUNC (ksmchsiz / 20),
COUNT (*), MAX (ksmchsiz), TRUNC (AVG (ksmchsiz)) "AvgSize",
TRUNC (SUM (ksmchsiz)) "Total"
FROM x$ksmsp
WHERE ksmchsiz BETWEEN 140 AND 267 AND ksmchcls = 'free'
GROUP BY ksmchcls, 20 * TRUNC (ksmchsiz / 20)
UNION ALL
SELECT '2 (268-523)' bucket, ksmchcls, 50 * TRUNC (ksmchsiz / 50),
COUNT (*), MAX (ksmchsiz), TRUNC (AVG (ksmchsiz)) "AvgSize",
TRUNC (SUM (ksmchsiz)) "Total"
FROM x$ksmsp
WHERE ksmchsiz BETWEEN 268 AND 523 AND ksmchcls = 'free'
GROUP BY ksmchcls, 50 * TRUNC (ksmchsiz / 50)
UNION ALL
SELECT '3-5 (524-4107)' bucket, ksmchcls, 500 * TRUNC (ksmchsiz /500),
COUNT (*), MAX (ksmchsiz), TRUNC (AVG (ksmchsiz)) "AvgSize",
TRUNC (SUM (ksmchsiz)) "Total"
FROM x$ksmsp
WHERE ksmchsiz BETWEEN 524 AND 4107 AND ksmchcls = 'free'
GROUP BY ksmchcls, 500 * TRUNC (ksmchsiz / 500)
UNION ALL
SELECT '6+ (4108+)' bucket, ksmchcls, 1000 * TRUNC (ksmchsiz /1000),
COUNT (*), MAX (ksmchsiz), TRUNC (AVG (ksmchsiz)) "AvgSize",
TRUNC (SUM (ksmchsiz)) "Total"
FROM x$ksmsp
WHERE ksmchsiz >= 4108 AND ksmchcls = 'free'
GROUP BY ksmchcls, 1000 * TRUNC (ksmchsiz / 1000);
清除shared_pool缓存。
alter system flush shared_pool;
SELECT free_space, avg_free_size,used_space, avg_used_size,request_failures, last_failure_size FROM v$shared_pool_reserved;
如果:REQUEST_FAILURES > 0并且 LAST_FAILURE_SIZE
或者 REQUEST_FAILURES等于0并且 LAST_FAILURE_SIZE
这时候就需要去调整了
官方文档Diagnosing and ResolvingError ORA-04031 [ID 146599.1]详解关于ORA-04031的如下:把所有可能产生ORA04031的原因都讲到了还列举了很多bug和解决方法。不过现在10g已经很普遍了ora-04031的错误应该不多了。
SELECT SUM(PINS)"EXECUTIONS",SUM(RELOADS) "CACHE MISSES WHILE EXECUTING" FROMV$LIBRARYCACHE; --如果丢失超过1%,那么尝试通过加大共享池的大小来减少库高速缓冲丢失。
select* from v$sgastat a where a.NAME like '%cache%';
select* from v$sgastat a where a.NAME like '%library%';
select * from v$sgastat a where a.pool = 'shared pool' and a.NAME = 'freememory';
selectsum(pinhits)/sum(pins)*100 from v$librarycache;
select parameter,sum(gets),sum(getmisses),100*sum(gets-getmisses)/sum(gets),sum(modifications)
from v$rowcache
where gets>0 group by parameter;
selectl.namespace,l.GETHITRATIO,l.PINHITRATIO,l.reloads,l.invalidations fromv$librarycache l;
select xidusn, object_id, session_id,locked_mode from v$locked_object;
SQL> select event,sid,p1,p2,p3 fromv$session_wait where event not like 'SQL*%' and event not like 'rdbms%';
SQL> select event,sid,p1,p2,p3 fromv$session_wait where event like '%library cache lock%';
SELECT sid, username, event, p1text, p1,p2text, p2, p3text, p3, seconds_in_wait FROM gv$session WHERE event = 'librarycache lock';
col operation format a50
col cost format 999999
col kbytes format 999999
col object format a20
select hash_value,child_number,
lpad('',2*depth)
||operation
||''
||options
||decode(id,0,substr(optimizer,1,6)||'Cost='||to_char(cost))operation,
object_name,object_type,cost,round(bytes/1024) kbytes
from v$sql_plan where hash_value in(
select a.sql_hash_value
from v$session a,v$session_wait b
where a.sid=b.sid
and b.event='db filesequential read')
order by hash_value,child_number,ID;
select name,value from v$sysstat where namelike '%cursor%';
selectname,value from v$sysstat where name like '%parse%';
parse count(total)就是总的parse次数中,session cursor cache hits就是在session cursor cache中找到的次数,所占比例越高,性能越好。如果比例比较低,并且有剩余内存的话,可以考虑加大该参数。
select * fromdba_tables where table_name = TABLE
--查看表的stats
select * from user_tab_statistics wheretable_name = 'STUDENT'
--查看列的stats
select * from user_tab_col_statistics wheretable_name = 'STUDENT'
--查看索引的stats
select * from user_ind_statistics wheretable_name = 'STUDENT'
l SQL> select * from (select *from v$sys_time_model order by value desc ) where rownum <=10;
花在了sql executeelapsed time指标上,记录下stat_id=372226525
l Select * from (select sid,stat_name,valuefrom v$sess_time_model where stat_id=372226525 order by value desc ) whererownum <= 10;
时间(微秒),同时获得SID。
SID号对应的PID
Select a.sid,a.username,a.status,a.process,b.spidfrom v$session a,v$process b where a.paddr=b.addr and sid=2116;
l 查询v$session或v$session_wait视图来获得实际的执行事件event信息。
SQL> selectsid,event,wait_time,seconds_in_wait,state,wait_class from v$session_wait wheresid=144;
l 当然也可以查询v$session_wait_class来查询具体的wait_class信息:
SQL> selectwait_class_id,wait_class,total_waits,time_waited from v$session_wait_class where sid=144;
l 找到占用系统资源特别大的Oracle的Session及执行的SQL语句。
select sid,sql_text from v$session s,v$sql q wheresid = 144 and (q.sql_id=s.sql_id or q.sql_id = s.prev_sql_id);
select sid,sql_text from v$session s,v$sql q wheresid = 86 and (q.sql_id=s.sql_id or q.sql_id = s.prev_sql_id);