Comment puis-je supprimer toutes les sessions de connexion à ma base de données Oracle ?
-
09-06-2019 - |
Question
Je dois supprimer rapidement (et de force) toutes les sessions externes se connectant à ma base de données Oracle sans la supervision d'un administrateur.
Je ne veux pas simplement verrouiller la base de données et laisser les utilisateurs quitter gracieusement.
Comment pourrais-je écrire cela ?
La solution
Cette réponse est fortement influencée par une conversation ici : 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;
J'évite de supprimer les sessions provenant du serveur de base de données pour éviter de supprimer les connexions d'Oracle avec lui-même.
Autres conseils
En tant que SYS :
startup force;
Brutal, mais élégant.
Avant les séances de mise à mort, si possible, faites
ALTER SYSTEM ENABLE RESTRICTED SESSION;
pour empêcher les nouvelles sessions de se connecter.
J'utilise quelque chose comme ça depuis un moment pour tuer mes sessions sur un serveur partagé.La première ligne du « où » peut être supprimée pour tuer toutes les sessions 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;
Si vous souhaitez empêcher les nouveaux utilisateurs de se connecter, mais autoriser les sessions en cours jusqu'à ce qu'elles soient inactives, vous pouvez mettre la base de données en mode QUIESCE :
ALTER SYSTEM QUIESCE RESTRICTED;
Du Guide de l'administrateur de base de données Oracle:
Les séances actives non DBA se poursuivront jusqu'à ce qu'elles deviennent inactives.Une session active est celle qui est actuellement à l'intérieur d'une transaction, d'une requête, d'une récupération ou d'une instruction PL / SQL;ou une session qui détient actuellement toutes les ressources partagées (par exemple, les enquêtes).Aucune séance inactive n'est autorisée à devenir active ... une fois que toutes les sessions non DBA deviennent inactives, la déclaration restreinte du système alter se termine et que la base de données est dans un état
information additionnelle
Modifications importantes d'Oracle 11g pour modifier la session de suppression de session
Oracle Author Mladen Gogala note qu'un signe @ est maintenant nécessaire pour tuer une session lors de l'utilisation de la colonne Inst_id:
alter system kill session '130,620,@1';
Essayez de déclencher à la connexion
Au lieu d'essayer de déconnecter les utilisateurs, vous ne devriez pas leur permettre de se connecter.
Il existe un exemple d'un tel déclencheur.
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;
J'ai trouvé l'extrait ci-dessous utile.Pris à partir 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
;
Puis j'ai couru :
Alter System Kill Session '<value from ss above>'
;
Pour tuer des sessions individuelles.
Pour répondre à la question posée, voici le SQL le plus précis pour accomplir le travail, vous pouvez le combiner avec PL / SQL LOOP pour exécuter réellement les déclarations de 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;
Si Oracle fonctionne sous Unix/Linux, nous pouvons rechercher toutes les connexions client et les supprimer
grep tous les processus client Oracle :
ps -ef | grep local = non | grep -v grep | awk '{print $ 2}' | wc -l
Tuez tous les processus client Oracle :
tuer -9 ps -ef | grep LOCAL=NO | grep -v grep | awk '{print $2}'