29

我需要在没有管理员监督的情况下快速(并强制)终止连接到我的 oracle 数据库的所有外部会话。

我不想只是锁定数据库并让用户优雅地退出。

我将如何编写这个脚本?

4

10 回答 10

44

此答案深受此处对话的影响: http ://www.tek-tips.com/viewthread.cfm?qid=1395151&page=3

ALTER SYSTEM ENABLE RESTRICTED SESSION;

begin     
    for x in (  
            select Sid, Serial#, machine, program  
            from v$session  
            where  
                machine <> 'MyDatabaseServerName'  
        ) loop  
        execute immediate 'Alter System Kill Session '''|| x.Sid  
                     || ',' || x.Serial# || ''' IMMEDIATE';  
    end loop;  
end;

我跳过了源自数据库服务器的终止会话,以避免终止 Oracle 与其自身的连接。

于 2008-09-10T21:27:44.500 回答
11

作为 SYS:

startup force;

残酷,却不失优雅。

于 2010-09-29T19:45:24.943 回答
7

在杀死会话之前,如果可能的话

ALTER SYSTEM ENABLE RESTRICTED SESSION;

阻止新会话连接。

于 2008-09-13T20:00:36.743 回答
5

一段时间以来,我一直在使用类似的东西来终止共享服务器上的会话。可以删除“where”的第一行以终止所有非“sys”会话:

BEGIN
  FOR c IN (
      SELECT s.sid, s.serial#
      FROM v$session s
      WHERE (s.Osuser = 'MyUser' or s.MACHINE = 'MyNtDomain\MyMachineName')
      AND s.USERNAME <> 'SYS'
      AND s.STATUS <> 'KILLED'
  )
  LOOP
      EXECUTE IMMEDIATE 'alter system kill session ''' || c.sid || ',' || c.serial# || '''';
  END LOOP;
END;
于 2011-10-18T10:55:32.377 回答
2

如果您想阻止新用户连接,但允许当前会话继续直到它们处于非活动状态,您可以将数据库置于 QUIESCE 模式:

ALTER SYSTEM QUIESCE RESTRICTED;

Oracle 数据库管理员指南

非 DBA 活动会话将继续,直到它们变为非活动状态。活动会话是当前在事务、查询、提取或 PL/SQL 语句中的会话;或当前持有任何共享资源(例如,入队)的会话。不允许非活动会话变为活动状态...一旦所有非 DBA 会话变为非活动状态,ALTER SYSTEM QUIESCE RESTRICTED 语句完成,数据库处于静默状态

于 2008-10-24T16:10:07.413 回答
2

附加信息

重要的 Oracle 11g 更改以更改会话终止会话

Oracle 作者 Mladen Gogala 指出,在使用 inst_id 列时,现在需要一个 @ 符号来终止会话:

alter system kill session '130,620,@1';

http://www.dba-oracle.com/tips_killing_oracle_sessions.htm

于 2012-02-02T18:14:21.713 回答
1

尝试登录时触发

尝试断开用户连接,您不应该允许他们连接。

有这种触发器的例子。

CREATE OR REPLACE TRIGGER rds_logon_trigger
AFTER LOGON ON DATABASE
BEGIN
  IF SYS_CONTEXT('USERENV','IP_ADDRESS') not in ('192.168.2.121','192.168.2.123','192.168.2.233') THEN
    RAISE_APPLICATION_ERROR(-20003,'You are not allowed to connect to the database');
  END IF;

  IF (to_number(to_char(sysdate,'HH24'))< 6) and (to_number(to_char(sysdate,'HH24')) >18) THEN
    RAISE_APPLICATION_ERROR(-20005,'Logon only allowed during business hours');
  END IF;

END;
于 2008-09-12T17:34:05.543 回答
1

我发现下面的代码片段很有帮助。取自:http: //jeromeblog-jerome.blogspot.com/2007/10/how-to-unlock-record-on-oracle.html

select
owner||'.'||object_name obj ,
oracle_username||' ('||s.status||')' oruser ,
os_user_name osuser ,
machine computer ,
l.process unix ,
s.sid||','||s.serial# ss ,
r.name rs ,
to_char(s.logon_time,'yyyy/mm/dd hh24:mi:ss') time
from v$locked_object l ,
dba_objects o ,
v$session s ,
v$transaction t ,
v$rollname r
where l.object_id = o.object_id
and s.sid=l.session_id
and s.taddr=t.addr
and t.xidusn=r.usn
order by osuser, ss, obj
;

然后跑:

Alter System Kill Session '<value from ss above>'
;

杀死单个会话。

于 2009-06-02T14:05:04.610 回答
1

要回答所提出的问题,这里是完成这项工作的最准确的 SQL,您可以将它与 PL/SQL 循环结合以实际运行 kill 语句:

select ses.USERNAME,
    substr(MACHINE,1,10) as MACHINE, 
    substr(module,1,25) as module,
    status, 
    'alter system kill session '''||SID||','||ses.SERIAL#||''';' as kill
from v$session ses LEFT OUTER JOIN v$process p ON (ses.paddr=p.addr)
where schemaname <> 'SYS'
    and not exists
    (select 1 
        from DBA_ROLE_PRIVS 
        where GRANTED_ROLE='DBA' 
            and schemaname=grantee)
    and machine!='yourlocalhostname' 
order by LAST_CALL_ET desc;
于 2011-05-25T09:57:44.677 回答
0

如果 Oracle 在 Unix /Linux 中运行,那么我们可以 grep 查找所有客户端连接并终止它

grep所有oracle客户端进程:

ps -ef | grep 本地=否 | grep -v grep | awk '{打印 $2}' | wc -l

杀死所有 oracle 客户端进程:

杀死 -9ps -ef | grep LOCAL=NO | grep -v grep | awk '{print $2}'

于 2016-03-30T04:47:34.460 回答