2012-02-05 4 views
3

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

Сессия отмечена как убитая. Что мне делать?

Я нашел дополнительную информацию по следующей ссылке: http://oracleunix.wordpress.com/2006/08/06/alter-system-kill-session-marked-for-killed-forever/ , но если я launche следующий запрос возвращает 241 записей. Что это значит?

SELECT spid 
    FROM v$process 
WHERE NOT EXISTS (SELECT 1 
         FROM v$session 
         WHERE paddr = addr); 

ответ

5

Я собираюсь предположить, что вы убили сессию только как select, как вы заявляете, и что вы работаете по варианту * nix.

Если вы используете update или delete, тогда ждать завершения отката будет лучше. Вы можете проверить количество отката, используя следующий запрос, который я бессовестно украденный из orafaq, потому что я не помню эти вещи с верхней частью моей головы:

select rn.Name "Rollback Segment", rs.RSSize/1024 "Size (KB)", rs.Gets "Gets" 
    , rs.waits "Waits", (rs.Waits/rs.Gets)*100 "% Waits" 
    , rs.Shrinks "# Shrinks", rs.Extends "# Extends" 
    from sys.v_$rollName rn, sys.v_$rollStat rs 
where rn.usn = rs.usn; 

Во-первых select не должны использовать с помощью отката ... если это произойдет, то у вас, вероятно, есть функция, которая делает что-то около DML, что не очень хорошая идея. Вы также не упоминаете, использует ли этот код select ссылку на базу данных, если это немного облегчает ситуацию.

Если select не использует ссылку на базу данных и не выполняет никаких DML, то найденная вами ссылка сделает все, что вам нужно. Ваши 241 строки должны быть в основном одинаковыми - может быть более одного значения, если у вас есть несколько процессов, у которых есть эта проблема. Я хотел бы изменить запрос:

select p.* 
    from v$process p 
    left outer join v$session s 
    on p.addr = s.paddr 
where s.saddr is null 

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

Вы можете перейти прямо к своей коробке и выдать sigtermkill 1234. Это выдает сигнал завершения процесса на уровне вашей ОС и должен избавиться от него.

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

Этот должен Работа.Тем не менее, можно сделать гораздо более радикальным; Я был недавно после того, как подчиненная виртуальная машина начала принимать входящие соединения, а затем не отправила ошибку или не вернула значение.

Предупреждение: Чем более жестоким вы попадаете в поле, тем более жестоким оно будет для вас, и, скорее всего, все пойдет не так.

Следующим шагом вверх от SIGTERM является SIGKILL. Это сигнал ОС, чтобы убить процесс, не задавая никаких вопросов. На * nix это kill -9 1234. Это редко необходимо. Если вы выполняли DML, он остановит любой откат и может затруднить восстановление базы данных до согласованного состояния в случае сбоя.

Если это все еще не работает, у вас возникают серьезные проблемы. В примере, приведенном с помощью VM, мы закончили выполнение следующего, чтобы остановить проблему. Большинство из них не рекомендуется :-).

  1. Oracle - alter system kill 123
  2. OS - kill 1234
  3. OS - kill -9 1234
  4. Oracle - shutdown immediate - это на самом деле politer чем kill -9 ..... Он не отправляет sigkill в ОС и ждет процессов для отката и т. Д. Но всегда полезно быть вежливым в вашей базе данных.
  5. Oracle - shutdown abort - это примерно то же, что и sigkill. Это сигнал к базе данных, чтобы немедленно остановить все и умереть (путающая терминология, которую я знаю).
  6. ОС - reboot
  7. Да, это так, reboot не работал. Как только вы достигнете этого этапа, вам лучше надеяться, что вы используете виртуальную машину. Мы закончили его удаление ...
+0

Большое спасибо! Сессия сама закончилась через несколько часов, но мне действительно интересно знать – Revious

+0

Я улучшил и разъяснил некоторые части этого ответа здесь: http://stackoverflow.com/questions/9545560/how-to-kill-a-running-select -statement/9546094 # 9546094 – Ben

5

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

Попробуйте этот запрос:

select vt.used_ublk from v$transaction vt, v$session vs where vs.taddr=vt.addr and vs.sid=&&sid; 

Теперь, если вы запустите выше запроса несколько раз подряд, является used_ublk падение или повышение? Если он падает, сеанс возвращается.

Надеюсь, что это поможет.

+0

Спасибо, это действительно интересно знать! – Revious

Смежные вопросы