Как я могу завершить все сеансы, подключающиеся к моей базе данных Oracle?

StackOverflow https://stackoverflow.com/questions/55342

Вопрос

Мне нужно быстро (и принудительно) завершить все внешние сеансы, подключающиеся к моей базе данных Oracle, без присмотра и администратора.

Я не хочу просто заблокировать базу данных и позволить пользователям корректно выйти из нее.

Как бы я это написал?

Это было полезно?

Решение

На этот ответ сильно повлиял разговор здесь: 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 с самим собой.

Другие советы

Как СИС:

startup force;

Брутальный, но элегантный.

Прежде чем убивать сеансы, если возможно, сделайте

ALTER SYSTEM ENABLE RESTRICTED SESSION;

чтобы остановить подключение новых сеансов.

Я некоторое время использовал что-то подобное, чтобы завершить свои сеансы на общем сервере.Первую строку «где» можно удалить, чтобы завершить все сеансы, отличные от «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;

Если вы хотите запретить новым пользователям подключаться, но разрешить текущим сеансам продолжаться до тех пор, пока они не станут неактивными, вы можете перевести базу данных в режим QUIESCE:

ALTER SYSTEM QUIESCE RESTRICTED;

Из Руководство администратора базы данных Oracle:

Активные сеансы без DBA будут продолжаться до тех пор, пока они не станут неактивными.Активный сеанс - это то, что в настоящее время находится внутри транзакции, запроса, выборки или оператора PL/SQL;или сессия, которая в настоящее время проводит любые общие ресурсы (например, Enqueues).Невозможные сеансы не допускаются активными ... как только все сеансы, не являющиеся DBA

Дополнительная информация

Важные изменения Oracle 11g для изменения сеанса уничтожения сеанса

Автор Oracle Mladen Gogala отмечает, что теперь требуется знак убить сеанс при использовании столбца Inst_id:

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

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

Попробуйте триггер при входе в систему

Вместо того, чтобы пытаться отключить пользователей, вы не должны позволять им подключаться.

Есть и пример такого триггера.

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;

Я нашел приведенный ниже фрагмент полезным.Взято из: 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>'
;

Убить отдельные сессии.

Чтобы ответить на заданный вопрос, вот самый точный SQL для выполнения работы, вы можете объединить его с циклом PL/SQL, чтобы фактически запустить заявления о убийстве:

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;

Если Oracle работает в Unix/Linux, мы можем выполнить поиск всех клиентских подключений и уничтожить их.

grep весь клиентский процесс Oracle:

PS -EF | grep local = нет | grep -v grep | awk '{print $ 2}' | wc -l

Убейте все клиентские процессы Oracle:

убить -9 ps -ef | grep LOCAL=NO | grep -v grep | awk '{print $2}'

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top