СПАСОИ (10) - Лекция №11 - Восстановление БД после сбоя: различия между версиями
ILobster (обсуждение | вклад) |
ILobster (обсуждение | вклад) м (→Ведение версий записи: t2, а не t1) |
||
(не показаны 4 промежуточные версии этого же участника) | |||
Строка 13: | Строка 13: | ||
[[Файл:10semSPASOIl11pic1.png|center|400px]] | [[Файл:10semSPASOIl11pic1.png|center|400px]] | ||
Предположим, что в момент {{Формула|f=T_1}} выполняется SELECT и проверяется время обновления записи. Если {{Формула|f=T_1 > | Предположим, что в момент {{Формула|f=T_1}} выполняется SELECT и проверяется время обновления записи. Если {{Формула|f=T_1 > t_2}}, то запись читается из БД. Если {{Формула|f=T_1 < t_2 = t_{обновления} }}, то записи читаются из сегмента отката (до обновления). Представленный механизм ведения версии записей обеспечивает целостность чтения данных в интервале {{Формула|f=T_1-T_2}}. | ||
=== Схема восстановления данных после сбоя === | === Схема восстановления данных после сбоя === | ||
Строка 28: | Строка 28: | ||
Предположим, что произошёл сбой. После восстановления выполняются следующие действия: | Предположим, что произошёл сбой. После восстановления выполняются следующие действия: | ||
# докат системы - ищется последняя метка о перезаписи всех "грязных" блоков на диск, и начиная с этой отметки и до конца файла читаются записи полных транзакций, и они перезаписываются в БД; | # докат системы (<code>rollforward</code>) - ищется последняя метка о перезаписи всех "грязных" блоков на диск, и начиная с этой отметки и до конца файла читаются записи полных транзакций, и они перезаписываются в БД; | ||
# откат незавершённых транзакций - потому что в БД могли попасть записи незавершённых транзакций. Из сегмента отката с конца транзакции читаются записи до обновления и записываются в БД. | # откат незавершённых транзакций (<code>rollback</code>) - потому что в БД могли попасть записи незавершённых транзакций. Из сегмента отката с конца транзакции читаются записи до обновления и записываются в БД. | ||
По оператору <code>COMMIT</code> сначала необходимо записать обновлённые записи транзакции в БД, а только потом эти записи записать в журнал транзакций. | По оператору <code>COMMIT</code> сначала необходимо записать обновлённые записи транзакции в БД, а только потом эти записи записать в журнал транзакций. | ||
Ещё можно почитать в [http://ru.wikipedia.org/wiki/%D0%92%D0%BE%D1%81%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B1%D0%B0%D0%B7%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85 этой статье]. | |||
==== Пример восстановления БД после сбоя ==== | ==== Пример восстановления БД после сбоя ==== | ||
Строка 46: | Строка 48: | ||
=== Обработка тупиковых ситуаций === | === Обработка тупиковых ситуаций === | ||
Предположим, что процедура проверки | Предположим, что процедура проверки реализуется иначе, чем в [[СПАСОИ (10) - Лекция №10 - SQL (продолжение)#Блокировка обновляемых записей | прошлой лекции]]: | ||
проводка(счёт1, счёт2, остаток) | проводка(счёт1, счёт2, остаток) |
Текущая версия от 21:08, 16 июня 2013
...начало
Этот конспект ещё не дописан. Здесь не хватает: - примера попадания в БД записей незавершённых транзакций - примера порядка выполнения COMMIT |
Особенности разработки приложений для работы с БД в сети
Ведение версий записи
Она же блокировка по чтению.
После выполнения COMMIT
записи из сегмента отката удаляются не сразу. Это связано с ведением версий записей.
Предположим, что в момент $$T_1$$ выполняется SELECT и проверяется время обновления записи. Если $$T_1 > t_2$$, то запись читается из БД. Если $$T_1 < t_2 = t_{обновления}$$, то записи читаются из сегмента отката (до обновления). Представленный механизм ведения версии записей обеспечивает целостность чтения данных в интервале $$T_1-T_2$$.
Схема восстановления данных после сбоя
При восстановлении данных используются два системных файла:
- журнал транзакций;
- сегмент отката.
В журнале транзакции сохраняются полные транзакции (записываются записи после обновления). В этом же журнале записываются метки по перезаписи всех "грязных" блоков.
В сегменте отката для каждой незавершённой транзакции записываются записи до и после обновления.
Предположим, что произошёл сбой. После восстановления выполняются следующие действия:
- докат системы (
rollforward
) - ищется последняя метка о перезаписи всех "грязных" блоков на диск, и начиная с этой отметки и до конца файла читаются записи полных транзакций, и они перезаписываются в БД; - откат незавершённых транзакций (
rollback
) - потому что в БД могли попасть записи незавершённых транзакций. Из сегмента отката с конца транзакции читаются записи до обновления и записываются в БД.
По оператору COMMIT
сначала необходимо записать обновлённые записи транзакции в БД, а только потом эти записи записать в журнал транзакций.
Ещё можно почитать в этой статье.
Пример восстановления БД после сбоя
Здесь выполняется только докат. Отката нет, потому что в сегменте отката нет незавершённых транзакций.
Перезапись "грязных" блоков из общесистемного буфера на диск выполняется в следующей строгой последовательности:
- блоки сегмента отката;
- блоки журнала транзакций;
- блоки БД.
Обработка тупиковых ситуаций
Предположим, что процедура проверки реализуется иначе, чем в прошлой лекции:
проводка(счёт1, счёт2, остаток)
-- дебет
UPDATE счёт1 -- запись автоматически блокируется до завершения операции (до COMMIT)
...
-- кредит
UPDATE счёт2 -- запись автоматически блокируется до завершения операции (до COMMIT)
...
COMMIT;
При одновременном обращении к этой процедуре двух процессов возможно возникновение тупиковой ситуации.
Современные СУБД отслеживают такие ситуации. Процесс с наименьшим приоритетом (или произвольный) аварийно завершается с некоторым кодом. В программе, выдавшей запрос на обновление, должна быть предусмотрена обработка данной ошибки.