从Oracle 10g数据库模式中删除一个连接的用户

71

有没有比重新启动Oracle数据库服务更好的方法来强制断开所有用户与Oracle 10g数据库模式的连接?

我们有几个开发人员使用SQL Developer连接到单个Oracle 10g服务器上的同一模式。问题在于,当我们想要删除模式以重建它时,不可避免地有人仍然连接着,因此我们无法删除数据库模式或用户。

同样,我们也不想断开其他模式的所有连接,因为其他人可能仍然连接并使用那些模式进行测试。

是否有人知道解决这个问题的快速方法?

7个回答

121

作为DBA,要查找会话,请使用

select sid,serial# from v$session where username = '<your_schema>'

如果您想确保仅获取使用SQL Developer的会话,则可以添加and program = 'SQL Developer'。 如果您只想杀死属于特定开发人员的会话,则可以在os_user上添加限制。

然后通过以下命令将其终止

alter system kill session '<sid>,<serial#>'

(例如:alter system kill session '39,1232'

可生成现成的kill语句的查询如下:

select 'alter system kill session ''' || sid || ',' || serial# || ''';' from v$session where username = '<your_schema>'

这将为该用户返回每个会话一个kill语句 - 类似于:

alter system kill session '375,64855';

alter system kill session '346,53146';


我发现在我们的RAC环境中,杀死会话经常会导致其挂起,但是从操作系统找到进程ID并将其杀死总是有效的。 - Jonathan
4
小修改-在命令中加入 immediate 关键字:select 'alter system kill session ''' || sid || ',' || serial# || ''' immediate;' from v$session where username = '<your_schema>'; 这会强制执行该命令。 - Michael
很好的答案。正是我在寻找的。 - Iván Rodríguez Torres
很明显,但可能需要注意的是用户名(上面的“<your_schema>”)应该是大写的。 - rshdev

19

使用此查询查找现有的数据库会话:

SELECT s.inst_id,
       s.sid,
       s.serial#,
       p.spid,
       s.username,
       s.program
FROM   gv$session s
       JOIN gv$process p ON p.addr = s.paddr AND p.inst_id = s.inst_id
WHERE  s.type != 'BACKGROUND';

你会看到类似下面的内容。 Oracle Sessions

接着,使用上述结果中提取的值运行以下查询。

ALTER SYSTEM KILL SESSION '<put above s.sid here>,<put above s.serial# here>';

例如:ALTER SYSTEM KILL SESSION '93,943';


9
我的建议是使用这个简单的匿名块:
DECLARE
   lc_username   VARCHAR2 (32) := 'user-name-to-kill-here';
BEGIN
   FOR ln_cur IN (SELECT sid, serial# FROM v$session WHERE username = lc_username)
   LOOP
      EXECUTE IMMEDIATE ('ALTER SYSTEM KILL SESSION ''' || ln_cur.sid || ',' || ln_cur.serial# || ''' IMMEDIATE');
   END LOOP;
END;
/

2
最好在终止会话之前先注意ospid,否则它们可能会被卡住。 - user3380585

1

在你杀死进程之前,确保你修改了系统并启用了受限会话,否则它们会在你完成工作之前迅速重新登录到数据库中。


2
可能更容易且不会过于侵入性,先锁定要删除的用户,然后杀掉该用户的所有连接会话,之后再删除并重新创建该用户。没有必要无谓地限制其他用户的访问。 - Mark J. Bobak

0

仅供参考:最好的方式(虽然在短期内可能不是最快的)可能是让每个开发人员都在自己的数据库实例上工作(请参阅数据库工作规则#1)。

自从Oracle Database 10g Express Edition发布以来,在开发人员站点上安装Oracle已经变得非常简单了。


仅适用于Windows和某些Linux版本。 - Peter Bratton
这与问题无关。 - Konrads
可能不是提问者寻找的答案,我完全理解为什么它没有得到很多赞同,但考虑到他明确提出的用例,我认为它非常相关。多个开发人员同时使用同一数据库是一个非常糟糕的想法,而且这个问题肯定不是最糟糕的。 - Mac

0
你尝试过使用 ALTER SYSTEM KILL SESSION 吗?从给定模式中的每个会话的 V$SESSION 中获取 SID 和 SERIAL#,然后执行以下操作:
ALTER SCHEMA KILL SESSION sid,serial#;

0

只需要使用SQL:

disconnect; 

conn tiger/scott as sysdba;

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