暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Oracle enqueue相关的一些数据结构

白鳝的洞穴 2021-03-24
1104
锁是数据库中最为复杂的并发控制机制之一。oracle锁通常称为Enqueue,因为每当会话请求任何共享资源结构上的锁时,它锁定数据结构都会通过资源列表去排队等待,Oralce锁可以应用于复合对象和简单对象(例如表和缓存缓冲区)。
Oracle在运行时决定是允许会话锁定特定资源,还是将锁定请求在某个队列(Waiter,Convertor)。enqueue的实现属于Oracle内核队列服务层(KSQ)。今天我们通过KSQ的一些数据结构来分析一下Oracle enqueue管理方面的一些算法。

oracle的enqueue的数据结构是ksqlk,每个锁都对应一个资源的指针。通过这个指针可以找到锁对应的资源的情况。

大家注意ksqrseqt和ksqrsid1/ksqrsid2这三个字段,ksqrseqt是锁的类别,都是两个字母的,比如TX/TM,id1/id2是对应的resource的ID,这三部分组成了一个锁的唯一性的描述,比如TM-2353-0,这个锁是一个表锁,对应的表的OBJECT ID是2353。
LOCK和RESOURCE在SGA中是两个数组,数组的大小是由两个参数来确定的。这两个参数是_enqueue_locks _enqueue_resources ,这两个都是隐含参数,目前的数据库版本都是根据CPU数量,SGA大小等自动计算的。比如:

大家看到老白这个数据库的resources数组是7500个,如果我们经常在这个数组中查找某个res,那么遍历这个数组肯定不是好办法。于是Oracle的看家绝技hash bucket又出现了。

可以看到ksqsg结构里有一个hash table的指针,以及hash table的大小的数值。hsqht的结构如下:

可以看出ksqht是一个单向链表,链表的头是ksqhtlk。从上门的结构,我们可以画一张Oracle enqueue管理的全景图。

通过HASH表可以快速的根据RESOURCE的名称定位到某个BUCKET,我们可以从Oracle的参数中看出bucket的数量为3345,而RESOURCE的数组为7500,每个bucket上挂的RESOURCE数量很少,这便于快速的找到某个RESOURCE。通过简单的HASH计算,我们就可以定位到某个resource在hash table中的位置,然后通过链头指针单向查找,找到这个res。
从上述数据结构我们也可以看出,ksqlk是面向应用的结构,可以清晰的描述出该锁对应的事务或者会话,以及锁的访问者的信息。对于enqueue的申请使用直接通过ksqlk结构与enqueue模块交互。而ksqrs是面向锁对应的资源的,是实现enqueue的具体串行化共享互斥机制的主要数据结构。
当然今天老白只是简单的通过几个数据结构分析了一下Oracle的enqueue机制的最为粗浅的部分。实际上Oracle的锁管理远比其他数据库要复杂。对于行锁的实现,以及一些特殊的锁(包括字典锁等),我们以后找时间再单独分析,每个锁的实现方式,都不是一篇简单的千字文所能表述的很清晰的。
文章转载自白鳝的洞穴,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论