oracle官网当一个用户发出select..for update的错作准备对返回的结果集进行修改时,如果结果集已经被另一个会话锁定,就是发生阻塞。需要等另一个会话结束之后才可继续执行。可以通过发出 select… for update nowait的语句来避免发生阻塞,如果资源已经被另一个会话锁定,则会返回以下错误:Ora-00054:resource busy and acquire with nowait specified.
database运行变慢(transaction事务比较慢):v$session_wait(有无等待事件event:enq(tx,tm))--v$lock(有无排他exclusive lock session)--sqlarea
oracle官网死锁-deadlock
定义:当两个用户希望持有对方的资源时就会发生死锁.
即两个用户互相等待对方释放资源时,oracle认定为产生了死锁,在这种情况下,将以牺牲一个用户作为代价,另一个用户继续执行,牺牲的用户的事务将回滚.
oracle官网例子:
1:用户1对A表进行Update,没有提交。
2:用户2对B表进行Update,没有提交。
此时双反不存在资源共享的问题。
3:如果用户2此时对A表作update,则会发生阻塞,需要等到用户一的事物结束。
4:如果此时用户1又对B表作update,则产生死锁。此时Oracle会选择其中一个用户进行会滚,使另一个用户继续执行操作。
oracle官网起因:
Oracle的死锁问题实际上很少见,如果发生,基本上都是不正确的程序设计造成的,经过调整后,基本上都会避免死锁的发生。
DML锁分类表表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
oracle官网1.关于V$lock表和相关视图的说明
Column Datatype Description
ADDR RAW(4 | 8) Address of lock state object
KADDR RAW(4 | 8) Address of lock
SID NUMBER Identifier for session holding or acquiring the lock
TYPE VARCHAR2(2) Type of user or system lock
The locks on the user types are obtained by user applications. Any process that is blocking others is likely to be holding one of these locks. The user type locks are:
TM - DML enqueue
TX - Transaction enqueue
UL - User supplied
--我们主要关注TX和TM两种类型的锁
--UL锁用户自己定义的,一般很少会定义,基本不用关注
--其它均为系统锁,会很快自动释放,不用关注
ID1 NUMBER Lock identifier #1 (depends on type)
ID2 NUMBER Lock identifier #2 (depends on type)
---当lock type 为TM时,id1为DML-locked object的object_id
---当lock type 为TX时,id1为usn+slot,而id2为seq。
--当lock type为其它时,不用关注
LMODE NUMBER Lock mode in which the session holds the lock:
0 - none
1 - null (NULL)
2 - row-S (SS)
3 - row-X (SX)
4 - share (S)
5 - S/Row-X (SSX)
6 - exclusive (X)
--1.查看处于被锁状态的表
SELECT a.object_id,
a.session_id,
b.object_name
FROM v$locked_object a,
dba_objects b
WHERE a.object_id = b.object_id
--2.查出锁定object的session的信息以及被锁定的object名
SELECT l.session_id sid,
s.serial#,
l.locked_mode,
l.oracle_username,
l.os_user_name,
s.machine,
s.terminal,
o.object_name,
s.logon_time
FROM v$locked_object l,
all_objects o,
v$session s
WHERE l.object_id = o.object_id
AND l.session_id = s.sid
ORDER BY sid,
s.serial#;
--2.1查出锁定的object的session信息(指定object_name)
SELECT l.session_id sid,
s.serial#,
l.locked_mode,
l.oracle_username,
l.os_user_name,
s.machine,
s.terminal,
o.object_name,
s.logon_time
FROM v$locked_object l, all_objects o, v$session s
WHERE l.object_id = o.object_id
AND l.session_id = s.sid
and o.object_name = 'ZZOM_SEND_EMAIL'
ORDER BY sid, s.serial#;
--3.查出锁定表的session的sid, serial#,os_user_name, machine name, terminal和执行的语句
--比上面那段多出sql_text和action
SELECT l.session_id sid,
s.serial#,
l.locked_mode,
l.oracle_username,
s.user#,
l.os_user_name,
s.machine,
s.terminal,
a.sql_text,
a.action
FROM v$sqlarea a,
v$session s,
v$locked_object l
WHERE l.session_id = s.sid
AND s.prev_sql_addr = a.address
ORDER BY sid,
s.serial#;
--4.查出锁定表的sid, serial#,os_user_name, machine_name, terminal,锁的type,mode
SELECT s.sid,
s.serial#,
s.username,
s.schemaname,
s.osuser,
s.process,
s.machine,
s.terminal,
s.logon_time,
l.type
FROM v$session s,
v$lock l
WHERE s.sid = l.sid
AND s.username IS NOT NULL
ORDER BY sid;
V$locked_Object和dba_objects用object_id可以关联起来,找到dba_objects.object_name,
V$session的Sid和V$locked_object的session_id内联起来,可以从V$session中的machine找到机器名。进而找到机器。
使用alter system kill session 'sid,serial#'
select V$session.sid,V$session.machine,dba_objects.object_Name
from V$session.sid inner join V$locked_object on V$session.sid=V$locked_object.session_id
inner join dba_objects on dba_objects.object_id = V$locked_object.object_id;
-----------------------------------------------------------------------------------------------------------------------
招数一:
1. 查看被锁的表:
2. select p.spid,c.object_name,b.session_id,b.oracle_username,b.os_user_name from v$process p,v$session a, v$locked_object b,all_objects c where p.addr=a.paddr and a.process=b.process and c.object_id=b.object_id
3.
4. 解锁:
5. alter system kill session '146';(其中146为锁住的进程号)
招数二:
1. SELECT sn.username, m.SID,sn.SERIAL#, m.TYPE,
2. DECODE (m.lmode,
3. 0, 'None',
4. 1, 'Null',
5. 2, 'Row Share',
6. 3, 'Row Excl.',
7. 4, 'Share',
8. 5, 'S/Row Excl.',
9. 6, 'Exclusive',
10. lmode, LTRIM (TO_CHAR (lmode, '990'))
11. ) lmode,
12. DECODE (m.request,
13. 0, 'None',
14. 1, 'Null',
15. 2, 'Row Share',
16. 3, 'Row Excl.',
17. 4, 'Share',
18. 5, 'S/Row Excl.',
19. 6, 'Exclusive',
20. request, LTRIM (TO_CHAR (m.request, '990'))
21. ) request,
22. m.id1, m.id2
23. FROM v$session sn, v$lock m
24. WHERE (sn.SID = m.SID AND m.request != 0) --存在锁请求,即被阻塞
25. OR ( sn.SID = m.SID --不存在锁请求,但是锁定的对象被其他会话请求锁定
26. AND m.request = 0
27. AND lmode != 4
28. AND (id1, id2) IN (
29. SELECT s.id1, s.id2
30. FROM v$lock s
31. WHERE request != 0 AND s.id1 = m.id1
32. AND s.id2 = m.id2)
33. )
34. ORDER BY id1, id2, m.request;
35.
36. alter system kill session '91';
37. alter system kill session '144,633';
38. alter system kill session '91,21';
39. alter system kill session '112,5772';
oracle 查看死锁的脚本
select * from v$lock ,dba_objects,v$session where object_id=v$lock.id1 and v$lock.sid=v$session.sid