
锁(Lock):
锁的本质是在数据并发访问(data concurrency)及数据一致性(data consistency)之间取得一个平衡。
锁有两层意思,首先,它代表的是一种控制机制;其次,在这个机制中有一个成功叫作Lock。
Lock的框架:
Lock的框架包括三个组件:Resource Structure(资源)、Lock Structure(锁)、Enqueue(排队机制)。
其中Resource Structure和Lock Structure是数据结构,Enqueue是使用的算法。

Resource Structure:
Oracle对于每一个需要进行"并发控制"的资源,都在SGA中用一个数据结构来描述它,这个数据结构图就是Resource Structure。
这个数据结构中有三个与"并发控制"有关的成员:owner、waiter和Converter。
它是三个指针,分别指向三个由Lock Structure组成的链表。
Lock Structure:
每当进程要访问共享资源时,必须先"锁定"该资源。
这个动作实际就是从内存中申请一个Lock Structure,在其中记录"锁模式,进程ID"等重要的信息。
然后看是否能够立刻获得资源的访问权,如果不能,则把这个Lock Structure挂到Resource Structure的Waiter链表中。如果能够获得,则把Lock Structure挂到Resource
Structure的Owner链表中。
上面说的Resource Structure中的Owner、Waiter、Converter三个成员就是指向Lock Structure组成的链表的指针。
锁模式:
在Lock Structure中有一个很重要的信息是锁模式,锁模式用于表示对资源的保护级别。
常见的有三种级别:Null、Share、Exclusive。
Enqueue算法:
Lock Structure使用的是Enqueue算法,可以理解为"先入先出队列"。
锁的申请:
1、使用hash算法将资源做hash,做完hash得到一个结果值将对应一个hash bucket
2、申请enqueue hash chain以访问hash bucket。
3、此时,将资源放到hash bucket的hash chain上。如果在hash chain上没有找到对应的资源结构,就到free resource list上找,找到后放入到hash chain上。
4、获得enqueue latch
5、获得free lock的结构(与lock free list的头部断连)
6、将正确的资源信息放到lock上。
7、将lock结构连接到资源结构上。
8、释放enqueue latch
9、释放enqueue hash chain latch。
锁的释放:
1、使用hash函数得到resource的hash chain
2、获得enqueue hash chain来访问hash bucket
3、找到hash bucket,顺着hash chain找到resource。
4、申请enqueue latch
5、将lock结构和resource结构断连
6、将lock结构再次连到free lock list上
7、释放enqueue latch
8、如果resource结构有converter或者waiter,这继续处理。
9、如果可能的话,将resource结构从hash chain上断开,将resource 结构放到free resource list中。
10、释放enquene hash chain latch。
通俗解释:
上面的resource是指能被session共享的resource,如一个表、一个library cache中的child handle等等。enqueue是用于控制如何访问这些共享资源。
打个比方吧,有个钻石加工厂,要把钻石镶嵌到项链上,项链有不同大小的眼以供钻石镶嵌上去。由于为了清洗项链,项链被放在一个开水桶里面,开水桶做了标记,1,2,3,4……
开水桶就是我们的hash bucket,钻石是我们的resource,项链上的眼是resource structure,enquene hash chain是能伸进开水桶的钳子,free resource list是放了一堆链子托盘,如果某个桶里面没有链子,可以到这个上面去找一条来放入到开水桶中,enqueue是做镶嵌工作时小榔头。lock structure是项链上的眼需要抓紧钻石的爪子。该工厂就只有一把钳子和一把榔头,因此后续要操作的人必须等待。
钻石根据其自身的成色/切工/大小,根据hash算法,知道需要镶嵌在5号桶的一条项链上,于是,首先获得enqueue hash chain钳子,去捞那条链子,如果发现5号的hash bucket桶里面没有这条链子,则去free resource list上找一条链子,再泡到开水桶中。如果找到,就把抓钻石的小爪子安放到项链的眼上,小榔头把爪子敲好。





