如何为用户终止所有活动和非活动的 oracle 会话

Posted

技术标签:

【中文标题】如何为用户终止所有活动和非活动的 oracle 会话【英文标题】:How to kill all active and inactive oracle sessions for user 【发布时间】:2015-09-20 23:50:42 【问题描述】:

我正在尝试使用下面的脚本来一次终止用户的所有活动和非活动 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;

【问题讨论】:

这些会话的状态如何?您杀死会话的事实并不意味着它会立即消失。如果会话有一些事务打开,那么它首先回滚(它可能需要很长时间)然后它会退出。所以我的建议是检查 V$session 中的 STATUS 列。 我检查了列状态及其显示的活动会话很少。所以它没有被杀死.. 【参考方案1】:

KILL SESSION 命令实际上并没有杀死会话。它只是要求会话杀死自己。在某些情况下,例如等待来自远程数据库的回复或回滚事务,会话不会立即自我终止,而是会等待当前操作完成。在这些情况下,会话的状态将是“ma​​rked for kill”。然后它会尽快被杀死。

检查状态以确认:

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

您也可以使用 IMMEDIATE 子句:

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

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

更新如果你想杀死所有的会话,你可以准备一个小脚本。

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

假脱机.sql文件并执行它,或者,复制粘贴输出并运行它。

【讨论】:

你好 lalit 你说的是真的,我知道上面的 sql coomands 可以立即检查并终止会话。但这不是我问题的答案。可以说我有 20 个会话处于活动状态和处于非活动状态。然后我不能简单地想写 20 个改变语句来杀死它们。我想立刻杀了他们。 是的,但我们不能创建循环或过程来立即终止此会话吗?我不知道将来我的用户可能会有超过 20 个会话。 @Rahul 当您可以在纯 SQL 中使用 PL/SQL 时,切勿使用它。此外,这不是你时不时地做的事情。如果你真的想非常频繁地这样做,那么当我添加更新时,只需创建一个如上所示的小脚本。 您好,lalit 只是一个小问题,我不需要在您的查询中指定我正在终止会话的用户吗? 杀死所有会话:SELECT 'ALTER SYSTEM KILL SESSION '''||sid||','||serial#||''';' FROM v$session; 然后复制结果并执行。作者忘记放一些 ' 字符【参考方案2】:
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,我是新手。用解释更新了我的答案。 谢谢 - 你做了什么不同的事情并不明显。【参考方案3】:

执行这个脚本:

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

它会打印出需要执行的sqls。

【讨论】:

【参考方案4】:
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;
/

它对我有用。

【讨论】:

【参考方案5】:

对于 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;

【讨论】:

【参考方案6】:

杀死前一天的非活动会话

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;

【讨论】:

以上是关于如何为用户终止所有活动和非活动的 oracle 会话的主要内容,如果未能解决你的问题,请参考以下文章

如何为多个活动注册制作网站? [关闭]

如何为两种不同类型的用户创建一个登录活动页面?

如何为特定活动禁用 Android 软键盘?

如何为特定活动禁用Android Soft Keyboard?

Django - 如何为注册站点用户和非站点用户创建模型?

为啥数据库经此会话中的活动事务已由另外一个会话提交或终止