在oracle中查找有多少表被锁住的方法:
select b.owner table_owner,b.object_name,c.username,c.sid,c.serial#
from v$locked_object a,dba_objects b,v$session c
where a.object_id=b.object_id and c.sid=a.session_id;
这样根据sid和serial#就可以直接杀掉(具体方法下面介绍)
查找一个表是否被锁的方法,例如:临时表SHZGY.SHZGY_PZ_BB_ERROR1
select object_id, owner||'.'||object_name object_name
from dba_objects
where owner='SHZGY'
and object_name like 'SHZGY_PZ_BB_ERROR1';
OBJECT_ID OBJECT_NAME
---------- ----------------------------------
105421 SHZGY.SHZGY_PZ_BB_ERROR1
找出该表的id1。
select * from v$lock where id1 = 105421;
ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
-------- -------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
A08E1304 A08E1314 29 TO 105421 1 3 0 1209396 0
A08D4904 A08D4914 30 TO 105421 1 3 0 1295439 0
A08E1188 A08E1198 32 TO 105421 1 3 0 1284027 0
A08E12B8 A08E12C8 77 TO 105421 1 3 0 1209674 0
A08E11D4 A08E11E4 120 TO 105421 1 3 0 1280668 0
A08E1350 A08E1360 144 TO 105421 1 3 0 1209330 0
A08E1220 A08E1230 151 TO 105421 1 3 0 1279593 0
已选择7行。
说明有七个会话锁住该临时表。
如果可以kill,就可以 drop table shzgy.shzgy_pz_bb_error1;
select a.sid, a.SERIAL#, b.spid, a.status, a.PROGRAM
from v$session a, V$PROCESS b
where a.sid in (29, 30, 32, 77, 120, 144, 151)
and a.paddr=b.ADDR
order by a.sid;
SID SERIAL# SPID STATUS PROGRAM
---------- ---------- ------------ -------- ------------------------
29 619 9738 INACTIVE JDBC Thin Client
30 47 7608 INACTIVE JDBC Thin Client
32 148 8014 INACTIVE JDBC Thin Client
77 198 9736 INACTIVE JDBC Thin Client
120 258 8204 INACTIVE JDBC Thin Client
144 17 9762 INACTIVE JDBC Thin Client
151 253 8232 INACTIVE JDBC Thin Client
这七个会话都是JDBC调用,status=INACTIVE。
然后根据这些调用和活动状态判断是否可以kill掉这些session。
如果可以就直接kill掉这些session:
使用dbms_system.set_sql_trace_in_session包来对这个session进行trace:
SQL > alter system kill session 'sid,SERIAL#' immediate;
这时这些session的状态就被标记为killed,Oracle会在该用户下一次touch时清除该进程。
我们发现当一个session被kill掉以后,该session的paddr被修改,如果有多个session被kill,那么多个session的paddr都被更改为相同的进程地址:
SQL> select saddr,sid,serial#,paddr,username,status from v$session where username is not null;
SADDR SID SERIAL# PADDR USERNAME STATUS
-------- ---------- ---------- -------- ------------------------------ --------
542E0E6C 11 314 542B70E8 EYGLE INACTIVE
542E5044 18 662 542B6D38 SYS ACTIVE
SQL> alter system kill session '11,314';
System altered.
SQL> select saddr,sid,serial#,paddr,username,status from v$session where username is not null;
SADDR SID SERIAL# PADDR USERNAME STATUS
-------- ---------- ---------- -------- ------------------------------ --------
542E0E6C 11 314 542D6BD4 EYGLE KILLED
542E5044 18 662 542B6D38 SYS ACTIVE
SQL> select saddr,sid,serial#,paddr,username,status from v$session where username is not null;
SADDR SID SERIAL# PADDR USERNAME STATUS
-------- ---------- ---------- -------- ------------------------------ --------
542E0E6C 11 314 542D6BD4 EYGLE KILLED
542E2AA4 14 397 542B7498 EQSP INACTIVE
542E5044 18 662 542B6D38 SYS ACTIVE
SQL> alter system kill session '14,397';System altered.
SQL> select saddr,sid,serial#,paddr,username,status from v$session where username is not null;
SADDR SID SERIAL# PADDR USERNAME STATUS
-------- ---------- ---------- -------- ------------------------------ --------
542E0E6C 11 314 542D6BD4 EYGLE KILLED
542E2AA4 14 397 542D6BD4 EQSP KILLED
542E5044 18 662 542B6D38 SYS ACTIVE
在这种情况下,很多时候,资源是无法释放的,我们需要查询spid,在操作系统级来kill这些进程.
方法:一个session会对应着操作系统中相应的一个进程(process),我们不使用Alter system kill session这种方式了,取而代之则是kill的方式,当session的后台进程被杀掉了,便会促使懒散的Pmon进程迅速进行清理工作。
以一个session做以示例,
a、 找到你要杀掉的那个session, 并记下paddr
b、 找到这个session所对应的spid
c、 杀掉spid所标识的那个进程
♀如果你的Oracle是在Unix平台上的,可以用kill。
$kill 13824
♀如果你的Oracle是在windown平台上的,有一些的不同,因为windown是以thead来代替process的,需要用到sid和spid两个值,所用的命令也由kill替换为Orakill,格式为:orakill sid spid
C:\>orakill 941 13824
d、 再查一下v$session,看会话在不在了。