Chinaunix首页 | 论坛 | 博客
  • 博客访问: 666990
  • 博文数量: 128
  • 博客积分: 265
  • 博客等级: 二等列兵
  • 技术积分: 1464
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-27 20:44
个人简介

just do it

文章分类

全部博文(128)

文章存档

2023年(1)

2020年(1)

2019年(1)

2018年(3)

2017年(6)

2016年(17)

2015年(16)

2014年(39)

2013年(34)

2012年(10)

分类: Oracle

2014-09-05 11:04:53


How To Find The Process Identifier (pid, spid) After The Corresponding Session Is Killed?

使用alter system kill session ‘sid,serial#’命令杀会话的时候,其session只是被标记killed而已,而且还可以观察到v$session.paddr变化掉,而对应的v$process.addr却没有相应的更改,这就导致,在session被kill之后很难再由这两个列的联系找出操作系统的peocess id。如下
session 1:

SQL> select distinct sid from v$mystat;

       SID
----------
       134

session 2:

SQL> select p.spid, s.username, s.sid, s.serial#, s.status, p.addr, s.paddr
  2    from v$process p, v$session s
  3   where p.addr = s.paddr
  4     and s.sid = 134;

SPID                     USERNAME          SID    SERIAL# STATUS           ADDR             PADDR
------------------------ ---------- ---------- ---------- ---------------- ---------------- ---------------- 19856 SYSTEM 134 36001 INACTIVE 000000007FE5E4C8 000000007FE5E4C8 SQL> alter system kill session '134,36001';

System altered.

SQL> select p.spid,p.addr from v$process p where p.spid=19856;

SPID                     ADDR
------------------------ ---------------- 19856 000000007FE5E4C8 SQL> select s.username, s.sid, s.serial#, s.status,s.paddr from v$session s where s.sid=134;

USERNAME          SID    SERIAL# STATUS           PADDR
---------- ---------- ---------- ---------------- ----------------
SYSTEM 134 36001 KILLED 000000007FEA05F8 SQL> select p.spid, s.username, s.sid, s.serial#, s.status, p.addr, s.paddr
  2    from v$process p, v$session s
  3   where p.addr = s.paddr
  4     and s.sid = 134;

no rows selected

oracle对此的一开始以Bug解释,Bug 5453737 WHEN A SESSION IS KILLED, PADDR CHANGES IN V$SESSION BUT ADDR NOT IN V$PROCESS。不过后来这个Bug并不被当作bug给关闭了,给出的解释是

Bug 5453737 WHEN A SESSION IS KILLED, PADDR CHANGES IN V$SESSION BUT ADDR NOT IN V$PROCESS
closed as not a bug with the following explanation:
When a session is killed, the session state object(and all the child state objects under the session state object) move out from under the original parent process state object, and are placed under the pseudo process state object (which is expected, given the parent/child process mechanism on Unix). PMON will clean up all the state objects found under the pseudo process state object. That explains why PADDR changes in V$SESSION when a session is killed. New PADDR you are seeing in v$SESSION is the address of the pseudo process state object. This shows up in system state under PSEUDO PROCESS for group DEFAULT: V$PROCESS still maintains the record of the original parent process. This is expected.

但是这个找出标记为killed的session对应的操作系统进程就颇有难度了,尤其是11g之前的版本,这时oracle又给出了一个Bug,BUG:5379252 – Hard To Determine Server Processes Which Owned Killed Session。

为何说11g版本之前更难呢?11g中提供诸多的方便可以解决这个问题。
1、v$session多了两个字段CREATOR_ADDR和CREATOR_SERIAL#
CREATOR_ADDR – state object address of creating process
CREATOR_SERIAL# – serial number of creating process
CREATOR_ADDR可以与v$process.addr进行join操作。

select p.spid, s.username, s.sid, s.serial#, s.status, p.addr, s.paddr
  from v$process p, v$session s
 where p.addr = s.creator_addr
   and s.sid = &sid;

如11g中的输出示例:

SQL> select p.spid, s.username, s.sid, s.serial#, s.status, p.addr, s.paddr
  2    from v$process p, v$session s
  3   where p.addr = s.creator_addr
  4     and s.sid = 140;

SPID  USERNAME          SID    SERIAL# STATUS           ADDR             PADDR
----- ---------- ---------- ---------- ---------------- ---------------- ----------------
413   SYSTEM            140       1911 KILLED           00000000774A0BE0 000000007752DCF8

2、另外就是11g中提供的视图

V$PROCESS_GROUP
INDX – Index
NAME – The name of the process group. The default group is called DEFAULT.
PID – Oracle process id

V$DETACHED_SESSION
INDX – Index
PG_NAME – The process group name that owns this session. The default group is DEFAULT.
SID – Oracle session id.
SERIAL# – Session serial number.
PID – Oracle process id.

select p.spid, s.username, s.sid, s.serial#, s.status, p.addr, s.paddr
  from v$detached_session d
  join v$session s
    on d.sid = s.sid
   and d.serial# = s.serial#
  join v$process p
    on d.pid = p.pid;

如11g中的输出示例:

SQL> select p.spid, s.username, s.sid, s.serial#, s.status, p.addr, s.paddr
  2    from v$detached_session d
  3    join v$session s
  4      on d.sid = s.sid
  5     and d.serial# = s.serial#
  6    join v$process p
  7      on d.pid = p.pid;

SPID  USERNAME          SID    SERIAL# STATUS           ADDR             PADDR
----- ---------- ---------- ---------- ---------------- ---------------- ----------------
413   SYSTEM            140       1911 KILLED           00000000774A0BE0 000000007752DCF8

比较遗憾的是,这些字段和视图是11g中出现的,从11.1.0.6开始。但是,对于该版本之前的也不是没有办法,但是可以考虑如下的语句:

SELECT addr, pid, spid, program
  FROM v$process
 WHERE NOT EXISTS (SELECT 1 FROM v$session WHERE paddr = addr);

如10g的中输出示例,也就是本文开头的案例:

SQL> SELECT addr, pid, spid, program
  2    FROM v$process
  3   WHERE NOT EXISTS (SELECT 1 FROM v$session WHERE paddr = addr)
  4  /

ADDR                    PID SPID                     PROGRAM
---------------- ---------- ------------------------ -----------------
000000007FE55E60          1                          PSEUDO
000000007FE5BD40         13 19481                    oracle@ace (D000)
000000007FE5C528         14 19483                    oracle@ace (S000)
000000007FE5E4C8         18 19856 oracleSYK@ace

但是需要注意的是,program为PSEUDO,D000和S000千万别被轻易kill掉,kill之前最好做好确认工作。

阅读(1497) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~