Можно ли убить один запрос в Oracle без прерывания сеанса? - PullRequest
15 голосов
/ 21 января 2009

Я хотел бы иметь возможность убить запрос пользователя в Oracle 10.2.0.4, не прерывая весь сеанс. Это позволило бы завершить запрос, но не регистрировать этого пользователя вне его сеанса, чтобы он мог продолжать делать другие запросы. Это вообще возможно? Или тупой молоток убийства сеанса - единственный способ завершить выполнение запроса?

Ответы [ 4 ]

16 голосов
/ 22 января 2009

Я нашел трюк. Я понятия не имею, насколько безопасно играть, но это работает. Существует событие Oracle 10237, которое описывается как «имитация ^ C (для целей тестирования)».

У вас должны быть SID и SERIAL # сеанса, который вы хотите прервать.

Вызовите SYS.DBMS_SYSTEM.SET_EV ( sid , serial # , 10237, 1, ''), чтобы активировать событие в целевом сеансе. Любой выполняемый в данный момент оператор должен быть прерван (получая «ORA-01013: пользователь запросил отмену текущей операции»). Пока событие установлено, любые дальнейшие операторы, которые пытается выполнить сеанс, будут немедленно прекращены с той же ошибкой.

Чтобы деактивировать событие, выполните тот же вызов с четвертым параметром, установленным в «0». После этого сеанс сможет снова выполнять операторы.

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

Вот пример кода. Он предназначен для запуска в SQLPlus как анонимный блок с переменными подстановки "sid" и "serial", определенными соответствующим образом. Вы можете превратить его в хранимую процедуру с такими параметрами.

DECLARE
  l_status  v$session.status%TYPE;
BEGIN

  dbms_system.set_ev( &sid, &serial, 10237, 1, '');

  LOOP
    SELECT status INTO l_status FROM v$session
      WHERE sid = &sid and serial# = &serial;
    EXIT WHEN l_status='INACTIVE';
  END LOOP;

  dbms_system.set_ev( &sid, &serial, 10237, 0, '');
END;
2 голосов
/ 22 января 2009

Я подозреваю, что это возможно, так как вы можете сделать это в TOAD. Во время выполнения запроса появляется диалоговое окно «Отмена», по которому можно нажать, чтобы остановить запрос.

Как это реализовано, я не знаю, но было бы очень интересно узнать тоже.

Если вы используете java, есть метод java.sql.Statement cancel (), который должен это делать. Смотрите здесь для некоторых заметок и ограничений ...

http://download.oracle.com/docs/cd/B14117_01/java.101/b10979/tips.htm#BACDAICJ

1 голос
/ 18 апреля 2011

В идеале приложение пользователя должно иметь возможность отменить запрос (через OCICancel или эквивалентный).

В противном случае лучше всего использовать Resource Manager (если в Oracle EE), вы можете использовать DBMS_RESOURCE_MANAGER.SWITCH_CONSUMER_GROUP_FOR_SESS, чтобы установить целевой сеанс для группы потребителей CANCEL_SQL.

Еще один способ отменить запрос других сеансов, который не работает с клиентскими сеансами sqlplus windows, - это отправить срочный сигнал процессу Oracle с помощью kill -URG (это взлом, не для повседневного использования)

Я написал о том, почему это работает здесь:

http://blog.tanelpoder.com/2010/02/17/how-to-cancel-a-query-running-in-another-session/

1 голос
/ 22 января 2009

Вы можете посмотреть на лимит ресурсов:

"Если пользователь превышает ограничение ресурса уровня вызова, Oracle останавливает обработку оператора, откатывает оператор и возвращает ошибку. Однако все предыдущие операторы текущей транзакции остаются без изменений, и сеанс пользователя остается подключенным. "

Это предполагает, что причиной отмены SQL является ограничение ресурсов, а не обновление неправильного набора строк (например). Я подозреваю, что вы не сможете повлиять на текущий запущенный SQL, добавив ограничение ресурсов.

http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/security.htm#i13767
http://download.oracle.com/docs/cd/B19306_01/server.102/b14231/dbrm.htm#i1010776
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...