Алгоритм фиксации транзакции

dbstalker, 01 октября

В этом посте уже шла речь о том, как выполняется фиксация транзакции. Сейчас коснемся этого же вопроса, но копнем немного глубже. А, главное, найдем подводные камешки.

Алгоритм выполнения фиксации транзакции:

  1. Выполняется генерация SCN для транзакции.
  2. Обновляется таблица транзакций заголовка сегмента отката
  3. Снимается exclusive pin с заголовка сегмента отмены, undo блок попадает в пул свободных блоков
  4. Создается маркер фиксации транзакции в redo log буфере
  5. Процессом LGWR сбрасывается redo log буфер на диск
  6. Освобождаются блокировки на записях и таблицах.

До тех пор пока все эти 6 пунктов не будут пройдены ораклом и сеанс не получит управления, сеанс считает, что фиксация не завершена. Таким образом, если произойдет какой либо сбой на любом из этих шагов, транзакция для сеанса считается незавершенной. Значит возможна такая ситуация когда промежуток времени между пунктом 2 и пунктом 5 будет настолько значительным, что другие сессии могут обратиться к таблице транзакций заголовка нашего сегмента отката, увидеть, что транзакция завершена и работать с измененными данными. И это будет происходить в то время, когда сеанс-владелец еще не завершил фиксацию транзакции.

Один пример такой ситуации. База работает в режиме ARCHIVELOG. Сеанс изменил данные и начал процесс фиксации. Но диск оказался заполненным - базе некуда писать архивные файлы. В оперативные журналы также нельзя ничего записать, так как они ждут архивации. В это время некий сеанс делает выборку для какого-то отчета. По таблице транзакций видит, что последняя транзакция, которая изменяла необходимые данные, уже завершена. Значит можно использовать новые данные для формирования отчета. Но на самом деле транзакция не завершена! Хорошо если администратор разберется в причине зависания сессий, которые изменяют данные. Найдет место для архивации журналов повторного выполнения, архивация продолжится, сеансы отвиснут и наша транзакция, в самом деле, будет завершена. А если, администратор, не мудрствуя лукаво, просто перегрузит сервер? Так как в журналы повторного выполнения не попала информация о завершении нашей транзакции, то данные после перезагрузки будут восстановлены на состояние до начала транзакции. А отчет, выполненный по обновляемым нашей транзакцией данным, будет неправильным!!! Разве такая ситуация не возможна?

Как можно избежать такого хода событий. Предлагаю:

  • Администратору нужно хорошо подумать перед перезагрузкой экземпляра
  • Перед выполнением важных выборок желательно выполнить простенькую транзакцию и зафиксировать ее.

Отступление.

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

2 комментария

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

Игорь
2 июля 2010 г. в 13:05

>А отчет, выполненный по обновляемым нашей транзакцией данным, будет неправильным!!!
> Разве такая ситуация не возможна?

Нет, не возможна.

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

Нет, нельзя.

Вы забыли, что Oracle для того, чтобы определить зафиксирована транзакция или нет не только смотрит на слоты журнала транзакций (которые могут быть перезаписаны во время выполнения транзакции - это когда голова обгоняет хвост), но и проверяет SCN в заголовке блока данных.
Если SCN(1) читающей транзакции меньше, чем SCN(2) транзакции изменяющей данные, то данные берутся из сегмента отката.
А SCN1, который взялся из заголовка файла данных повторного выполнения, меньше SCN2 т.к. LGWR не сбросил буфера на диск и CKPT не обновил заголовок и не вписал туда SCN2.
Пример
SCN=10 (SystemChangeNumber)
Транзакция на измерения получает SCN2=11
>Сеанс изменил данные и начал процесс фиксации. Но диск оказался заполненным - базе некуда писать архивные файлы.
Транзакция на чтение получает SCN1=10 (SystemChangeNumber, т.к. LGWR не может, CKPT не может). Читает блоки, понимает, есть измененные, не зафиксированные данные (SCN в блоке > SCN транзакции, надо взять из undo данные с SCN=10) ну и т.д.

П.С. Хотя мне кажется, что если LGWR встанет - встанет сервер и не о какой транзакции на чтение речи быть не может.

Админ перезагрузил сервер, поднимает базу, информации о не зафиксированной транзакции в базе нет.
Согласованность данных.
Вуаля.

Вячеслав
13 августа 2010 г. в 14:31

эта ситуация описана с примером здесь - только тут lgwr искусственно заморозили. Но тем не менее - сеанс номер 2 увидел в таблице 2, а не 1. Как написано в статье, признаком того что транзакция зафиксирована является шаг 3 - и видимо как только он выполнен Оракл undo уже не смотрит.

 

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

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



 

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

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

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

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


 
 

Бизнес форум

Последние темы:

Нужна гадалка
20 июля, 1 ответа
Бутель для воды
20 июля, 1 ответа