驗證LOCK請求的FIFO機制

llnnmc發表於2017-10-04

在多併發的會話場景中,需要先獲取資源的X鎖定才能對該資源進行修改。與此同時,當其他會話也同樣請求修改該資源時,則必須按照先進先服務的方式(FIFO)進入請求佇列排隊等候。以下實驗可以驗證這一機制。


建立表

create table t1(c1 number, c2 number);

insert into t1 values(101, 5000);

commit;


三個會話按照先後順序試圖更新資料,會話的SID可以透過以下查詢獲取

select userenv('sid') from dual;


Session1SID129

update t1 set c2=6000 where c1=101;


Session2SID135

update t1 set c2=7000 where c1=101;


Session3SID138

update t1 set c2=8000 where c1=101;


可以看到,Session1執行更新後因為沒有提交,Session2Session3都在等待。此時查詢事務資訊,顯示有一個事務

select xid, addr, ses_addr, xidusn, xidslot, xidsqn, ubafil, ubablk, ubasqn, ubarec, status, start_time from v$transaction;


XID              ADDR             SES_ADDR             XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK     UBASQN     UBAREC STATUS           START_TIME

---------------- ---------------- ---------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------------- --------------------

0100060090020000 000007FF49D24CA8 000007FF4C78B2A0          1          6        656          3        717        145         35 ACTIVE           10/04/17 11:44:47


檢視鎖定資訊,存在事務回滾段號XIDUSN的會話表示正在執行的事務,129會話優先獲取鎖,XIDUSN0則表示會話被鎖,處於等待狀態,LOCKED_MODE3表示行獨佔鎖

col oracle_username for a15

select * from v$locked_object;


    XIDUSN    XIDSLOT     XIDSQN  OBJECT_ID SESSION_ID ORACLE_USERNAME OS_USER_NAME                   PROCESS                  LOCKED_MODE

---------- ---------- ---------- ---------- ---------- --------------- ------------------------------ ------------------------ -----------

         1          6        656      73449        129 SYS             VM-ORA11G-1\Administrator      3136:1796                          3

         0          0          0      73449        135 SYS             VM-ORA11G-1\Administrator      2932:2184                          3

         0          0          0      73449        138 SYS             VM-ORA11G-1\Administrator      3820:2100                          3


再看鎖佇列,129會話因為已經獲取到鎖,所以只有AE會話鎖,沒有TX鎖請求,CTIME為請求時間,135會話先於138會話,REQUEST大於0表示當前會話被阻塞,其它會話以對應的模式佔有鎖

select * from v$enqueue_lock where sid in (129, 135, 138);


ADDR             KADDR                   SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK

---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------

000007FF4CC56968 000007FF4CC569C0        129 AE        100          0          4          0       6898          0

000007FF4CC56BD8 000007FF4CC56C30        135 AE        100          0          4          0       3183          0

000007FF4CC56E48 000007FF4CC56EA0        135 TX      65542        656          0          6       3152          1

000007FF4CC56F18 000007FF4CC56F70        138 AE        100          0          4          0       3140          0

000007FF4CC57000 000007FF4CC57058        138 TX      65542        656          0          6       3106          0


鎖型別TYPE列的定義:TM-表級鎖,TX-事務鎖,MR-Media Recovery(每個檔案一個),AE-會話鎖(每個會話一個),UL-使用者定義的鎖型別

鎖模式LMODE列的定義:0-none1-空(NULL);2-行共享(RS);3-行獨佔(RX);4-共享鎖(S);5-共享行獨佔(SRX);6-獨佔鎖(X


dump等待佇列,可見129會話queown表示正在持有鎖,135會話和138會話quewat表示正在鎖請求等待

oradebug setmypid

oradebug tracefile_name

oradebug dump enqueues 8


000007FF4CD05DC0 TX-00010006-00000290 U   0   0   0   0   0   1 40 [4cd25530,4cd25530]

         [49d24d30,49d24d30] [4cd05df0,4cd05df0] [4cc56eb0,4cc57068]

   lock     que owner    session        hold wait ser link

   ----------------------------------------------------------------------

   000007FF49D24D20 OWN 000007FF4C78B2A0 000007FF4C78B2A0 (129)    X NLCK  73 [4cd05dd0,4cd05dd0]

   000007FF4CC56EA0 WAT 000007FF4C779C00 000007FF4C779C00 (135) NLCK    X 1468 [4cc57068,4cd05de0]

   000007FF4CC57058 WAT 000007FF4C7710B0 000007FF4C7710B0 (138) NLCK    X 1191 [4cd05de0,4cc56eb0]


對照驗證,將Session1提交,檢視事務,新的事務在執行

select xid, addr, ses_addr, xidusn, xidslot, xidsqn, ubafil, ubablk, ubasqn, ubarec, status, start_time from v$transaction;


XID              ADDR             SES_ADDR             XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK     UBASQN     UBAREC STATUS           START_TIME

---------------- ---------------- ---------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------------- --------------------

050006005D030000 000007FF49D256A8 000007FF4C779C00          5          6        861          3        536        187         14 ACTIVE           10/04/17 11:45:36


檢視鎖定物件,129會話的鎖已釋放,所以無記錄,135會話正在執行事務而獲得鎖,138會話則繼續等待

col oracle_username for a15

select * from v$locked_object;


    XIDUSN    XIDSLOT     XIDSQN  OBJECT_ID SESSION_ID ORACLE_USERNAME OS_USER_NAME                   PROCESS                  LOCKED_MODE

---------- ---------- ---------- ---------- ---------- --------------- ------------------------------ ------------------------ -----------

         5          6        861      73449        135 SYS             VM-ORA11G-1\Administrator      2932:2184                          3

         0          0          0      73449        138 SYS             VM-ORA11G-1\Administrator      3820:2100                          3


檢視請求佇列,129會話和135會話都已經獲取了請求,138會話仍有TX鎖請求

select * from v$enqueue_lock where sid in (129, 135, 138);


ADDR             KADDR                   SID TYPE        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK

---------------- ---------------- ---------- ---- ---------- ---------- ---------- ---------- ---------- ----------

000007FF4CC56968 000007FF4CC569C0        129 AE          100          0          4          0      21793          0

000007FF4CC56BD8 000007FF4CC56C30        135 AE          100          0          4          0      18078          0

000007FF4CC56E48 000007FF4CC56EA0        138 TX       327686        861          0          6        674          0

000007FF4CC56F18 000007FF4CC56F70        138 AE          100          0          4          0      18035          0


dump等待佇列,可見135會話queown表示正在持有鎖,138會話quewat表示正在鎖請求等待

oradebug setmypid

oradebug tracefile_name

oradebug dump enqueues 8


000007FF4CD07F98 TX-00050006-0000035d U   0   0   0   0   0   1 40 [4cd25bc0,4cd25bc0]

         [49d25730,49d25730] [4cd07fc8,4cd07fc8] [4cc56eb0,4cc56eb0]

   lock     que owner    session        hold wait ser link

   ----------------------------------------------------------------------

   000007FF49D25720 OWN 000007FF4C779C00 000007FF4C779C00 (135)    X NLCK 1468 [4cd07fa8,4cd07fa8]

   000007FF4CC56EA0 WAT 000007FF4C7710B0 000007FF4C7710B0 (138) NLCK    X 1191 [4cd07fb8,4cd07fb8]


對照驗證,將Session2提交,檢視事務,又一新的事務在執行

select xid, addr, ses_addr, xidusn, xidslot, xidsqn, ubafil, ubablk, ubasqn, ubarec, status, start_time from v$transaction;


XID              ADDR             SES_ADDR             XIDUSN    XIDSLOT     XIDSQN     UBAFIL     UBABLK     UBASQN     UBAREC STATUS           START_TIME

---------------- ---------------- ---------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------------- --------------------

09000D003D030000 000007FF49CC9678 000007FF4C7710B0          9         13        829          3       2477        184         28 ACTIVE           10/04/17 11:46:22


檢視鎖定物件,135會話的鎖也已釋放,138會話正在執行事務而獲得鎖,沒有會話在等待了

col oracle_username for a15

select * from v$locked_object;


    XIDUSN    XIDSLOT     XIDSQN  OBJECT_ID SESSION_ID ORACLE_USERNAME OS_USER_NAME                   PROCESS                  LOCKED_MODE

---------- ---------- ---------- ---------- ---------- --------------- ------------------------------ ------------------------ -----------

         9         13        829      73449        138 SYS             VM-ORA11G-1\Administrator      3820:2100                          3


檢視請求佇列,已經沒有TX鎖請求

select * from v$enqueue_lock where sid in (129, 135, 138);


ADDR             KADDR                   SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK

---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------

000007FF4CC56968 000007FF4CC569C0        129 AE        100          0          4          0      24483          0

000007FF4CC56BD8 000007FF4CC56C30        135 AE        100          0          4          0      20768          0

000007FF4CC56F18 000007FF4CC56F70        138 AE        100          0          4          0      20725          0


dump等待佇列,只有138會話的記錄了,並且queown表示已經擁有

oradebug setmypid

oradebug tracefile_name

oradebug dump enqueues 8


000007FF4CD00378 TX-0009000d-0000033d U   0   0   0   0   0   1 40 [4cd23730,4cd23730]

         [49cc9700,49cc9700] [4cd003a8,4cd003a8] [4cd00398,4cd00398]

   lock     que owner    session        hold wait ser link

   ----------------------------------------------------------------------

   000007FF49CC96F0 OWN 000007FF4C7710B0 000007FF4C7710B0 (138)    X NLCK 1191 [4cd00388,4cd00388]


如果此時關閉已經提交了的Session1Session2會話,則請求佇列中不會再有129135會話的AE鎖記錄,在Oracle 11gAE鎖是每個會話都會有一個的,對於Oracle 10g則不存在AE會話鎖

select * from v$enqueue_lock where sid in (129, 135, 138);


ADDR             KADDR                   SID TY        ID1        ID2      LMODE    REQUEST      CTIME      BLOCK

---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------

000007FF4CC56F18 000007FF4CC56F70        138 AE        100          0          4          0      21120          0


由此,我們透過實驗來驗證了鎖佇列的FIFO機制,遵循先請求先服務的原則。


最後,清理實驗用表

drop table t1 purge;

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28974745/viewspace-2145707/,如需轉載,請註明出處,否則將追究法律責任。

相關文章