在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,看会话在不在了。

posted on 2012-10-18 10:58  骑牛射雕  阅读(1439)  评论(0编辑  收藏  举报