如何为用户终止所有活动和非活动的 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
命令实际上并没有杀死会话。它只是要求会话杀死自己。在某些情况下,例如等待来自远程数据库的回复或回滚事务,会话不会立即自我终止,而是会等待当前操作完成。在这些情况下,会话的状态将是“marked 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 会话的主要内容,如果未能解决你的问题,请参考以下文章