佇列、資源與鎖
原文地址:OCP知識點講解 之 佇列、資源與鎖 作者:葉紹琛
一、佇列與共享資源
共享資源可以被多個會話、程式同時訪問,因此它的訪問需要保護。Oracle中,除了PGA,所有的東西(包括記憶體、磁碟、CPU、表、索引、事務等等,種類太多,一概用東西兩字來代表)都是共享資源。多個程式或會話對共享資源操作時,就需要排隊。這裡所需要排的隊就是佇列(Enqueue)。訪問不同的共享資源,需要排不同的隊。可以這樣說,有多少種佇列,就有多少種需要保護的共享資源。佇列的名字一般是兩個位元組構成,如TM,TX,JQ,……。具體所有佇列的種類、名字,參見V$LOCK檢視介紹中的附表。
二、佇列標識
我們以TM為例,它是DML佇列鎖。在對錶作DML操作時,需要先在此排隊,正式點的說法是:需要先獲得TM佇列鎖。TM也被稱作表鎖,因為它主要是在對錶作操作是獲得的。如果資料庫中有1000個表,針對這一千個表,並非只有一個佇列,要是這樣的話也不太合理。1000個表,就應該有1000個TM佇列,這樣才附合常理。如果一千個佇列都叫TM,將來操作時不好區分,因此,需要為這一千個TM佇列分別名命,這個名字,也被稱為佇列標識。TM佇列的命名格式為:TM-OID-0。其中OID是Object ID,即物件ID。最後一部分一般都是0。假如AA表的OID是6636,它的佇列標識就是TM-6636-0。
每種佇列的命名格式各不相同,總的來說是“佇列名-ID1-ID2”,ID1和ID2分別是兩個引數,對於TM佇列來說,ID1是OID,ID2為0。
三、資源結構
繼續我們上面的假設,如資料庫中有一千個表,這就要對應一千個TM佇列。但只有當操作到哪個表了,才會為它建立相關的佇列資訊。比如會話釋出了對AA表的更新操作,需要在SGA中為AA建立相關的TM佇列資訊。這些相關AA的TM資訊,也被稱為“資源結構”(KSQRS,KSQ是核心服務佇列的簡寫,RS是Resource Structure的簡寫,即資源結構)。每一個資源結構維持一個所有者、等待者和轉換者的列表。如下圖:
資源結構前的即是佇列標識,也可以作為資源結構標識(資源標識)。
每一個所有者、等待者和轉換者有一個鎖結構(Ksqlk),簡單點說每一個所有者、等待者和轉換者有一個連結串列,此連結串列由會話、鎖模式等資訊構成,具體描述了什麼會話以什麼模式獲得此資源結構。具體如下:
1)如果會話獲得鎖,鎖結構將在所有者列表上
2)如果會話正在等待獲得鎖,鎖結構將在等待者列表上
3)如果鎖已被獲得,但會話正在等待它被轉換到一種不同的模式,鎖結構將在轉換者列表上
所有資源結構組成一個資源表,資源表和資源結構上的鎖都被分配在SGA中。資源表中總的行數由初始化引數ENQUEUE_RESOURCES決定,且資源表中的行可以在X$KSQRS中被看到。正在被使用的將在V$RESOURCE中顯示。還可以在v$resource_limit中看到資源結構數量的限制和使用情況:
sid=9 pid=10> select * from v$resource_limit where resource_name = 'enqueue_resources';
RESOURCE_NAME CURRENT_UTILIZATION MAX_UTILIZATION INITIAL_ALLOCATION LIMIT_VALUE
------------------------------ ------------------- --------------- -------------------- -------------
enqueue_resources 32 32 968 UNLIMITED
可以看到,當前使用了32個資源結構,最多時使用了32個資源結構,初始化引數中分配了968個資源結構。最多使用是UNLIMITED,沒有限制。由於Oracle 9i採用的演算法,我們在X$KSQRS中看到的總行數並不是968,而是992。為確保重用,資源表中未用的資源結構被放置在一個連線列表,稱為:Resource Free List。我們可以釋出一些更新宣告,不要提交,這樣佔用的TM、TX資源結構一直不會釋放。觀察X$KSQRS,TM資源結構的佔用增多,但檢視的總行數不變,還是992。新增的TM、TX資源結構佔用了其他已經釋放的資源結構。
四、資源結構雜湊表
為了在資源表中快速找到某一資源結構,Oracle當然還是要使用HASH演算法。Oracle根據資源標識計算HASH值。當然,和Library cache一樣,資源表中已被佔用的資源結構的HASH值構成了一個個HASH Buckut。
上圖就是HASH Bucket和資源結構的圖,可以看到和Library cache中的很像。HASH演算法嗎,所有的HASH演算法都會有很多共同點。從上圖中可以看到,想訪問Hash Bucket,需要Enqueue hash chain閂,它需要保護上圖中的HASH表,和每個Hash Bucket後的Hash鏈。它的數量由隱含引數_enqueue_hash_chain_latches控制。Enqueue hash chain閂類似於Buffer cache chain閂。它們都是一個閂要管理多個雜湊桶,不過Enqueue hash chain更特殊,在單CPU環境中,只有一個,卻要管理所有的雜湊桶,這是因為佇列的爭用,畢競比Buffer要小的多。
Oracle中所有關於HASH的演算法,都要有HASH表、HASH鏈和保護HASH鏈的閂,HASH表不需要保護,這是因為HASH表是大小固定的陣列。每一個陣列元素就是一個Hash Bucket。每個雜湊桶的雜湊值也都是事先定好的。因此不存在對雜湊桶的更改,如插入一個雜湊桶、修改一個雜湊桶的雜湊值或刪除一個未使用的雜湊桶等等,這些操作都是不存在的。因此,既然不會有修改操作,雜湊表就不需保護。需要保護的是每個雜湊桶後的鏈。每個桶後的鏈中,都可以掛多個物件,我們可能向鏈上新增或刪除物件,既然有修改,就需要保護。
佇列資源Hash表的長度由_enqueue_hash控制,其始值來源於SESSION引數,初始是375。我們的資源表共有992行,而雜湊桶只有375個,這必然會有多個資源結構排在某一個雜湊桶後面。如果曾經增加過ENQUEUE_RESOURCES的值,也就是說,資源結構比系統預設的還要更多一些,但控制雜湊表長度的_enqueue_hash引數值如果不跟著增加。這就意味著每個雜湊桶下要掛接更多的資源結構,這有可能因起Enqueue hash chain閂的競爭。如何觀察閂的使用情況這是下一章節的內容,這裡就不多說了。_enqueue_hash的初始值是根據Sessions引數來定的,計算公式如下:((sessions-10)*2)+55,預設 ((170-10)*2)+55,正好等於375,它並不隨ENQUEUE_RESOURCES的增加而增加。
佇列、資源結構和鎖結構的關係如上圖。上圖是分別在兩個會話中釋出如下宣告後的結果:
在會話10:sid=10 pid=11> insert into a1 values(1,1,1);
已建立 1 行。
在會話12:sid=12 pid=12> insert into a1 values(2,2,2);
已建立 1 行。
檢視雜湊表檢視:
sid=9 pid=10> select * from v$resource where type ='TM';
ADDR TY ID1 ID2
-------- -- ---------- ----------
7B6D5C40 TM 6657 0
可以看到,有一個TM佇列,地址是7B6D5C40,物件ID是6657,這個正是A1表。
檢視V$LOCK檢視:
sid=13 pid=13> select * from v$lock where sid>=8;
ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
7AF661FC 7AF66308 10 TX 458765 2212 6 0 452 0
7AF3A074 7AF3A088 10 TM 6657 0 3 0 452 0
7AF837AC 7AF838B8 12 TX 327686 2355 6 0 84 0
7AF3A17C 7AF3A190 12 TM 6657 0 3 0 84 0
上面的結果中顯示,TM-6657-0有兩個鎖,地址分別是7AF3A088、7AF3A190。
說明,上圖中的資訊,部分來自於佇列結構的DUMP,宣告如下,有興趣可以自己試試。
sid=10 pid=11> alter session set events 'immediate trace name enqueues level 4';
雜湊表的長度,由_enqueue_hash設定,資源結構的數量(也稱資源表的長度),由ENQUEUE_RESOURCES設定。鎖結構的的數量,也可以由DBA控制,隱含引數_enqueue_locks就是設定鎖結構數量的(也稱佇列鎖:Enqueue Lock),預設值2230。可以被看到在X$KSQEQ中,正在被使用的在V$ENQUEUE_LOCK顯示。但是,有關TM、TX這兩個佇列的鎖和其他情況的佇列鎖不一樣,除非它們發生了Enqueue等待,否則它們並不在X$KSQEQ結構中顯示,因此在X$KSQEQ之上的V$ENQUEUE_LOCK也沒有正在使用中的TX、TM佇列鎖的情況。Oracle使用不同的結構來管理TX和TM排除。TX:X$KTCXB,核心事務控制事務物件,V$TRANSACTION_ENQUEUE的基礎檢視。它的尺寸由transactions初始化引數控制。有關TX的我們下面專門再說。再看TM:X$KTADM,核心事務訪問定義DML鎖。X$KTADM的尺寸由DML_LOCKS定義,也就是TM鎖的數量。X$KTADM對DBA意義不大,可以為我們提供鎖的模式、加鎖的時間、正在請求的模式、會話SID等資訊,資訊量並不比V$LOCK中多。透過上兩個X$檢視觀察正在使用中的TM、TX鎖的最好辦法是:
set linesize 800
col KTCXBNAM for a20
select * from x$ktcxb where ktcxblkp in (select kaddr from v$lock where type='TX');
select * from x$ktadm where ksqlkadr in ( select kaddr from v$lock where type='TM');
我們也可以在V$RESOURCE_LIMIT中看到有關佇列鎖的使用情況:
sid=9 pid=10> select * from v$resource_limit where resource_name like 'enqueue%';
RESOURCE_NAME CURRENT_UTILIZATION MAX_UTILIZATION INITIAL_ALLOCATION LIMIT_VALUE
------------------------------ ------------------- --------------- -------------------- -------------
enqueue_locks 26 30 2230 2230
enqueue_resources 26 26 1200 UNLIMITED
注意enqueue_locks和transactions、DML_LOCKS的關係,enqueue_locks是總的佇列鎖的數量,transactions定義了在總的佇列鎖中,TX鎖的數量,DML_LOCKS是總佇列鎖中TM鎖的數量。也就是說transactions和DML_LOCKS是enqueue_locks的一部分。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2124615/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 無鎖佇列佇列
- 無鎖資料結構:佇列資料結構佇列
- 實現無鎖的棧與佇列(4)佇列
- 實現無鎖的棧與佇列(3)佇列
- 實現無鎖的棧與佇列(1)佇列
- 實現無鎖的棧與佇列(2)佇列
- 認識無鎖佇列佇列
- 佇列:佇列線上程池等有限資源池中的應用佇列
- Redis 分散式鎖與任務佇列實戰Redis分散式佇列
- 壯實學資料技術06:資源、佇列與叢集佇列
- 實現無鎖的棧與佇列(5):Hazard Pointer佇列
- 資料結構與演算法——佇列(環形佇列)資料結構演算法佇列
- 資料結構-棧與佇列資料結構佇列
- 資料結構:棧與佇列資料結構佇列
- python資料結構與演算法——棧、佇列與雙端佇列Python資料結構演算法佇列
- synchronized 中的同步佇列與等待佇列synchronized佇列
- 用 Redis 實現分散式鎖與實現任務佇列Redis分散式佇列
- Java版-資料結構-佇列(陣列佇列)Java資料結構佇列陣列
- java 棧與佇列Java佇列
- 抽象佇列同步器(獨佔鎖)抽象佇列
- 資料結構與演算法-棧與佇列資料結構演算法佇列
- 資料結構與演算法-佇列資料結構演算法佇列
- 建立訊息佇列(Kafka)源表佇列Kafka
- Oracle佇列鎖enq:TS,Temporary Segment (also TableSpace)Oracle佇列ENQ
- 基於佇列的鎖:mcs lock簡介佇列
- 佇列、阻塞佇列佇列
- 棧與佇列簡介佇列
- 堆與優先佇列佇列
- 6.13-棧與佇列佇列
- Java版-資料結構-佇列(迴圈佇列)Java資料結構佇列
- 資料結構與演算法—稀疏陣列和佇列資料結構演算法陣列佇列
- 聊聊陣列與連結串列,棧與佇列陣列佇列
- 資料結構與演算法(三),棧與佇列資料結構演算法佇列
- 資料結構與演算法分析——佇列資料結構演算法佇列
- javascript資料結構與演算法-佇列JavaScript資料結構演算法佇列
- javascript資料結構與演算法---佇列JavaScript資料結構演算法佇列
- Redis 應用-非同步訊息佇列與延時佇列Redis非同步佇列
- 三、資料結構演算法-棧、佇列、優先佇列、雙端佇列資料結構演算法佇列