Что делать, если Oracle SHUTDOWN IMMEDIATE завис?

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

А что произошло?

По всей вероятности, команде остановки БД никак не удается завершить какую-то открытую сессию пользователя. Почему это происходит? Данный вопрос требует отдельного обсуждения. В одном из моих конкретных случаев, когда пришлось бороться с зависанием, один из пользователей запустил запрос к плохо индексированной таблице с большим объемом данных. Запрос ушел в долгое вычисление. Попытки отмены запроса, попытки принудительного завершения сессии ни к чему не приводили. Команда полной остановки БД также уперлась в этот процесс и никак не могла с ним справиться.

Как с этим бороться? Можно позвать на помощь команду SHUTDOWN ABORT, но делать это крайне не рекомендуется. Есть риск получить повреждения в БД. Поэтому в данной ситуации лучше использовать более безопасный метод – найти зависшие процессы на уровне операционной системы (ОС) и завершить их вручную.

Как найти зависшие процессы БД в ОС

Находим все имеющиеся процессы, в имени которых присутствует название экземпляра БД в формате oracle$ORACLE_SID. Дополнительно проверяем наличие пометки LOCAL равно YES или NO. Когда БД уже находится в состоянии остановки, найденные таким образом процессы являются кандидатами на удаление.

[oracle@serv ~]$ ps -ef | grep LOCAL | grep oracle$ORACLE_SID
oracle 13708 1 1 14:58 ? 00:01:06 oraclefrmtst (LOCAL=NO)

 

В нашем случае, вот он. Единственный активный процесс с зависшей сессией.

Список идентификаторов зависших процессов

Чтобы принудительно завершить найденные процессы в ОС надо получить список их идентификаторов.

[oracle@serv ~]$ ps -ef | grep LOCAL | grep oracle$ORACLE_SID | awk '{print $2}'
13708

Завершение процессов командой kill

Перенаправлением полученного списка идентификаторов процессов команде kill можно завершить все найденные процессы одним вызовом.

[oracle@serv ~]$ kill -9 $(ps -ef | grep LOCAL | grep oracle$ORACLE_SID | awk '{print $2}')
[oracle@serv ~]$ echo $?
0

 

Источник: Ed Chen Logic

Close Menu