學習動態性能表html
第八篇-(1)-V$LOCK 2007.5.31sql
這個視圖列出Oracle 服務器當前擁有的鎖以及未完成的鎖或栓鎖請求。若是你覺着session在等待等待事件隊列那你應該檢查本視圖。若是你發現session在等待一個鎖。那麼按以下前後順序:數據庫
V$LOCK中的經常使用列服務器
公共鎖類型session
在Oracle數據庫中,DML鎖主要包括TM鎖和TX鎖,其中TM鎖稱爲表級鎖,TX鎖稱爲事務鎖或行級鎖。併發
當Oracle執行DML語句時,系統自動在所要操做的表上申請TM類型的鎖。當TM鎖得到後,系統再自動申請TX類型的鎖,並將實際鎖定的數據行的鎖標誌位進行置位。這樣在事務加鎖前檢查TX鎖相容性時就不用再逐行檢查鎖標誌,而只需檢查TM鎖模式的相容性便可,大大提升了系統的效率。TM鎖包括了SS、SX、S、X等多種模式,在數據庫中用0-6來表示。不一樣的SQL操做產生不一樣類型的TM鎖,以下表1。oracle
TX:行級鎖,事務鎖性能
按下列項以免競爭:學習
TM:表級鎖spa
在TM隊列避免競爭,能夠考慮屏蔽對象表級鎖,屏蔽表級鎖防止對象執行任何ddl語句。
ST:空間事務鎖
按以下項以免競爭:
UL:用戶定義鎖
用戶能夠自定義鎖。內容較多並與此節關係不大,略過。
V$LOCK中的鏈接列
Colum View Joined Column(s)
SID V$SESSIO SID
ID1, ID2, TYPE V$LOCK ID1, ID2, TYPE
ID1 DBA_OBJECTS OBJECT_ID
TRUNCID1/65536) V$ROLLNAME USN
表1 Oracle的TM鎖類型 |
|||
鎖模式 |
鎖描述 |
解釋 |
SQL操做 |
0 |
none |
|
|
1 |
NULL |
空 |
Select |
2 |
SS(Row-S) |
行級共享鎖,其餘對象只能查詢這些數據行 |
Select for update、Lock for update、Lock row share |
3 |
SX(Row-X) |
行級排它鎖,在提交前不容許作DML操做 |
Insert、Update、Delete、Lock row share |
4 |
S(Share) |
共享鎖 |
Create index、Lock share |
5 |
SSX(S/Row-X) |
共享行級排它鎖 |
Lock share row exclusive |
6 |
X(Exclusive) |
排它鎖 |
Alter table、Drop able、Drop index、Truncate table 、Lock exclusive |
數字越大鎖級別越高, 影響的操做越多。通常的查詢語句如select ... from ... ;是小於2的鎖, 有時會在v$locked_object出現。select ... from ... for update; 是2的鎖。
當對話使用for update子串打開一個遊標時,全部返回集中的數據行都將處於行級(Row-X)獨佔式鎖定,其餘對象只能查詢這些數據行,不能進行update、delete或select...for update操做。insert / update / delete ... ; 是3的鎖。
沒有commit以前插入一樣的一條記錄會沒有反應, 由於後一個3的鎖會一直等待上一個3的鎖, 咱們必須釋放掉上一個才能繼續工做。
建立索引的時候也會產生3,4級別的鎖。locked_mode爲2,3,4不影響DML(insert,delete,update,select)操做, 但DDL(alter,drop等)操做會提示ora-00054錯誤。有主外鍵約束時 update / delete ... ; 可能會產生4,5的鎖。DDL語句時是6的鎖。
若是出現了鎖的問題, 某個DML操做可能等待好久沒有反應。當你採用的是直接鏈接數據庫的方式,也不要用OS系統命令 $kill process_num 或者 $kill -9 process_num來終止用戶鏈接,由於一個用戶進程可能產生一個以上的鎖, 殺OS進程並不能完全清除鎖的問題。記得在數據庫級別用alter system kill session 'sid,serial#';殺掉不正常的鎖。
示例:
我按照本身的理解演示的TX,TM鎖以下:
1.create table TMP1(col1 VARCHAR2(50));--建立臨時表
2.select * from v$lock;--關掉當前鎖信息
3.select * from tmp1 for update; --加鎖
4.select * from v$lock; ---看看如今的鎖列表,是否是多了兩條記錄。Type分別爲tx,tm,對照表1。
5.新開一個鏈接,而後
select * from tmp1 for update; --呵呵,等待狀態了吧
6.select * from v$lock; --又新增了兩條記錄,其它一條type=tx,lmode=0
7.查看當前被鎖的session正在執行的sql語句
select /*+ NO_MERGE(a) NO_MERGE(b) NO_MERGE(c) */ a.username, a.machine, a.sid, a.serial#, a.last_call_et "Seconds", b.id1, c.sql_text "SQL"
from v$session a, v$lock b, v$sqltext c
where a.username is not null and a.lockwait = b.kaddr and c.hash_value =a.sql_hash_value
8.將以前的for update語句commit或者rollback,而後新開鏈接的session擁有鎖。有興趣的朋友還能夠試試兩條for update的時候,關閉先執行的那個窗口,看看oracle會給出什麼樣的響應。
這一節是我在自整理v$系列視圖以來花費時間和精力最多的一個,我反覆看了document,又從網上搜索了各類資料實際使用案例等,就是不開竅。這一節至今我也仍未有把握說盡在掌握,因此在上述文字中除了例子,我如實貼出了收集來的內容,未加任何自我理解,就是擔憂萬一個人理解有誤,會對其它瀏覽本文的人形成困擾。同時我把在收集過程當中自我感受對理解v$lock可能有幫助的資料地址列出,供有心人蔘考:
Oracle數據庫中的鎖機制研究
http://soft.zdnet.com.cn/software_zone/2007/0208/377403.shtml
DB2和 Oracle的併發控制(鎖)比較
http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0512niuxzh/
Itpub論壇的oracle專題深刻討論區也有一篇很是精彩的討論,地址以下:
我對ORACLE數據鎖的一點體會
http://www.itpub.net/270059.html
學習動態性能表
第八篇-(2)-V$LOCKED_OBJECT 2007.6.4
本視圖列出系統上的每一個事務處理所得到的全部鎖。
V$LOCKED_OBJECT中的列說明:
示例:
1.以DBA角色, 查看當前數據庫裏鎖的狀況能夠用以下SQL語句:
select object_id,session_id,locked_mode from v$locked_object;
select t2.username, t2.sid, t2.serial#, t2.logon_time
from v$locked_object t1, v$session t2
where t1.session_id = t2.sid order by t2.logon_time;
若是有長期出現的一列,多是沒有釋放的鎖。咱們能夠用下面SQL語句殺掉長期沒有釋放非正常的鎖:
alter system kill session 'sid,serial#';