Domanda

Devo eliminare rapidamente (e forzatamente) tutte le sessioni esterne che si connettono al mio database Oracle senza la supervisione di un amministratore.

Non voglio semplicemente bloccare il database e consentire agli utenti di uscire con garbo.

Come lo scripterei?

È stato utile?

Soluzione

Questa risposta è fortemente influenzata da una conversazione qui: 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;

Salto le sessioni di uccisione originate sul server del database per evitare di uccidere le connessioni di Oracle a se stesso.

Altri suggerimenti

Come SYS:

startup force;

Brutale, ma elegante.

Prima di interrompere le sessioni, se possibile, fallo

ALTER SYSTEM ENABLE RESTRICTED SESSION;

per impedire la connessione di nuove sessioni.

Utilizzo qualcosa del genere da un po' per terminare le mie sessioni su un server condiviso.La prima riga di "where" può essere rimossa per terminare tutte le sessioni non "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 desideri impedire ai nuovi utenti di connettersi, ma consentire alle sessioni correnti di continuare finché non diventano inattive, puoi mettere il database in modalità QUIESCE:

ALTER SYSTEM QUIESCE RESTRICTED;

Dal Guida per l'amministratore del database Oracle:

Le sessioni attive non DBA continueranno fino a quando non diventeranno inattive.Una sessione attiva è quella che si trova attualmente all'interno di una transazione, una query, una fetch o un'istruzione PL/SQL;o una sessione che sta attualmente detenendo risorse condivise (ad esempio, ACQUEUES).Non sono autorizzate sessioni inattive a diventare attive ... Una volta che tutte le sessioni non DBA diventano inattive, la dichiarazione limitata di alter System si è completata e il database è in uno stato quiesced

informazioni addizionali

Importanti modifiche di Oracle 11g per alterare la sessione di kill session

L'autore Oracle Mladen Gogala nota che è ora richiesto un segno @ per uccidere una sessione quando si utilizza la colonna Inst_id:

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

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

Prova ad attivare l'attivazione all'accesso

Invece di provare a disconnettere gli utenti, non dovresti consentire loro di connettersi.

Esiste un esempio di tale trigger.

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;

Ho trovato utile lo snippet seguente.Preso da: 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
;

Quindi ha eseguito:

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

Per uccidere le singole sessioni.

Per rispondere alla domanda posta, ecco il SQL più accurato per svolgere il lavoro, puoi combinarlo con il loop PL/SQL per eseguire effettivamente dichiarazioni di uccisioni:

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 Oracle è in esecuzione in Unix/Linux, possiamo eseguire il grep per tutte le connessioni client e ucciderle

grep tutto il processo client Oracle:

PS -ef | grep locale = no | grep -v grep | awk '{stampa $ 2}' | wc -l

Uccidi tutto il processo client Oracle:

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top