【问题标题】:Dropping a connected user from an Oracle 10g database schema从 Oracle 10g 数据库模式中删除连接的用户
【发布时间】:2010-09-10 07:00:08
【问题描述】:

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

我们有几个开发人员使用 SQL Developer 连接到单个 Oracle 10g 服务器上的相同架构。问题是当我们想要删除模式来重建它时,不可避免地有人仍然连接,我们不能在有人仍然连接时删除数据库模式或用户。

出于同样的原因,我们不希望删除与其他模式的所有连接,因为其他人可能仍会连接并使用这些模式进行测试。

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

【问题讨论】:

    标签: oracle


    【解决方案1】:

    您尝试过 ALTER SYSTEM KILL SESSION 吗?从 V$SESSION 获取给定模式中每个会话的 SID 和 SERIAL#,然后执行

    ALTER SCHEMA KILL SESSION sid,serial#;

    【讨论】:

      【解决方案2】:

      要查找会话,作为 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'

      产生现成的终止语句的查询可以是

      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 并从操作系统中杀死它总是有效的。
      • 小添加 - 立即添加到命令:select 'alter system kill session ''' || sid || ',' || serial# || ''' immediate;' from v$session where username = '<your_schema>'; 这将强制执行命令
      • 不错的答案。正是我想要的。
      【解决方案3】:

      仅我的两分钱:最好的方法(但在短期内可能不是最快的)可能是每个开发人员都在自己的数据库实例上工作(请参阅rule #1 for database work)。

      自从Oracle Database 10g Express Edition 以来,在开发人员站上安装 Oracle 已成为一件轻而易举的事。

      【讨论】:

      • 仅适用于 Windows 和某些版本的 Linux。
      • 这与问题无关?
      • 这可能不是提问者正在寻找的答案,我完全可以理解为什么它没有得到太多支持,但考虑到他特别提出的用例,我认为这非常相关。多个开发人员在同一个数据库上工作是一个非常糟糕的主意,而且这个问题绝对不是最坏的情况。
      【解决方案4】:

      确保在您杀死它们之前更改系统并启用受限会话,否则它们会在您完成工作之前快速登录回数据库。

      【讨论】:

      • 锁定他打算删除的用户,然后终止该用户的所有连接会话,然后删除并重新创建,可能会更容易且干扰更少。无需不必要地限制对其他用户的访问。
      【解决方案5】:

      只需使用 SQL :

      disconnect; 
      
      conn tiger/scott as sysdba;
      

      【讨论】:

        【解决方案6】:

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

        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';
        

        您会看到类似下面的内容。

        然后,使用从上述结果中提取的值运行下面的查询。

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

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

        【讨论】:

          【解决方案7】:

          我的建议是这个简单的匿名块:

          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;
          /
          

          【讨论】:

          • 最好在杀死会话之前注意 ospid,它们可能会卡住
          猜你喜欢
          • 2015-12-19
          • 1970-01-01
          • 2013-03-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-10
          • 2011-11-20
          • 1970-01-01
          相关资源
          最近更新 更多