昨天的时候,发现几个表被锁住了,
我用
 select     s.sid,s.machine,o.object_name,l.oracle_username,l.locked_mode,       
  'ALTER     SYSTEM     KILL     SESSION     '''||s.sid||',     '||s.serial#||''';'     Command       
  from     v$locked_object     l,v$session     s,all_objects     o       
  where     l.session_id=s.sid     and     l.object_id=o.object_id;   
这条语句查了一下,sid显示是478,机器名是A001。
我看了一下session里,sid为478的session状态是inactive,从locks里(pl/sql)里也看到未锁任何表。然后我就在session里,右键,kill,kill完了以后,过了一会儿,session里就没有sid为478的记录了。
但我用上面的SQL语句查,这几个表还是被锁着的,sid还是显示为478。我想,有可能sessoin被kill后,要等一段时间才会把锁的表释放掉,因此我就又等了二十分钟,结果SQL语句执行出来,还是被锁,对这些表进行增删改操作也还是不行。
我到服务器上,执行alter system kill session 要。sid 478, s.serial#12345,告诉我说是sid为478的session已经不存在了。这几张表很关键,直接影响现场操作,因此我当时只好重启服务器了。我用的数据库是10.2.0.1.0,哪位大虾指点一下呀,以后碰到这种情况,怎么样才能把这些锁的表释放出来呀?

解决方案 »

  1.   

    死锁啊,不能靠手工去释放的(下次还会来,你受不了的),一般来说,主要是子表的外键没有建索引引起来的,你把子表的外键字段建上索引就可以了,用下面的语句查询是不是子表的外键字段没有建立索引:select acc.OWNER,
           acc.table_name,
           acc.CONSTRAINT_NAME,
           acc.COLUMN_NAME,
           acc.POSITION,
           'No Index' Problem
      from dba_cons_columns acc, dba_constraints ac
     where ac.CONSTRAINT_NAME = acc.CONSTRAINT_NAME
       and ac.CONSTRAINT_TYPE = 'R'
       and acc.OWNER = 'NBGL'   --这里是你的用户名
       and not exists (select 'TRUE'
              from dba_ind_columns b
             where b.TABLE_OWNER = acc.OWNER
               and b.TABLE_NAME = acc.TABLE_NAME
               and b.COLUMN_NAME = acc.COLUMN_NAME
               and b.COLUMN_POSITION = acc.POSITION)
     order by acc.OWNER, acc.CONSTRAINT_NAME, acc.COLUMN_NAME, acc.POSITION
      

  2.   

    另外一种很大的可能引起死锁是bitmap索引(这个索引很好,但是有负作用),你网上查一下怎么解决,资料很多的
      

  3.   

    看哪些session阻碍了其他的sessionSELECT (select username FROM v$session WHERE sid=a.sid) blocker,
           a.sid,
           'is blocking',
           (select username FROM v$session WHERE sid=b.sid) blockee,
           b.sid
      FROM v$lock a, v$lock b
     WHERE a.block = 1
       AND b.request > 0
       AND a.id1 = b.id1
       AND a.id2 = b.id2
    /杀死这些session就ok了
      

  4.   

    lz已经在数据库中kill过session了。这个解决方法就是在os层面kill对应process就行了。设置sqlnet.expire_time也能解决
      

  5.   

    to majy:
      这些被锁的表没有使用任何外键,也没有建任何的bitmap索引的。
      

  6.   

    “在os层面kill对应process就行”
    在os层面已经没有对应的process了,怎么kill哇?
      

  7.   

    还是想办法查找程序的问题吧,这种事情发生了一次就肯定会发生第二次,不找到问题,你就得一直守在数据库服务器边上了:-)如果不是外键和bitmap索引引起,那么可以肯定是程序写的业务逻辑引起的,这种情况下,程序问题应该是比较好找的,把相互使用这些表的程序代码都检索出来,看看发生了什么事情