Разрешение зависаний во время Shutdown Immediate

dbstalker, 11 декабря

Достаточно часто ДБА сталкиваются с тем, что остановка экземпляра командой shutdown immediate длится бесконечно долго и кажется, что сессия зависла. Чаще всего это не зависание, если под зависанием понимать ожидание некоего ресурса.

Shutdown immediate может длиться долго в основном по следующим причинам:

  1. Происходит откат незавершенной транзакции
  2. Процесс SMON очищает временные сегменты или выполняет отложенную очистку блоков.
  3. Процессы подключены к базе и не завершаются

1. Происходит откат незавершенной транзакции

В этом случае после команды shutdown immediate в алерте появляется сообщение «Waiting for smon to disable tx recovery». Такая ситуация могла возникнуть по двум причинам:

  • Во время shutdown immediate выполнялся большой запрос
  • Во время shutdown immediate выполнялась большая транзакция

Для большого запроса выполним команду:

 select count(*) from v$session_longops where time_remaining>0;

если результат непустой, то можно выполнить shutdown abort, затем startup restrict и снова shutdown immediate.

Для длинных транзакций выполним:

select sum(used_ublk) from v$transaction;

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

А следующие запросы, будут показывать информацию о ходе восстановления транзакции:

select * from v$fast_start_servers
select *  from v$fast_start_transactions 

По мере восстановления транзакции число записей в представлении v$fast_start_transactions будет уменьшаться. После завершения восстановления база данных будет корректно остановлена. Затем ее можно поднять.

Если у вас нет времени и вам нужно быстро сделать экземпляр рабочим, то можно временно использовать event=”10513 trace name context forever, level 2”.Событие 10513 отключает процесс smon, который должен откатывать транзакцию при остановке экземпляра.

Таким образом, экземпляр будет остановлен командой shutdown immediate без завершения восстановления транзакции. SMON не будет восстанавливать транзакцию до тех пор, пока это событие будет прописано в init.ora.

Не забудьте, когда отпадет надобность в этом событии выполнить команду alter system set events '10513 trace name context off'; или удалить из init.ora и перегрузить экземпляр.

2. Процесс SMON очищает временные сегменты или выполняет отложенную очистку блоков.

Если у вас нет времени для ожидания завершения этого процесса и вы хотите его пропустить, тогда используйте событие event=”10061 trace name context forever, level 10”

Этим вы предостережете SMON от очистки временных сегментов. Только не устанавливайте это событие навсегда: пусть все ж таки SMON выполняет свою работу.

3. Процессы подключены к базе и не завершаются.

В таком случае после команды shutdown immediate, мы видим в alert log что-то типа:

Active call for process 10071 user 'oracle' program 'oracle@server.domain.abc (J001)'
SHUTDOWN: waiting for active calls to complete.
SHUTDOWN: Active sessions prevent database close operation

Это означает, что есть активные вызовы от 'oracle@server.domain.abc (J001)' . База данных ждет завершения этих вызовов. Однако pmon не в состоянии с ними определиться, завершить и почистить экземпляр от этих вызовов.

Рекомендации:

1.До выполнения shutdown immediate, остановить листенер listener:

lsnrctl stop

2. Убить «плохие» процессы. Например так, как указано здесь . Для UNIX :

Сначала : ps -eaf | grep LOCAL

По полученным результатам: Kill -9 [OSPID]

4. Выполнить shutdown immediate .

Не забудьте после старта базы данных стартовать listener.

Можно также установить событие 10046 в сессии выполняющей остановку экземпляра.

SQL>alter session set events '10046 trace name context forever, level 12'

SQL>Shutdown immediate;

Чтобы определиться с причиной вызвавшей «зависание» экземпляра при shutdown immediate в первую очередь нужно смотреть файлы трассировки в папке определенной параметром user_dump_dest и, конечно же, alert.log

Информация к сведению:

Чтобы SMON не занимался undo, тогда когда вам этого не нужно ( имею ввиду при нештатных ситуациях) не установите следующие события:

event = '10510 trace name context forever, level 10'
event = '10511 trace name context forever, level 10'
event = '10512 trace name context forever, level 10'
----
10510 "turn off SMON check to offline pending offline rollback segment"
10511 "turn off SMON check to cleanup undo dictionary"
10512 "turn off SMON check to shrink rollback segments"

Больше о событиях:

здесь и здесь и здесь. источник

1 комментарий

Прокоментировать

blacksaifer
23 декабря 2009 г. в 15:30

Здравствуйте.
Очень познавательны пост, (и вообще блог крайне полезный) но, с моей точки зрения, есть один недочет в ваших рассуждениях: обычно дба сначала делает shutdown immediate, потом видит в алерт-логе сообщение о ожидании, и вот только потом перед ним стает делема - что со всем этим делать. После shutdow immediate "нормально" отработать можно только вариант номер 3, описанный вами, те кильнуть процесс (*nix), который мешает базе погаснуть. С первым и вторым случаем сложнее: вы уже не сможете установить событие, база просто не даст подключиться, а все текущие соединения умрут. Остается или ждать, или сделать kill "жизненно-важному" процессу оракла, те аварийно завершить работу инстанса, ну и надеяться, что все будет нормально.
Для избежания подобных проблем я использую примерно следующий алгоритм остановки баз с высокой нагрузкой:
1. остановить листнер
2. убить сессии, занимающие много места в undo (например, больше 200мб)
SELECT s.sid, s.serial#, s.program, s.username, t.xidusn undo_seg_num,
t.ubafil undo_block_addr_filenum,
t.ubablk undo_block_addr_block,
t.used_ublk,
round(t.used_ublk * 8 / 1024, 2) as used_undo_mb
FROM v$session s
left join v$transaction t on s.saddr = t.ses_addr
where t.xidusn > 0
order by used_undo_mb desc

Если позволяют бизнес-процессы, то этот шаг можно выполнить заранее.

3. убиваем все процессы, обрабатывающие пользовательские подключения (метод только для *nix, ну и, насколько мне известно, вендором не одобряется)
ps -ef | grep oracle<SID> | grep -v "AL=YES" | while read id pid tail; do kill -9

4. ну и вот тут можно сделать
shutdown immediate

5. после чего проверить, действительно ли все процессы, относящиеся к ораклу погасли, а то раз на раз...
ps -ef | grep ora

 

Новый комментарий

Я не спамер: введите суму 8+7



 

От авторов блога

О Блоге - прочитай перед началом.

Задать вопрос и получить ответ - уже решено 94 вопросов

Глоссарий - список терминов и сокращений


 
 

Бизнес форум