转载至http://blog.sina.com.cn/s/blog_1536e8bba0102vrsk.html
要解决oralce中的锁冲突,首先必须要知道以下字段的含义:
1.saddr(session address):表示当前记录的内存地址。
2.paddr(processaddress):表示session对应的进程地址,对应v$process中的addr字段。
3.taddr(transactionaddress):表示当前事物有关的地址,关联v$transaction表的addr字段。
4.serial#:表示sid的序列号,可能有些sid的回话相同,sid可以重复使用。(个人理解用于区别不同的回话)
5.sid(session id):回话id。
6.spid(serverprocess id):操作系统进程id。
当我们发现一个表被锁住之后,我们应该如何解决锁冲突??
1.首先查看被锁的信息,得到锁住表的回话的sid,serial#。
SQL> select t2.username,t2.sid,t2.serial#,t2.logon_time
from v$locked_object t1,v$session t2
where t1.session_id=t2.sid;
2.确定回话无用之后,在oracle层面杀死当前回话。
SQL> alter system kill session 'sid,serial#' immediate;
3.被杀掉的回话会被标记为killed.可通过以下语句查看会话状态。
SQL> select saddr,sid,serial#,paddr,username,status from v$session(where username is not null);
实际上在oracle中杀死会话,oracle只是简单的把paddr指向了同一个虚拟的地址。此时v$session和v$process就失去了关联,然后等待oracle的PMON进程去清除这些回话。
4.有时我们可能需要再操作系统的层面去杀死这些会话,就需要知道会话对应进程的paddr,可以通过下面的命令查询会话对应进程的paddr。(下面语句有待确认)
SQL> SELECTs.username,s.status,
x.ADDR,x.KSLLAPSC,x.KSLLAPSN,x.KSLLASPO,x.KSLLID1R,x.KSLLRTYP,
decode(bitand (x.ksuprflg,2),0,null,1)
FROM x$ksupr x,v$session s
WHERE s.paddr(+)=x.addr
and bitand(ksspaflg,1)!=0;
简化一点就是下面的命令:(下面语句有待确认)
SQL> select p.addr from v$process p where pid<>1
minus
select s.paddr from v$session s;
在获得了进程地址paddr后,就可以在v$process中找到spid,然后使用kill来杀死这些进程。
额外知识点:在linux下如何杀死进程。
kill -9 进程id
-9:强制进程立即停止,并且不实施清理操作。