oracle殺死死鎖進程 鎖表進程


 

 
 
 一般再pl/sql中常用:kill掉這個死鎖鎖表的進程:

alter system kill session ‘sid,serial#’;

alter system kill session ‘23,678234’;

不行的時候用:

alter system kill session ‘233,1231421’ immediate;

(其中sid=l.session_id)

 

 

oracle殺死死鎖進程 鎖表進程

 

常用處理方式如下:

先查看哪些表被鎖住了

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;


OWNER                          OBJECT_NAME                                 SESSION_ID LOCKED_MODE
------------------------------ --------------------------------------      -------
WSSB                           SBDA_PSHPFTDT                               22           3
WSSB_RTREPOS                   WB_RT_SERVICE_QUEUE_TAB                     24           2
WSSB_RTREPOS                   WB_RT_NOTIFY_QUEUE_TAB                      29           2
WSSB_RTREPOS                   WB_RT_NOTIFY_QUEUE_TAB                      39           2
WSSB                           SBDA_PSDBDT                                 47           3
WSSB_RTREPOS                   WB_RT_AUDIT_DETAIL                          47           3

 

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;

 

USERNAME                              SID    SERIAL# LOGON_TIME
------------------------------ ---------- ---------- -----------
WSSB_RTACCESS                          39       1178 2006-5-22 1
WSSB_RTACCESS                          29       5497 2006-5-22 1


殺會話

alter system kill session 'sid,serial#';

e.g

alter system kill session '29,5497';

如果有ora-00031錯誤,則在后面加immediate;

alter system kill session '29,5497' immediate;

 


-------------

1.查哪個過程被鎖
查V$DB_OBJECT_CACHE視圖:
SELECT * FROM V$DB_OBJECT_CACHE WHERE OWNER='過程的所屬用戶' AND CLOCKS!='0';

2. 查是哪一個SID,通過SID可知道是哪個SESSION.
查V$ACCESS視圖:
SELECT * FROM V$ACCESS WHERE OWNER='過程的所屬用戶' AND NAME='剛才查到的過程名';

3. 查出SID和SERIAL#
查V$SESSION視圖:
SELECT SID,SERIAL#,PADDR FROM V$SESSION WHERE SID='剛才查到的SID'
查V$PROCESS視圖:
SELECT SPID FROM V$PROCESS WHERE ADDR='剛才查到的PADDR';

4. 殺進程
(1).先殺ORACLE進程:
ALTER SYSTEM KILL SESSION '查出的SID,查出的SERIAL#';
(2).再殺操作系統進程:
KILL -9 剛才查出的SPID

ORAKILL 剛才查出的SID 剛才查出的SPID


------------------
oracle的死鎖
查詢數據庫死鎖
select t2.username||'   '||t2.sid||'   '||t2.serial#||'   '||t2.logon_time||'   '||t3.sql_text
      from v$locked_object t1,v$session t2,v$sqltext t3
      where t1.session_id=t2.sid 
      and t2.sql_address=t3.address
      order by t2.logon_time;

查詢出來的結果就是有死鎖的session了,
下面就是殺掉
拿到上面查詢出來的SID和SERIAL#,填入到下面的語句中

alter system kill session 'sid,serial#';

一般情況可以解決數據庫存在的死鎖了,

或通過session id 查到對應的操作系統進程,在unix中殺掉操作系統的進程。
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=  and a.serial#=  ;
然后采用kill (unix) 或 orakill(windows )
 
在unix中
ps -ef|grep os_process_id
kill -9 os_process_id
ps -ef|grep os_process_id

----

經常在oracle的使用過程中碰到這個問題,所以也總結了一點解決方法:)
1)查找死鎖的進程:
sqlplus "/as sysdba"   (sys/change_on_install)
SELECT s.username,l.OBJECT_ID,l.SESSION_ID,s.SERIAL#,l.ORACLE_USERNAME,l.OS_USER_NAME,l.PROCESS 
FROM V$LOCKED_OBJECT l,V$SESSION S WHERE l.SESSION_ID=S.SID; 
2)kill掉這個死鎖的進程:
alter system kill session ‘sid,serial#’;  (其中sid=l.session_id)
3)如果還不能解決,
select pro.spid from v$session ses,v$process pro where ses.sid=XX and ses.paddr=pro.addr;  
 其中sid用死鎖的sid替換。
exit
ps -ef|grep spid
其中spid是這個進程的進程號,kill掉這個Oracle進程。 

 

 

經過以下處理,對於釋放服務器資源,效果非常明顯

 

--查詢死鎖的進程
select   'ALTER  SYSTEM  KILL  SESSION  '''||b.sid||',  '||b.serial#||''';'
from v$access a,v$session b
where a.SID=b.SID
and b.program like 'dis%'
group by b.sid,b.serial#

 

--查詢SID對應的操作系統進程

select spid, osuser, s.program from v$session s,v$process p where
s.paddr=p.addr and s.sid in (54,82,500,195,303,492,496)

--查看操作系統進程

 ps -ef | more

 

--從操作系統殺掉會話不能殺的進程

kill -9 操作系統進程號

 
 
 
 
 
 
 
 
 

 

一般再pl/sql中常用:kill掉這個死鎖鎖表的進程:
alter system kill session ‘sid,serial#’;

alter system kill session ‘23,678234’;

不行的時候用:

alter system kill session ‘233,1231421’ immediate;

(其中sid=l.session_id)

 

 

在ORACLE數據庫當中,有時候會使用ALTER SYSTEM KILL SESSION 'sid,serial#'殺掉一個會話進程,但是使用這個SQL語句殺掉會話后,數據庫並不會立即釋放掉相關的資源,有時候你會發現鎖定的資源很長時間也不會釋放,即使會話狀態為“KILLED”,依然會阻塞其它會話。
 
下面根據Eygel的"Oracle中Kill session的研究",構造一個案例看看kill session到底做了什么。如下所示
 
會話1:
 
SQL> conn etl/etl
Connected.
SQL> update test set status='invalid';
 
55944 rows updated.
 
SQL> update test2 set dropped='Y';
 
3090 rows updated.
會話2:
 
 
SQL> show user
USER is "SYS"
SQL> update etl.test2 set dropped='Y';
 
3090 rows updated.
會話3
 
 
SQL> select saddr,sid,serial#,paddr,username,status from v$session where username =upper('etl') or username =upper('sys');
 
SADDR SID SERIAL# PADDR USERNAME STATUS
---------------- ---------- ---------- ---------------- ------------------------------ --------
000000025C233B00 27 33353 000000025F1D1FC8 ETL INACTIVE
000000025C23A608 37 11448 000000025F1D27B0 SYS ACTIVE
000000025C24BC50 63 54311 000000025F1D5F08 SYS ACTIVE
 
 
SQL> alter system kill session '27,33353';
 
System altered.
 
SQL> select saddr,sid,serial#,paddr,username,status from v$session where username =upper('etl') or username =upper('sys');
 
SADDR SID SERIAL# PADDR USERNAME STATUS
---------------- ---------- ---------- ---------------- ------------------------------ --------
000000025C233B00 27 33353 000000025C21A0B0 ETL KILLED
000000025C23A608 37 11448 000000025F1D27B0 SYS ACTIVE
000000025C24BC50 63 54311 000000025F1D5F08 SYS INACTIVE
 
 
 
如下所示,我殺掉了其中兩個會話后,這兩個會話的地址都變為000000025C21A0B0了(請見PADDR列)。當在Oracle中kill session以后, Oracle只是簡單的把相關session的paddr 指向同一個虛擬地址.此時v$process和v$session失去關聯,進程就此中斷。 然后Oracle就等待PMON去清除這些Session.所以通常等待一個被標記為Killed的Session退出需要花費很長的時間. 如果此時被Kill的process,重新嘗試執行任務,那么馬上會收到進程中斷的提示,process退出,此時Oracle會立即啟動PMON 來清除該session.這被作為一次異常中斷處理.
 
 
SQL> alter system kill session '63,54311';
 
System altered.
 
SQL> select saddr,sid,serial#,paddr,username,status
from v$session where username =upper('etl') or username =upper('sys');
 
SADDR SID SERIAL# PADDR USERNAME STATUS
---------------- ---------- ---------- ---------------- ------------------------------ --------
000000025C233B00 27 33353 000000025C21A0B0 ETL KILLED
000000025C23A608 37 11448 000000025F1D27B0 SYS ACTIVE
000000025C24BC50 63 54311 000000025C21A0B0 SYS KILLED
我們根據下面SQL找到進程的地址,然后在v$process里面找到對應的spid,然后從操作系統中殺掉該進程。
 
SQL> select p.addr from v$process p where pid <> 1
2 minus
3 select s.paddr from v$session s;
 
ADDR
----------------
000000025F1D1FC8
000000025F1D5F08
 
 
 
SQL> select saddr,sid,serial#,paddr,username,status from v$session
where username =upper('etl') or username =upper('sys');
 
SADDR SID SERIAL# PADDR USERNAME STATUS
---------------- ---------- ---------- ---------------- ------------------------------ --------
000000025C233B00 27 33353 000000025C21A0B0 ETL KILLED
000000025C23A608 37 11448 000000025F1D27B0 SYS ACTIVE
000000025C24BC50 63 54311 000000025C21A0B0 SYS KILLED
 
SQL> select addr, pid, spid, username from v$process where addr in ('000000025F1D1FC8','000000025F1D5F08');
 
ADDR PID SPID USERNAME
---------------- ---------- ------------ ---------------
000000025F1D1FC8 22 12959 oracle
000000025F1D5F08 38 12971 oracle
 
SQL> ! kill -9 12959
 
SQL> ! kill -9 12971
 
SQL> select saddr,sid,serial#,paddr,username,status
from v$session where username =upper('etl') or username =upper('sys');
 
SADDR SID SERIAL# PADDR USERNAME STATUS
---------------- ---------- ---------- ---------------- ------------------------------ --------
000000025C23A608 37 11448 000000025F1D27B0 SYS ACTIVE
 
 
在ORACLE數據庫殺掉會話進程有三種方式:
 
1: ALTER SYSTEM KILL SESSION
 
關於KILL SESSION Clause ,如下官方文檔描述所示,alter system kill session實際上不是真正的殺死會話,它只是將會話標記為終止。等待PMON進程來清除會話。
 
The KILL SESSION clause lets you mark a session as terminated, roll back ongoing transactions, release all session locks, and partially recover session resources. To use this clause, your instance must have the database open. Your session and the session to be terminated must be on the same instance unless you specify integer3.You must identify the session with the following values from the V$SESSION view:
 
For integer1, specify the value of the SID column.
 
For integer2, specify the value of the SERIAL# column.
 
For the optional integer3, specify the ID of the instance where the target session to be killed exists. You can find the instance ID by querying the GV$ tables.
If the session is performing some activity that must be completed, such as waiting for a reply from a remote database or rolling back a transaction, then Oracle Database waits for this activity to complete, marks the session as terminated, and then returns control to you. If the waiting lasts a minute, then Oracle Database marks the session to be terminated and returns control to you with a message that the session is marked to be terminated. The PMON background process then marks the session as terminated when the activity is complete.
Whether or not the session has an ongoing transaction, Oracle Database does not recover the entire session state until the session user issues a request to the session and receives a message that the session has been terminated.
可以使用ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE 來快速回滾事物、釋放會話的相關鎖、立即返回當前會話的控制權。
 
Specify IMMEDIATE to instruct Oracle Database to roll back ongoing transactions, release all session locks, recover the entire session state, and return control to you immediately.
 
 
 
2: ALTER SYSTEM DISCONNECT SESSION
 
 
 
ALTER SYSTEM DISCONNECT SESSION 殺掉專用服務器(DEDICATED SERVER)或共享服務器的連接會話,它等價於從操作系統殺掉進程。它有兩個選項POST_TRANSACTION和IMMEDIATE, 其中POST_TRANSACTION表示等待事務完成后斷開會話,IMMEDIATE表示中斷會話,立即回滾事務。
 
SQL> ALTER SYSTEM DISCONNECT SESSION 'sid,serial#' POST_TRANSACTION;
 
SQL> ALTER SYSTEM DISCONNECT SESSION 'sid,serial#' IMMEDIATE;
 
3: KILL -9 SPID (Linux) 或 orakill ORACLE_SID spid (Windows)
 
可以使用下面SQL語句找到對應的操作系統進程SPID,然后殺掉。當然殺掉操作系統進程是一件危險的事情,尤其不要誤殺。所以在執行前,一定要謹慎確認。
 
SET LINESIZE 100
COLUMN spid FORMAT A10
COLUMN username FORMAT A10
COLUMN program FORMAT A45
 
SELECT s.inst_id,
s.sid,
s.serial#,
p.spid,
s.username,
s.program
FROM gv$session s
JOIN gv$process p ON p.addr = s.paddr AND p.inst_id = s.inst_id
WHERE s.type != 'BACKGROUND';
 
 
在數據庫如果要徹底殺掉一個會話,尤其是大事務會話,最好是使用ALTER SYSTEM DISCONNECT SESSION IMMEDIATE或使用下面步驟:
 
1:首先在操作系統級別Kill掉進程。
 
2:在數據庫內部KILL SESSION
 
或者反過來亦可。這樣可以快速終止進程,釋放資源。
 
參考資料:
 
 
 
 
 
 


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM