【開發篇sql】 基礎概述(一) 鎖定和事務

yellowlee發表於2010-05-15

1oracle的鎖定與事務

僅僅來看下oracle的一些鎖和事務的相關檢視或引數,基本原理見基礎篇的事務原理一節。(本節內容可以參考9i10g

V$lock:

這個檢視列出了所有資料庫中的所有鎖(locks)和閂(latches)和所有在一個lock或者latch上的請求。簡述如下:

Addr

處於lock狀態的物件的地址

Kaddr

lock的地址

Sid    

session id

Type

使用者或者系統鎖的型別,使用者鎖例如:TM-DML入隊,

        TX-事務入隊,UL-使用者提供的(User supplied

        系統型別的鎖定諸如:SMON指派恢復程式,臨時段入隊,

        分配新的塊入隊,redo執行緒全域性入隊,

redo log的入隊(media recovery)等等

例如:

SQL> select distinct type from v$lock;

 

TYPE

----

MR

RT

TS

XR

dba_lock中的lock_type對應,可以得到:

SQL> select a.ADDR, a.KADDR, a.TYPE, b.lock_type, a.ID1, a.LMODE

  2    from v$lock a, dba_locks b

  3   where a.SID = b.session_id;

 

ADDR     KADDR    TYPE LOCK_TYPE                         ID1      LMODE

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

682BE818 682BE828 MR   Media Recovery                    201          4

682BE7CC 682BE7DC MR   Media Recovery                     10          4

682BE780 682BE790 MR   Media Recovery                      9          4

682BE734 682BE744 MR   Media Recovery                      8          4

682BE6E8 682BE6F8 MR   Media Recovery                      7          4

682BE69C 682BE6AC MR   Media Recovery                      6          4

682BE650 682BE660 MR   Media Recovery                      5          4

682BE604 682BE614 MR   Media Recovery                      4          4

682BE5B8 682BE5C8 MR   Media Recovery                      3          4

682BE56C 682BE57C MR   Media Recovery                      2          4

682BE520 682BE530 MR   Media Recovery                      1          4

682BE43C 682BE44C RT   Redo Thread                         1          6

682BE30C 682BE31C XR   XR                                  4          1

682BE488 682BE498 TS   Temp Segment                        2          3

 

14 rows selected

 

再來看看一般開發中涉及到比較重要的兩種鎖定型別:DML鎖定和DDL鎖定

DML鎖定

DML鎖定簡單講,用於保證一行在一段時間只有一個使用者進行修改,並且其他人不能夠刪除這個表或者修改這個表的結構。Dml鎖定指定了資料行的鎖定,或者資料表的鎖定,也即行鎖或者表鎖。

TX(事務)鎖定

從一個事務開始,一直到該事務commit或者rollback,該事務擁有一個TX鎖定,它是一個排隊機制,使得其他會話等待這個事務的完成。簡單的看一個TX例子:

SQL> update scott.dept a set a.dname = 'dname' where a.deptno = 10;

 

1 row updated

 

SQL>

SQL> select /*+ rule*/

  2   a.TYPE,

  3   c.lock_type lt,

  4   a.ID1,

  5   c.lock_id1 l_id1,

  6   a.ID2,

  7   c.lock_id2 l_id2,

  8   a.LMODE

  9    from v$lock a, (select sid from v$mystat where rownum = 1) b, dba_lock c

 10   where a.SID = b.SID

 11     and a.SID = c.session_id

 12     and a.ID1 = c.lock_id1

 13     and a.ID2 = c.lock_id2;

 

TYPE LT                                ID1 L_ID1     ID2 L_ID2           LMODE

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

TM   DML                             30137 30137        0 0                  3

TX   Transaction                    196647 196647    2527 2527            6

 

注意到上面的v$lockid1,id2(或者dba_lock中的lock_id1,lock_id2)欄位,

對於tm鎖,id1就是object_idid20,對於txid1是以十進位制數值表示事務佔用的回滾段號和事務solt number,具體演算法就是把id1除以216次方,餘數就是solt number,結果的取整數值是回滾段號(參見asktom),那麼改進一下上述查詢:

SQL> select /*+ rule*/

  2   a.TYPE,

  3   c.lock_type lt,

  4   trunc(a.ID1/power(2,16)) rollback_seq,

  5   mod(a.ID1,power(2,16)) slot,

  6   c.lock_id1 l_id1,

  7   a.ID2 seq,

  8   c.lock_id2 l_id2,

  9   a.LMODE

 10    from v$lock a, (select sid from v$mystat where rownum = 1) b, dba_lock c

 11   where a.SID = b.SID

 12     and a.SID = c.session_id

 13     and a.ID1 = c.lock_id1

 14     and a.TYPE = 'TX';

 

TYPE LT               ROLLBACK_SEQ       SLOT L_ID1            SEQ L_ID2       LMODE

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

TX   Transaction      3                  39 196647             2527 2527        6

再看看事務和鎖定物件的檢視,通過鎖定物件的地址和session id進行關聯,再改進一下上述查詢:

SQL> select /*+ rule*/

  2   a.TYPE,

  3   trunc(a.ID1/power(2,16)) rollback_seq,

  4   mod(a.ID1,power(2,16)) slot,

  5   a.ID2 seq,

  6   a.LMODE,

  7   d.XIDUSN,

  8   d.XIDSLOT,

  9   d.XIDSQN,

 10   e.OBJECT_ID,

 11   e.LOCKED_MODE

 12    from v$lock a, (select sid from v$mystat where rownum = 1) b, dba_lock c,

 13    v$transaction d,v$locked_object e

 14   where a.SID = b.SID

 15     and a.SID = c.session_id

 16     and a.ID1 = c.lock_id1

 17     and a.TYPE = 'TX'

 18     and a.SID = e.SESSION_ID

 19     and a.ADDR = d.ADDR;

 

TYPE ROLLBACK_SEQ       SLOT        SEQ      LMODE     XIDUSN    XIDSLOT     XIDSQN  OBJECT_ID LOCKED_MODE

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

TX              3         39       2527          6          3         39       2527      30137           3

上述(ROLLBACK_SEQSLOTSEQ)分別對應事務的(XIDUSNXIDSLOTXIDSQN)這就是事務idlmode便是鎖定的模式,見稍後的詳述。

那麼如果在一個另外的session中再執行對scott.dept中的相同的行進行修改,這樣將會看到tx鎖是如何工作的。按照此要求改動後的查詢(本例中第一個事務和第二個事務id分別為1012):

SQL> select /*+ rule*/

  2   a.SID,

  3   a.BLOCK,

  4   a.REQUEST,

  5   a.LMODE,

  6   d.XIDUSN,

  7   d.XIDSLOT,

  8   d.XIDSQN,

  9   e.OBJECT_ID,

 10   e.LOCKED_MODE

 11    from v$lock a,

 12    v$transaction d,v$locked_object e

 13   where a.SID in (10,12)

 14     and a.TYPE = 'TX'

 15     and a.SID = e.SESSION_ID

 16     and a.ADDR = d.ADDR(+)/*因為session 12的事務被10阻塞了,故現在看到的v$transaction12的事務並沒有開始。  */

 17     ;

 

       SID      BLOCK    REQUEST      LMODE     XIDUSN    XIDSLOT     XIDSQN  OBJECT_ID LOCKED_MODE

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

        10          1          0          6          3         39       2527      30137           3

        12          0          6          0                                       30137           3

對比一下session 10session 12 的屬性值:

10block=1代表了阻塞了其他,request是請求的鎖的型別,其值代表的意義與LMODE一樣,為0說明沒有請求,Lmode則是擁有6的鎖定,事務id為(3 392527),請求或者鎖定的物件id30137locked_mode說明事務請求或者鎖定已經完成的鎖定型別,為3,即是完成了對行的修改。(具體的LOMODE見後續詳細說明)。

12block=0,說明了當前沒有阻塞其他,request=6說明請求了一個6的鎖定,當前的lmode0,還沒有獲得鎖定,事務並沒有開始,故而還沒有事務id

接下來讓10提交,看看又會發生什麼:

SQL> select sid from v$mystat where rownum = 1;

 

       SID

----------

        10

 

SQL> commit;

 

Commit complete

 

檢視session 12,發現已經完成了update語句:

SQL> update scott.dept a set a.dname = 'dname' where a.deptno = 10;

 

1 row updated

 

SQL>

再看看前面的查詢語句:

SQL> select /*+ rule*/

  2   a.SID,

  3   a.BLOCK,

  4   a.REQUEST,

  5   a.LMODE,

  6   d.XIDUSN,

  7   d.XIDSLOT,

  8   d.XIDSQN,

  9   e.OBJECT_ID,

 10   e.LOCKED_MODE

 11    from v$lock a,

 12    v$transaction d,v$locked_object e

 13   where a.SID in (10,12)

 14     and a.TYPE = 'TX'

 15     and a.SID = e.SESSION_ID

 16     and a.ADDR = d.ADDR(+)/*現在session 10已經commit  */

 17     ;

 

       SID      BLOCK    REQUEST      LMODE     XIDUSN    XIDSLOT     XIDSQN  OBJECT_ID LOCKED_MODE

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

        12          0          0          6          9         42       2544      30137           3

可以很清楚的看到變化,session 12不在被block,請求也完成了,獲得了6的鎖定,事務id已經生成,而session 10的事務已經完成,已經釋放掉了鎖定和資源,v$transactionv$lock中已經沒有相應記錄。

 

TMdml入隊)鎖定

Tm鎖用來保證修改表資料的時候,表結構不被修改。例如:

在一個session(10)更新表scott.dept,而在另外一個session中(12)中修改表結構,則會出現下面的情況:

SQL> alter table scott.dept add (add_col number);

 

alter table scott.dept add (add_col number)

 

ORA-00054: resource busy and acquire with NOWAIT specified.

 

仍然繼續修改在講述TX鎖時使用的查詢:

SQL> select /*+ rule*/

  2   a.SID,

  3   a.ID1,

  4   a.TYPE,

  5   a.BLOCK,

  6   a.REQUEST,

  7   a.LMODE,

  8   d.XIDUSN,

  9   d.XIDSLOT,

 10   d.XIDSQN,

 11   e.OBJECT_ID,

 12   e.LOCKED_MODE

 13    from v$lock a,

 14    v$transaction d,v$locked_object e

 15   where a.SID in (10,12)

 16     and a.TYPE in ( 'TM','TX')

 17     and a.SID = e.SESSION_ID

 18     and a.ADDR = d.ADDR(+)/*現在session 10已經commit  */

 19     ;

 

       SID        ID1 TYPE      BLOCK    REQUEST      LMODE     XIDUSN    XIDSLOT     XIDSQN  OBJECT_ID LOCKED_MODE

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

        10      30137 TM            0          0          3                                       30137           3

        10     131097 TX            0          0          6          2         25       2545      30137           3

注意到tm鎖的id1就是tx鎖的物件id

 

DDL鎖定

主要有三種:

        獨佔的ddl鎖定

        共享ddl鎖定

        Breakable parse lock

像前面示例中的:

alter table scott.dept add (add_col number);

就是獨佔的ddl鎖。

 

DBA_DDL_LOCKS檢視

Session_id              session id

Owner                   owner of the lock

Name                    name of the lock

Type                   

鎖定型別,ddl的鎖定型別:

Cursor Table/Procedure/TypeBodyTriggerIndexClusterJava SourceJava ResourceJava Data

Mode_heldMode_request分別是Lock modeLock request type,包括:

None

Null

Share

Exclusive

通常在重新編譯包或者過程的時候,實際已經有使用者在執行,則編譯會被掛起,或者在grant某個正在執行的過程時,也會發生這樣的情況,查詢DBA_DDL_LOCKS檢視可以找到問題的具體所在。

具體將專門在附錄中分析鎖定相關的問題集。

 

LMODE(鎖定模式)和REQUEST(請求的鎖定模式)                                           

會話擁有的鎖的模式:

        0none

        1null

        2row-s 行共享(RS):共享表鎖,用於行的查詢

        3row-x 行專用(RX):用於行的修改,通常表明持有該鎖的事務已經完成了對行的修改

        4share 共享鎖(S):阻止其他dml操作

        5s/row-x 共享行專用(SRX):阻止其他事務操作

        6exclusive 專用(X):獨立訪問使用,是表鎖的最具限制性的形式。

Block

當前的鎖是否阻塞了其他的鎖。

 

鎖定相關的幾個引數:

SQL> show parameter DML_LOCKS;

 

NAME                                 TYPE        VALUE

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

dml_locks                            integer     748

這個引數用來規定TM鎖的總數,要獲得表鎖需要TM鎖。

 

SQL> show parameter ROW_LOCKING;

 

NAME                                 TYPE        VALUE

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

row_locking                          string      always

這個引數指定行鎖的方式,ROW_LOCKING該引數指定行封鎖方式。若設定為ALWAYS,則在修改表時只實施行封鎖。若設定為INTENT時,則行封鎖只適用於SELECT FOR UPDATE,而在修改時實施表封鎖。

 

v$transaction

ADDR               Address of the transaction state object 事務物件地址

XIDUSN             Undo segment number 回滾段編號

XIDSLOT            Slot number 槽(slot)編號

XIDSQN             Sequence number 序列編號

UBAFIL             Undo block address (UBA) filenum 回滾塊地址在的檔案序號

UBABLK             UBA block number        uba塊數量

UBASQN             UBA sequence number     uba序列編號

UBAREC             UBA record number       uba記錄數

STATUS             Status  事務狀態

START_TIME         Start time (wall clock)

START_SCNB         Start system change number (SCN) base

START_SCNW         Start SCN wrap

START_UEXT         Start extent number

START_UBAFIL       Start UBA file number

START_UBABLK       Start UBA block number

START_UBASQN       Start UBA sequence number

START_UBAREC       Start UBA record number

SES_ADDR           User session object address     使用者會話物件地址

FLAG               Flag

SPACE              YES if a space transaction 是否是空間事務

RECURSIVE          YES if a recursive transaction 是否是遞迴事務

NOUNDO             YES if a no undo transaction 是否是非撤銷事務

PTX                YES if parallel transaction     是否是並行事務

NAME               Name of a named transaction 是否命名事務

PRV_XIDUSN         Previous transaction undo segment number

PRV_XIDSLT         Previous transaction slot number

PRV_XIDSQN         Previous transaction sequence number

PTX_XIDUSN         Rollback segment number of the parent XID

PTX_XIDSLT         Slot number of the parent XID

PTX_XIDSQN         Sequence number of the parent XID

DSCN-B             Dependent SCN base

DSCN-W             Dependent SCN wrap

USED_UBLK          Number of undo blocks used 使用的撤銷塊數

USED_UREC          Number of undo records used 書用的撤銷記錄數

LOG_IO             Logical I/O     邏輯io

PHY_IO             Physical I/O    物理io

CR_GET             Consistent gets 一致性讀

CR_CHANGE          Consistent changes 一致性更改

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

相關文章