由于Oracle有内部锁定(的机制),因此有些时候它对于找到并终止Oracle里锁定数据库资源的会话很有用。首先,你需要找到所有的Oracle会话。下面是一段脚本,用来显示Oracle内所有会话的细节。
remsession.sql - displays all connected sessions
set echo off;
set termout on;
set linesize 80;
set pagesize 60;
set newpage 0;
select
rpad(c.name':',11)rpad(' current logons='
(to_number(b.sessions_current)),20)'cumulative logons='
rpad(substr(a.value,1,10),10)'highwater mark='
b.sessions_highwater Information
from
v$sysstat a,
v$license b,
v$database c
where
a.name = 'logons cumulative'
;
ttitle "dbnameDatabaseUNIX/Oracle Sessions";
set heading off;
select 'Sessions on database 'substr(name,1,8) from v$database;
set heading on;
select
substr(a.spid,1,9) pid,
substr(b.sid,1,5) sid,
substr(b.serial#,1,5) ser#,
substr(b.machine,1,6) box,
substr(b.username,1,10) username,
substr(b.osuser,1,8) os_user,
substr(b.PRogram,1,30) program
from
v$session b,
v$process a
where
b.paddr = a.addr
and
type='USER'
order by
spid;
ttitle off;
set heading off;
select 'To kill, enter SQLPLUSALTER SYSTEM KILL SESSION',
'''''SID, SER#'''''';' from dual;
spool off;
一旦我们找到了Oracle里所有的会话,那么下一步就是运行一个脚本来检测所有已经被锁定的会话。这是因为,Oracle可能无法以足够快的速度检测到一个不活动(dead)的会话,用以防止对数据访问的阻断(blockage)。你可以运行下面的脚本以定位那些管制着锁定资源的会话。
select
sess.sid,
sess.serial#,
lo.oracle_username,
lo.os_user_name,
ao.object_name,
lo.locked_mode
from
v$locked_object lo,
dba_objects ao,
v$session sess
where
ao.object_id = lo.object_id
and
lo.session_id = s.sid;
一旦定位了已锁定的会话,你就可以使用下面的脚本来自动地创建ALTER SESSION句法,用来终止你所希望终止的会话,这样就能够将锁定的会话从Oracle里清除掉。
spoolrun_nuke.sql
select
'alter system kill session '''
sess.sid', 'sess.serial#';'
from
v$locked_object lo,
dba_objects ao,
v$session sess
where
ao.object_id = lo.object_id
and
lo.session_id = s.sid;
在创建完run_nuke.sql文件之后,你就可以迅速地选择那些要被终止的会话并单独地运行它们。