Oralce解鎖表

轉載:http://blog.sina.com.cn/s/blog_701218960100l0ij.html

今天把DataStage導一個大表,一不小心把表給鎖住了........

      其實解鎖並不複雜,用PL/SQL可以很方便解鎖,可以用兩種方式得到目前被鎖住的表。第一種是,直接從,Tools->Session裏面查看,裏面有很多的Session和進程,下面有一個Lock的Tab,選中那個Tab,然後一條一條地去上面Session,如果Lock這一欄有數據,就說明被鎖住了,在Objec_Name裏面可以看到表名。

      如果是自己的表,可以得到Sid和Serial#,接着執行以下語句就可以解鎖:

      alter system kill session 'sid,serial#';

     第二種方法是用語句得到詳細的被鎖住的表的信息,語句如下:


SELECT s.username,
decode(l.type,'TM','TABLE LOCK',
'TX','ROW LOCK',
NULL) LOCK_LEVEL,
o.owner,o.object_name,o.object_type,
s.sid,s.serial#,s.terminal,s.machine,s.program,s.osuser
FROM v$session s,v$lock l,dba_objects o
WHERE l.sid = s.sid
AND l.id1 = o.object_id(+)
AND s.username is NOT Null



----以上爲引用,下面是自己的方法



查看錶是否鎖住
select *
  from dba_lock a
 where a.lock_id1 in
       (select t.object_id
          from dba_objects t
         where t.object_name = 'B_F_GL_BASE_STDC_AMT_ACC_A')

SELECT
   s.username,
   decode(l.type, 'TM', 'TABLE LOCK', 'TX', 'ROW LOCK', NULL) LOCK_LEVEL,
   o.owner,
   o.object_name,
   o.object_type,
   s.sid,
   s.serial#,
   s.STATUS,
   s.terminal,
   s.machine,
   s.program,
   s.osuser,
   s.LOGON_TIME,
   l.BLOCK
  FROM v$session s, v$lock l, dba_objects o
 WHERE l.sid = s.sid
   AND l.id1 = o.object_id(+)
   AND s.username is NOT NULL
   and l.BLOCK=1 --是否是死鎖

--查詢誰鎖定,誰等待
SELECT
 lpad(' ', decode(l.xidusn, 0, 3, 0)) || l.oracle_username User_name,
 o.owner,
 o.object_name,
 o.object_type,
 s.sid,
 s.serial#
  FROM v$locked_object l, dba_objects o, v$session s
 WHERE l.object_id = o.object_id
   AND l.session_id = s.sid
 ORDER BY o.object_id, xidusn DESC;
果發生了鎖等待,我們可能更想知道是誰鎖了表而引起誰的等待
以上的語句可以查詢到誰鎖了表,而誰在等待。
以上查詢結果是一個樹狀結構,如果有子節點,則表示有等待發生。
如果想知道鎖用了哪個回滾段,還可以關聯到V$rollname,其中xidusn就是回滾段的USN
找出誰鎖定的記錄,kill掉就行了。
   -----------------------

Oracle殺死死鎖進程

先查看哪些表被鎖住了:
1獲得sid
select b.owner,
       b.object_name,
       a.session_id,
       a.locked_mode from v$locked_object a,
       dba_objects b where b.object_id = a.object_id;
##########
2獲得sid,serial
select b.username, b.sid, b.serial#, logon_time
  from v$locked_object a, v$session b
 where a.session_id = b.sid
 order by b.logon_time
3殺
alter system kill session 'sid,serial';
如果有ora-00031錯誤,則在後面加immediate;alter system kill session '29,5497' immediate;
--殺數據庫進程(數據庫服務器的機子)
SELECT a.username, c.spid AS os_process_id, c.pid AS oracle_process_id
  FROM v$session a, v$process c
 WHERE c.addr = a.paddr
   and a.sid ='1392'
   and a.serial# ='10858';


補註:如果在數據庫級別kill不掉。還可以在OS級別kill (方法簡單明瞭)

1.下面的語句用來查詢哪些對象被鎖:

select object_name,machine,s.sid,s.serial# 
from v$locked_object l,dba_objects o ,v$session s
where l.object_id = o.object_id and l.session_id=s.sid;

2.下面的語句用來殺死一個進程:
alter system kill session '24,111'; (其中24,111分別是上面查詢出的sid,serial#)

【注】以上兩步,可以通過Oracle的管理控制檯來執行。

3.如果利用上面的命令殺死一個進程後,進程狀態被置爲"killed",但是鎖定的資源很長時間沒有被釋放,那麼可以在os一級再殺死相應的進程(線程),首先執行下面的語句獲得進程(線程)號:
select spid, osuser, s.program 
from v$session s,v$process p
where s.paddr=p.addr and s.sid=24 (24是上面的sid)

4.在OS上殺死這個進程(線程):
1)在unix上,用root身份執行命令
#kill -9 12345(即第3步查詢出的spid)
2)在windows(unix也適用)用orakill殺死線程,orakill是oracle提供的一個可執行命令,語法爲:
orakill sid thread
其中:
sid:表示要殺死的進程屬於的實例名
thread:是要殺掉的線程號,即第3步查詢出的spid。
例:c:>orakill orcl 12345


ORA-00031: session marked for kill


Cause: The session specified in an ALTER SYSTEM KILL SESSION command cannot be killed immediately (because it is rolling back or blocked on a network operation), but it has been marked for kill. This means it will be killed as soon as possible after its current uninterruptible operation is done.

Action: No action is required for the session to be killed, but further executions of the ALTER SYSTEM KILL SESSION command on this session may cause the session to be killed sooner.

 

kill -9 12345


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章