想必大家都遇到过在数据库层面发起“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 清理会话,释放资源。如果1 分钟过后,上述动作未完成,则该会话被标记为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 ”命令快速清理会话。需要注意的是,在查杀会话之前一定要再三确认信息,千万不要误杀了系统核心进程。
编辑推荐:
- 日常运维之TX锁处理(二)03-03
- 国际物流报关中EDI和电子单有什么区别?03-03
- 高峰期谨慎编译业务对象03-03
- Oracle replayc测试03-03
- Oracle asm磁盘损坏异常恢复03-03
- 【ASK_ORACLE】使用insert语句将普通表转换成分区表03-03
- oracle adg备库归档满了无法同步03-03
- plsqldevelper工具处理生僻字03-03
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
