如何杀死用户的所有活动和非活动Oracle会话

37
我正在尝试以下脚本,以一次性关闭所有活动和非活动的Oracle用户会话,但它无法正常工作。该脚本执行成功,但无法关闭该用户的会话。
BEGIN
  FOR r IN (select sid,serial# from v$session where username = 'USER')
  LOOP
    EXECUTE IMMEDIATE 'alter system kill session ''' || r.sid 
      || ',' || r.serial# || '''';
  END LOOP;
END;

2
这些会话的状态是什么?关闭一个会话并不意味着它会立即消失。如果会话有一些事务未完成,它会先回滚(可能需要很长时间),然后才会退出。因此,我的建议是检查 V$session 表中的 STATUS 列。 - ibre5041
1
我检查了列的状态,显示有几个活动会话。因此它还没有被终止... - Andrew
6个回答

56

KILL SESSION命令实际上并不会“杀死”会话,它只是请求会话自我结束。在一些情况下,例如等待远程数据库的回复或者回滚事务,会话将不会立即结束并会等待当前操作完成。在这些情况下,会话状态将会被标记为“marked for kill”,然后尽快被终止。

检查状态确认:

SELECT sid, serial#, status, username FROM v$session;

你也可以使用IMMEDIATE从句:

ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;

IMMEDIATE子句不会影响命令执行的工作,但它会立即将控制权返回给当前会话,而不是等待终止确认。请参阅结束Oracle会话.

更新 如果您想杀死所有会话,那么只需要准备一个小脚本即可。

SELECT 'ALTER SYSTEM KILL SESSION '''||sid||','||serial#||''' IMMEDIATE;' FROM v$session;

将上述内容复制到一个 .sql 文件中并执行,或者复制粘贴输出并运行。


1
你好lalit,你说的是真的,我也知道以上SQL命令可以立即检查和终止会话。但这不是我的问题的答案。假设我有20个活动和非活动会话,那么我不能简单地编写20个ALTER语句来中止它们。我想一次性将它们全部中止。 - Andrew
1
是的,但我们能否创建一个循环或过程来一次性终止所有这些会话呢?我不知道在未来我的用户可能会有超过20个会话。 - Andrew
@Rahul,如果可以使用纯SQL完成任务,请不要使用PL/SQL。此外,这不是您经常要做的事情。如果您真的想经常这样做,那么就像我上面展示的那样添加一个更新,只需创建一个小脚本即可。 - Lalit Kumar B
1
你好 Lalit,我有一个小问题,你的查询中我需要指定要终止会话的用户吗? - Andrew
你说要查看所有会话,所以我没有添加任何筛选器。如果你想终止特定用户的会话,请使用 WHERE username = <username> 查看 v$session 的其他属性。如果是 RAC,请使用 gv$session - Lalit Kumar B
4
终止所有会话: 运行以下SQL语句:SELECT 'ALTER SYSTEM KILL SESSION '''||sid||','||serial#||''';' FROM v$session;,然后复制结果并执行。作者忘记添加一些 ' 字符。 - Lorenzo Lerate

23
BEGIN
  FOR r IN (select sid,serial# from v$session where username='user')
  LOOP
      EXECUTE IMMEDIATE 'alter system kill session ''' || r.sid  || ',' 
        || r.serial# || ''' immediate';
  END LOOP;
END;

这应该可以解决 - 我刚刚更改了您的脚本以添加immediate关键字。正如先前的答案所指出的那样,kill session仅标记会话以进行终止;它不会立即执行,而是在方便时稍后执行。

从您的问题中,似乎您希望立即看到结果。因此,immediate关键字用于强制立即执行。


谢谢@TobySpeight,我是新手。已经更新了我的答案并附上了解释。 - Zeeshan Adnan
谢谢 - 不显然你做了什么不同的事。 - Toby Speight

9
执行此脚本:
SELECT 'ALTER SYSTEM KILL SESSION '''||sid||','||serial#||''' IMMEDIATE;' 
FROM v$session 
where username='YOUR_USER';

它将打印出应该执行的SQL语句。

5
BEGIN
  FOR r IN (select sid,serial# from v$session where username='user')
  LOOP
      EXECUTE IMMEDIATE 'alter system kill session ''' || r.sid  || ',' || r.serial# || '''';
  END LOOP;
END;
/

对我有效。

2

对于Oracle 11g,这种方法可能不起作用,因为您可能会收到以下错误:

"最初的回答"

Error report:
SQL Error: ORA-00026: missing or invalid session ID
00026. 00000 -  "missing or invalid session ID"
*Cause:    Missing or invalid session ID string for ALTER SYSTEM KILL SESSION.
*Action:   Retry with a valid session ID.

为了解决这个问题,请使用以下代码来识别会话: SQL> select inst_id,sid,serial# from gv$session 或者 v$session(注意:v$session没有inst_id字段)
然后使用以下代码结束它们:
alter system kill session 'sid,serial,@inst_id' IMMEDIATE;

0

前一天未活动的会话将被终止

begin
    for i in (select * from v$session where status='INACTIVE' and (sysdate-PREV_EXEC_START)>1)
    LOOP
        EXECUTE IMMEDIATE(q'{ALTER SYSTEM KILL SESSION '}'||i.sid||q'[,]'  ||i.serial#||q'[']'||' IMMEDIATE');    END LOOP;end;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接