日常运维之TX锁处理(二)

来源:这里教程网 时间:2026-03-03 18:11:34 作者:

想必大家都遇到过在数据库层面发起“alter system kill session  ”(数据库层杀掉会话,不加immediate  关键字)时,经常出现资源无法及时释放、会话一直处于killed  状态的情况。如果这个会话是锁的源头,那么除了等待PMON  (进程监视器)来清理之外,没有更好的办法了,而在操作系统层面杀掉进程的方式,基本上是百试百灵。使用系统命令“kill -9  ”杀死进程,系统向该process  进程发出sigkill  sigkill  信号直接发送给init  进程,终止process  进程。这种方式直接终止了Oracle  会话中对应的操作进程,资源也可以直接释放。

”的过程,以及为何“alter system kill session  ”杀掉会话之后,查不到处于killed  状态的会话所对应的系统进程spid 

alter system kill session    (不加immediate  关键字)杀掉会话可针对两种场景进行讨论:一是会话状态是active  ,二是会话状态是inactive  。使用此命令杀掉处于active  状态的会话时,过程可以简单概括如下:会话在收到kill  信号后进行回滚,此过程不可被中断,直至过程完成,该会话会接收到 ORA-00028: your session has been killed  ”信息  PMON  清理会话,释放资源。如果分钟过后,上述动作未完成,则该会话被标记为killed  状态,若会话拥有的资源未释放 PMON  进程清理会话。  使用此命令杀掉处于inactive  状态的会话时,过程可以简单概括如下:会话在收到kill  信号后被标记为killed  状态,会话拥有的资源未释放,等待PMON  进程清理会话。如果会话再次发出查询信号,会话就会接收到“ORA-00028: your session has been killed  ”信息,PMON  清理会话,释放资源。

接下来模拟不加immediate  参数,杀掉会话后状态被标记为killed  ,操作系统查不到进程的实验,过程如下:

SQL> select username,sid,serial#,paddr,server,status from v$session where username = 'SCOTT';

 

USERNAME     SID    SERIAL#  PADDR            SERVER    STATUS

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

SCOTT         17       6733  00000000A34C7040 DEDICATED INACTIVE

SCOTT        158       9177  00000000A34D4998 DEDICATED INACTIVE

 

SQL> select b.sid,b.serial#,c.spid,b.status from v$session b,v$process c where b.paddr = c.addr and b.sid in (17,158);

   SID    SERIAL# SPID      STATUS

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

   17       6733 23883     INACTIVE

   158       9177 24120     INACTIVE

手动杀掉这两个会话的命令如下:

SQL>  alter system kill session '17,6733';

SQL>  alter system kill session '158,9177';

再次查询这两个会话的状态,命令及结果如下:

SQL> select username,sid,serial#,paddr,server,status from v$session where username = 'SCOTT';

USERNAME    SID    SERIAL#  PADDR            SERVER    STATUS

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

SCOTT        17       6733  00000000A3551F18 PSEUDO     KILLED

SCOTT       158       9177  00000000A3551F18 PSEUDO     KILLED

从代码中我们可以发现,当两个会话的状态为killed  时,会话的paddr  指向同一地址00000000A3551F18  (虚拟地址),此地址在操作系统层面并无对应的spid  ,这就是当会话的状态变为killed  之后,使用以下语句查不到spid  的原因,查询示例代码如下所示:

SQL>  select b.sid,b.serial#,c.spid,b.status from v$session b,v$process c where b.paddr = c.addr and b.sid in (17,158);

no rows selected

此时我们就可以使用前文的查询语句,查杀并清理会话,  命令及结果如下:

SQL> select 'alter system kill session ''' || c.sid || '' || ',' || c.serial# || ''' immediate;' kill_session from v$session c where status='KILLED';

KILL_SESSION

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

alter system kill session '17,6733' immediate;

alter system kill session '158,9177' immediate;

因此,在查杀会话时,可以考虑直接使用“alter system kill session 'sid,serial#' immediate  ”命令快速清理会话。需要注意的是,在查杀会话之前一定要再三确认信息,千万不要误杀了系统核心进程。

相关推荐