首先我们要搞清楚什么了Enqueue,enqueue可以做名词,也可以做动词来解释。做名词时,指的的是一种锁的类型,比如Tx enqueue。做动词时,则是指将锁请求放入到请求队列的操作。我们知道,lock是一种需要排队的锁实现机制,这和latch是不一样的,latch是一种轻量级的锁,是不需要排队得。Enqueue就是lock的排队机制的实现。lock是用来实现对于共享资源的并发访问的。如果两个session请求的lock是兼容的,则可以同时锁定资源,如果两个session请求的lock是不兼容的,则其中一个session必须等待另外一个session释放其持有的lock后,才能获得对共享资源的锁定。这时,等待的session的lock请求就需要进入到一个队列当中,这就是enqueue等待。
Oracle server使用不同类型的锁去控制用户之间的并发访问。利用不同的被锁资源,可以将oracle Locks划分成为以下几个类别:
1、 DDL or data dictionary locks
2、 DML or data locks
3、 Internal locks and latches
4、 Distribute locks(ensure the data and other resources distributed among the instance of RAC)
5、 Global cache recources(RAC only)
Enqueues是一个用户序列化访问共用资源的一个本地锁(Enqueues are a locking mechanism for managing access to shared resources)。Enqueues可以生存范围在本实例,也可以在RAC中的,可以有global enqueues。比如Space management enqueues(ST)就是。Enqueues有三种接口:获得,转换或者释放。如果一个enqueues不可用,那么客户层有三种方式来处理,wait indefinitely、wait timeout和nowait。每个Enqueue都有唯一的标识名,就像lock和recource的名一样。Enqueue的标识名遵循以下模式:
SQL> select type,id1,id2 from v$lock where rownum<3;
TY ID1 ID2
-- ---------- ----------
MR 201 0
MR 28 0
enqueue(lock)一共有六种模式: NULL、在共享模式下锁行SS(Row Share)、在专有模式下锁行SX(Row Exclusive)、在共享模式下锁整个表S(Share)、在共享模式下锁表,但有一行是专有模式SSX(Share Row Exclusive)、在专有模式下锁整个表X(Exclusive)。Enqueue几个模式间存在兼容性。
Enqueues是被session所获取,转换和释放,而不是进程。Session可以在processes间迁移,而拥有enqueue的session也可以在processes间迁移。迁移只所以能够容易的实现,主要是借助了状态对象(state objects)。对于每个enqueue,都有自己的锁结构或者资源结构(resource structure),在这个锁结构中维持着owner list、waiter list和converter list。锁和资源表分配在SGA中,资源表的行数由参数enqueue_resources所控制。具体可以通过v$resource来查询。而在enqueue lock表中的行数由_enqueue_locks参数所控制,可以查询v$enqueue_lock而得到具体的信息。Resource and lock structures如下:
Enqueue可能是管理enqueue或者客户端enqueue。主要差别在于锁数据结构的位置。Client enqueue将锁结构数据放在自己的state object中,而managed enqueue是由kernel来分配和控制的。Client enqueues包括DML enqueue(TM)、Transaction enqueu(TX)和User Supplied(UL)。Managed enqueues包括CF(Controlfile Transaction)、PF(password file)、DM(Database Mount)、SQ(Sequence Number enqueue)、JQ(Job queue)、SS(Sort segment)、MR(Media recovery)和ST(Space management transaction)。
即使进程失败,锁结构也可以借助PMON进程从state object中而得到恢复。这就意味着你可以通过system state dump观察其中的详细信息。不同的enqueue类型而言,state objects信息能在enqueue state object 或者client state object中发现。所有的资源结构都是资源表resource table的一部分。为了在资源表中发现资源结构,一个hash算法被使用。资源名resource name
通过上面关于enqueue resource的描述,我们可以知道,oracle查找一个lock时,需要先在enqueue resource数上查找到该lock的位置。如果每次都在数组上顺序查找,显然效率较低。我们知道hash是一种高效的查找算法,所以oracle对于enqueue resource的查找也采用了hash方式,引入了一个hash数组,其大小由隐含参数_enqueue_hash控制。通过对enqueue的名字
同样的,对于enqueue resource数组中的空闲位置,需要通过一个freelist列表来管理,这样每次在请求新的位置时,不至于要扫描整个数组。enqueue freelist由enqueues latch的保护。实际上,enqueue resource的Hash管理方式,和buffer cache/library cache的管理方式非常的相像。
下面在具体说说几个和enqueue相关的参数。
1、enqueue_resources:enqueue的数据,默认值由数据库数据文件数量、sessions和DML_locks来决定。Oracle server会自动从shared pool中分配,如果指定的数量不够用。
2、 managed enqueue lock structure被参数_enqueue_locks所控制。这个值是由session数量、files、query slaves、lock processes和instance间的信息所计算而得。你可以通过select * from v$resource_limit来查询相关的信息。
3、 hash bucket的数量由单数_enqueue_hash所规定。相关数值的计算方法和enqueue_resource的计算方法相当。
4、 _enqueue_hash_chain_latches,控制hash chain latches的数量。缺省等同于cpu_count。
当一个session没有拥有lock时而想得到lock时,当然,这个session也不存在waiter lists和converter lists中。否则,这个session将在wait queue中等待。要想获得一个lock,步鄹大概如下:
1、 使用hash function,决定那个linked list有需要的resource。
2、 得到相应的enqueue hash chain latch。
3、 定位resource,如果没有free resource structure,把lock放在linked list中。
4、 得到enqueue latch。
5、 获得a free lock structure。
6、 Population it with the correct information for the resource requested
7、 Link the lock structure to the resource structure
8、 Release enqueue latch
9、 Release enqueue hash chain latch
Lock conversersion只有在要求的mode和已经占有者的模式是compatible和subset的情况下发生。Lock release的步鄹如下:
1、 use hash function to determine the linked list
2、 get enqueue hash chain latch
3、 locate the resource
4、 get enqueue latch
5、 unlink lock resource from the resource
6、 link the lock resource to the lock freelist
7、 release enqueue latch
8、 post the next converter or waiter(if only)
9、 possibly unlink the resource structure from the hash chain ,and link it to he resource free list
10、release enqueue hash chain latch
如下用一个图表表示一个enqueue的operations。
Enqueue waits tunning主要是reduce the number of requests and reduce the amount of time the enqueue。
可以使用x$ksgst这个试图得到各个类型lock的gets 和waits。
可以通过v$lock查询系统所有的lock structure,其中的type,id1和id2和v$resource相匹配,Lmode表示lock mode held;Request表示lock mode requested;ADDR:表示address of lock state object;kaddr表示address of lock 。
V$resource中包含系统中被locked的resource structure。其中addr是address of resource object。每行中的数据对应一行或者多行v$lock。
v$locked_object中包含系统中所有在objects上的对象,如TM locks。
使用catblock.sql脚本可以生成一系列数据库字典,如dba_locks、dba_dml_locks、dba_ddl_locks、dba_waiters和dba_blockers。利用utllockt.sql可以生成一个lock tree。
没有评论:
发表评论