在数据库运维工做中,有至关大一部分工做跟锁有关。sql
锁用对了地方能保证数据一致性,用错了地方就能致使并发性降低。数据库
下面来说解数据库发生锁,该如何进行诊断:session
首先将几个锁相关的视图:并发
v$lock运维
v$lock_objectui
v$sessioncode
dba_objects对象
v$processes事件
v$sql事务
一、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持有锁类型,对于排他锁而言,一旦持有排它锁,那么就堵塞了别人的会话,。
二、 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一致。