鎖分析
在資料庫運維工作中,有相當大一部分工作跟鎖有關。
鎖用對了地方能保證資料一致性,用錯了地方就能導致併發性下降。
下面來講解資料庫發生鎖,該如何進行診斷:
首先將幾個鎖相關的檢視:
v$lock
v$lock_object
v$session
dba_objects
v$processes
v$sql
1、v$lock
type:TM 表鎖 或者DML鎖
TX 行鎖 事務鎖
lmode:會話保持的鎖模式
0 = none
1 = null
2 = Row-S(SS 行級共享鎖 ,只能查詢這些物件)
3 = Row-X(行級排他鎖,在提交前不允許修改)
4 = Share(共享鎖)
5 = S/ROW-X(共享行級排他鎖)
6 = Exclusive(排他鎖)
ID1,ID2 根據Type取值不同而不同。
對於type=TM表級鎖或者DML鎖, ID1表示被鎖定表的object_id,ID2 為0 ;
對於type=TX事務鎖,ID1表示高事務所佔用的回滾段及事務槽,ID2表示為 環繞warp次數,即事務槽被重用的次數
REQUEST:表示會話請求鎖型別
block:表示堵塞了別的會話對該鎖物件的請求次數,重點關注大於 1 ,等待鎖型別由lmode決定,
SQL> select addr,kaddr,sid,type,id1,id2,lmode,request,block from v$lock where type in ('TX','TM'); ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST BLOCK ---------------- ---------------- ---------- ---- ---------- ---------- ---------- ---------- ---------- 000007FF5EC570F0 000007FF5EC57148 8 TX 589848 1189 0 6 0 000000001FCCDA30 000000001FCCDA90 8 TM 74686 0 3 0 0 000000001FCCDA30 000000001FCCDA90 73 TM 74686 0 3 0 0 000007FF5ACD8880 000007FF5ACD88F8 73 TX 589848 1189 6 0 1
73 會話持有TX鎖,鎖型別類6(排他鎖),堵塞別人1次;
8 會話持有TX鎖,鎖型別為0,請求6號鎖,;
從ID1,ID2可知 這兩個事務請求的物件都一樣,可見 73堵塞了8。
到底鎖發生的物件是哪個?可以檢視
可以看到一點,lmode = 0 表示會話沒有持有鎖,但是 很有可能被別的會話給堵塞了,具體要REQUEST 欄位和ID1,ID2欄位
死鎖查詢:
select a.sid,holdsid,b.sid,a.type,a.id1,a.id2,a.ctime from v$lock a,v$lock b where a.id1=b.id1 and a.id2=b.id2 and a.block > =1 and b.bllck =0;
查詢TM表鎖物件:
select object_name from dba_objects o ,v$lock l where l.ID1=o.object_id and l.TYPE='TM';
查詢TX鎖物件:
select ss.EVENT,ss.SID,ss.SERIAL#,ss.PADDR,ss.ROW_WAIT_OBJ#,obj.object_name from v$session ss ,
dba_objects obj,v$lock l where ss.ROW_WAIT_OBJ#=obj.object_id and ss.SID=l.SID and l.KADDR=ss.LOCKWAIT;
SQL> select ss.EVENT,ss.SID,ss.SERIAL#,ss.PADDR,ss.ROW_WAIT_OBJ#,obj.object_name from v$session ss ,
2 dba_objects obj,v$lock l where ss.ROW_WAIT_OBJ#=obj.object_id and ss.SID=l.SID and l.KADDR=ss.LOCKWAIT
3 ;
EVENT SID SERIAL# PADDR ROW_WAIT_OBJ# OBJECT_NAME
-------------------------------- ------- ---------- ---------------- ------------- ---------------
enq: TX - row lock contention 8 36 000007FF5E4D9DE0 74686 TEST1
或者
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"
2 from v$session a, v$lock b, v$sqltext c
3 where a.username is not null and a.lockwait = b.kaddr and c.hash_value =a.sql_hash_value
4 ;
USERNAME MACHINE SID SERIAL# Seconds ID1 SQL
-------- ----------------------------- ------- ---------- ---------- ---------- ----------------------------------------------------------------
SYS WORKGROUP\PC201812010809 8 36 10863 589848 update test1 set object_id=object_id+1 where object_id=1900
不知道大家有沒有感覺得在資料庫通過‘ alter system kill session 'sid,serial#' immediate;'’殺會話,有時候殺不掉,這個時候我們可以通過OS系統 pid 來殺 pkill -9 SID
SQL> select a.spid,a.PID,a.username,b.program,b.SID,b.SERIAL# from v$process a,v$session b,v$lock c where a.addr=b.paddr and c.SID=b.SID and c.TYPE in ('TX','TM');
SPID PID USERNAME PROGRAM SID SERIAL#
------- ---------- --------------- --------------------------
8964 20 SYSTEM sqlplus.exe 8 36
8964 20 SYSTEM sqlplus.exe 8 36
10368 49 SYSTEM sqlplus.exe 73 2616
10368 49 SYSTEM sqlplus.exe 73 2616
下面來探討一下,誰堵塞了誰?
這個需要檢視v$lock 檢視,block表示堵塞別人次數,只要block>1就比是堵塞了別人,有死鎖。
REQUEST 表示這個SID請求鎖型別,LMODE表示SID持有鎖型別,對於排他鎖而言,一旦持有排它鎖,那麼就堵塞了別人的會話,。
2、 v$locked_object
This view lists all locks acquired by every transaction on the system. It shows which sessions are holding DML locks (that is, TM-type enqueues) on what objects and in what mode.
只包含DML的鎖資訊,包括回滾段和會話的資訊。所以v$lock_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 logon_time
總結:
其它相關檢視說明
檢視名 描述 主要欄位說明
v$session 查詢會話的資訊和鎖的資訊。
sid,serial#:表示會話資訊。
program:表示會話的應用程式資訊。
row_wait_obj#:表示等待的物件,和dba_objects中的object_id相對應。
lockwait :該會話等待的鎖的地址,與v$lock的kaddr對應.
v$session_wait 查詢等待的會話資訊。 sid:表示持有鎖的會話資訊。
Seconds_in_wait:表示等待持續的時間資訊
Event:表示會話等待的事件,鎖等於enqueue
dba_locks 對v$lock的格式化檢視。
Session_id:和v$lock中的Sid對應。
Lock_type:和v$lock中的type對應。
Lock_ID1: 和v$lock中的ID1對應。
Mode_held,mode_requested:和v$lock中的lmode,request相對應。
v$locked_object 只包含DML的鎖資訊,包括回滾段和會話資訊。
Xidusn,xidslot,xidsqn:表示回滾段資訊。和v$transaction相關聯。
Object_id:表示被鎖物件標識。
Session_id:表示持有鎖的會話資訊。
Locked_mode:表示會話等待的鎖模式的資訊,和v$lock中的lmode一致。