Pergunta

Preciso interromper rapidamente (e à força) todas as sessões externas conectadas ao meu banco de dados Oracle sem a supervisão de um administrador.

Não quero apenas bloquear o banco de dados e permitir que os usuários saiam normalmente.

Como eu faria o script disso?

Foi útil?

Solução

Esta resposta é fortemente influenciada por uma conversa aqui: 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;

Eu pulo a eliminação de sessões originadas no servidor de banco de dados para evitar a interrupção das conexões do Oracle consigo mesmo.

Outras dicas

Como SYS:

startup force;

Brutal, mas elegante.

Antes de matar sessões, se possível faça

ALTER SYSTEM ENABLE RESTRICTED SESSION;

para impedir a conexão de novas sessões.

Estou usando algo assim há algum tempo para encerrar minhas sessões em um servidor compartilhado.A primeira linha de 'where' pode ser removida para eliminar todas as sessões que não sejam '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;

Se quiser impedir a conexão de novos usuários, mas permitir que as sessões atuais continuem até que fiquem inativas, você pode colocar o banco de dados no modo QUIESCE:

ALTER SYSTEM QUIESCE RESTRICTED;

De Guia do Administrador de Banco de Dados Oracle:

As sessões ativas não-DBA continuarão até que se tornem inativas.Uma sessão ativa é aquela que está atualmente dentro de uma transação, uma consulta, uma instrução PL/PL/SQL;ou uma sessão que atualmente esteja mantendo quaisquer recursos compartilhados (por exemplo, Enqueues).Nenhuma sessões inativas pode se tornar ativa ... Uma vez que todas as sessões não-DBA se tornem inativas, a declaração restrita do sistema de alteração é concluída e o banco de dados está em um estado quieto

informação adicional

Mudanças importantes no Oracle 11g para alterar a sessão de encerramento da sessão

O autor do Oracle Mladen Gogala observa que agora é necessário um sinal de @ é necessário para matar uma sessão ao usar a coluna Inst_id:

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

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

Tente acionar no logon

Em vez de tentar desconectar usuários, você não deve permitir que eles se conectem.

Existe um exemplo desse gatilho.

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;

Achei o trecho abaixo útil.Tirado de: 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
;

Então correu:

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

Para matar sessões individuais.

Para responder à pergunta feita, aqui está o SQL mais preciso para realizar o trabalho, você pode combiná -lo com o loop PL/SQL para realmente executar declarações de matar:

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;

Se o Oracle estiver rodando em Unix/Linux, podemos usar o grep para todas as conexões do cliente e eliminá-lo

grep todos os processos do cliente Oracle:

ps -ef | Grep Local = Não | grep -v grep | awk '{print $ 2}' | wc -l

Mate todos os processos do cliente Oracle:

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top