一、oracle的鎖
鎖的做用:保護數據,解決併發問題,後臺及大量的前臺進程同時訪問SGA,須要保持數據的一致性,由於有鎖
纔有併發,由於鎖限制了併發。
應用級鎖:對錶等資源進行鎖定,保證業務邏輯正確性;
數據字典鎖:oracle內核程序用於保證數據字典邏輯正確性;
內存控制鎖:保護oracle內部數據結構的鎖(latch,mutex);
latch鎖:chain,鏈,多個sp對鏈進行訪問致使latch爭用,經過簡單的底層技術實現,不使用隊列機制,十分高效
一個latch能夠保護多個內存區域,但一個內存區域只能有一個latch
mutex:比latch開銷更小,效率高,
二、LOCK鎖:保護數據塊,數據行
排他鎖(X):A訪問後加鎖,B不能夠訪問不能對它讀取和修改
經過lock table in exclusive mode命令添加X鎖
共享鎖(S):A訪問後加鎖,B也能夠讀取,但不能修改
經過lock table in share mode命令添加該S鎖
DML鎖(data locks,數據鎖),用於保護數據的完整性;
DDL鎖(dictionary locks,字典鎖),用於保護數據庫對象的結構,如表、索引等的結構定義;
內部鎖和閂(internal locks and latches),保護 數據庫的內部結構。html
三、行級鎖:DML語句,數據行上加鎖標記,鎖的粒度越小,併發性越好,sqlserver的鎖粒度是數據塊
oracle併發性好的緣由:對數據行的修改,不影響該數據行所在的塊,及另外事務對該行數據的訪問(構造CR塊),
事務鎖TX:由於行級鎖產生,一個事務一個事務鎖,加在行上
鎖的結構
事務鎖的加鎖和解鎖過程:commit,rollback解鎖,DML加鎖
只有排他鎖:不影響讀(CR塊)
Latch與lock的異同
閂鎖(Latch)是一個低級別、輕量級的鎖,得到和釋放的速度很快。能夠簡單地理解爲閂鎖是微觀領域的,而lock
則是宏觀領域的。latch是用於保護SGA區中共享數據結構的一種串行化鎖定機制。它不單單用於buffer cache, 還用於
shared pool以及log buffer等。Latch 不會形成阻塞,只會致使等待。Latch是對內存數據結構提供互斥訪問的一種機
制,而Lock是以不一樣的模式來套取共享資源對象,各個模式間存在着兼容或排斥,從這點看出,Latch的訪問,包括查詢
也是互斥的,任什麼時候候,只能有一個進程能pin住內存的某一塊。
Latch只做用於內存中,他只能被當前實例訪問,而Lock做用於數據庫對象,在RAC體系中實例間容許Lock檢測與訪問
Latch是瞬間的佔用,釋放,Lock的釋放須要等到事務正確的結束,他佔用的時間長短由事務大小決定
Latch是非入隊的,而Lock是入隊的
Latch不存在死鎖,而Lock中存在。
四、表級鎖:TM,爲了標註事務對錶的操做
行級排他鎖(Row exclusive)RX鎖:因對錶修改產生的,可加多個RX鎖
鎖的兼容性:鎖怎麼產生,最小限度的減少鎖的粒度,目的最大限度的減小鎖的影響
A修改一行數據:會在行上加行級X鎖,事務加TX鎖,表上加TM鎖RX
B刪除A修改的數據表:須要在表上加X鎖,先看是否有RX,X鎖與RX互斥
當咱們進行DML時,會自動在被更新的表上添加RX鎖
容許其餘事務經過DML語句修改相同表裏的其餘數據行
容許使用lock命令對錶添加RX鎖定
不容許其餘事務對錶添加X鎖
行級共享鎖(Row Shared,簡稱RS鎖)
select … from for update --悲觀鎖
與DML同樣,以DML方式讀取,加RS鎖與RS鎖加再同一行數據時互斥
五、鎖的兼容性
六、加鎖語句以及鎖的釋放
lock table table_name in [row share][row exclusive][share][share row exclusive][exclusive] mode;
七、鎖相關視圖
查詢會話已得到的鎖和正在請求的鎖 v$lock
select * from v$lock t;
記錄了session已經得到的鎖定以及正在請求的鎖定的信息
SID:說明session的ID號
TYPE:說明鎖定鎖定級別,主要關注TX和TM
LMODE:說明已經得到的鎖定的模式,以數字編碼表示
REQUEST:說明正在請求的鎖定的模式,以數字編碼表示
BLOCK:說明是否阻止了其餘用戶得到鎖定,大於0說明是,等於0說明否
對於TM鎖來講,ID1表示被鎖定的對象的對象ID,ID2始終爲0s
對於TX鎖來講,ID1表示事務使用的回滾段編號以及事務表中對應的記錄編號,ID2表示該記錄編號被重用的次數(wrap)
鎖定模式 鎖定簡稱 編碼數值
Row Exclusive RX 3
Row Shared RS 2
Share S 4
Exclusive X 6
Share Row Exclusive SRX 5
NULL N/A 0或者1
select sid,type,id1,id2,decode(lmode,0,'None',1,'Null',2,'Row share',3,'Row Exclusive',4,'Share',5,
'Share Row Exclusive',6,'Exclusive') lock_mode,decode(request,0,'None',1,'Null',2,'Row share',3,
'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive') request_mode,block
from v$lock where sid=138;
查詢申請鎖定被阻塞的session相關信息 v$enqueue_lock
select addr,kaddr,sid,lmode,request,ctime,block from v$enqueue_lock --ctime比阻塞時間
查詢被鎖定對象及用戶信息 v$locked_object,關聯dba_objects 查詢具體鎖定的對象
select XIDUSN,XIDSLOT,XIDSQN,OBJECT_ID,LOCKED_MODE,process,oracle_username from v$locked_object;
select * from dba_objects where object_id = 51151;
oracle中殺掉一個會話
alter system kill session '77,22198'; --sid,||serial#
查詢v$enqueue_lock來得到鎖定隊列中的session信息
select sid,type, decode(request,0,'None',1,'Null',2,'Row share',3,'Row Exclusive',4,'Share',5,
'Share Row Exclusive',6,'Exclusive') request_mode from v$enqueue_lock where sid in(131,153);
查詢阻塞和被阻塞信息
select a.sid blocker_sid,a.serial#,a.username as blocker_username,b.type,decode(b.lmode,0,'None',1,
'Null',2,'Row share',3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive') lock_mode,
b.ctime as time_held,c.sid as waiter_sid,decode(c.request,0,'None',1,'Null',2,'Row share',3,
'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive') request_mode, c.ctime time_waited
from v$lock b, v$enqueue_lock c, v$session a where a.sid = b.sid and b.id1= c.id1(+) and
b.id2 = c.id2(+) and c.type(+) = 'TX' and b.type = 'TX' and b.block = 1 order by time_held, time_waited;
一個事務修改多行,產生一個TX鎖,多個TM(一條語句一個TM)鎖
select sid from v$mystat where rownum=1;
update employees set last_name=last_name||'a' where department_id=60;
update departments set department_name='unknow' where department_id=10;
update locations set city='unknown' where location_id=1100;sql
select sid,type,id1,id2, decode(lmode,0,'None',1,'Null',2,'Row share',3,'Row Exclusive',4,'Share',5,
'Share Row Exclusive',6,'Exclusive') lock_mode, decode(request,0,'None',1,'Null',2,'Row share',3,
'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive')request_mode,block
from v$lock where sid=153;
能夠得到的TX鎖定的總個數由初始化參數transactions決定,而能夠得到的TM鎖定的個數則由初始化參數dml_locks決定
select name,value from v$parameter where name in('transactions','dml_locks');
查詢當前值,曾經達到的最大值,設置的最大值
select resource_name as "R_N",current_utilization as "C_U",max_utilization as
"M_U",initial_allocation as "I_U" from v$resource_limit
where resource_name in('transactions','dml_locks');數據庫
八、死鎖
兩個session(以A和C來表示),若是A持有C正在申請的鎖定,同時C也持有A正在申請的鎖定時,這時發生死鎖現象。
死鎖是典型的「雙輸」狀況,若是任其發展,則會出現A和C這兩個session正在執行的事務都沒法結束的現象。所以,在
Oracle數據庫中,形成死鎖的那個DML語句會被撤銷。死鎖老是因爲應用程序設計不合理引發的。當某個session的事務引
起了死鎖時,Oracle會自動二次將阻塞該事務的事務撤銷,被阻塞事務繼續等待。
session 1
select sid from v$mystat where rownum=1;
update employees set last_name=last_name||'a' where employee_id between 101 and 105;
session 2
select sid from v$mystat where rownum=1;
update employees set last_name=last_name||'b' where employee_id between 106 and 120;
session 1
update employees set last_name=last_name||'c' where employee_id between 106 and 125;
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
session 2
update employees set last_name=last_name||'d' where employee_id between 95 and 104;
死鎖發放生後會生成
cd /u01/app/oracle/admin/ipemsdb/bdump/alert_ipemsdb.log --總日誌裏有死鎖信息
ORA-00060: Deadlock detected. More info in file /u01/app/oracle/admin/ipemsdb/udump/ipemsdb_ora_20431.trc.session
參考資料:
http://www.poluoluo.com/jzxy/201010/95955.html
http://www.cnblogs.com/sopost/archive/2011/11/17/2253352.html數據結構