Тема 9. Защита от системных сбоев. Принципы работы транзакций: Принцип корректности – транзакция при отсутствии других транзакций переводит базу данных из одного согласованного состояния в другое. Принцип атомарности – транзакция либо выполняется целиком, либо не выполняется вообще. Операции транзакций по перемещению данных. INPUT(X) – копирование блока диска, содержащего элемент X в оперативную память; READ(X,t) – копирование элемента X в локальную переменную t; WRITE(X,t) – копирование значения переменной t в элемент X в оперативной памяти; OUTPUT(X) – копирование блока, содержащего элемент X из буфера оперативной памяти на диск. Пример. Воздействие транзакции на оперативную память и диск. Пусть согласованное состояние базы данных предполагает, что A=B. Действия T A в памяти В в памяти А на диске READ(A,t) 8 8 8 t=t*2 16 8 8 WRITE(A,t) 16 16 8 READ(B,t) 8 16 8 8 t=t*2 16 16 8 8 WRITE(B,t) 16 16 16 8 OUTPUT(A) 16 16 16 16 OUTPUT(B) 16 16 16 16 В на диске 8 8 8 8 8 8 8 16 Записи в протокол. <START T> - транзакция Т стартовала; <COMMIT T> - транзакция Т была завершена успешно; <ABORT T> - транзакция Т отменена. Протокол возврата. При выполнении команды WRITE осуществляется запись в протокол следующего типа: <T,X,v> - транзакция Т изменяет элемент базы данных X, прежнее значение которого v. Правила протокола-возврата. Если транзакция T изменяет элемент базы данных X, тогда запись в протокол <T,X,v> должна быть записана до момента, когда новое значение элемента X будет записано на диске. Если транзакция завершена успешно, тогда ее запись COMMIT в протокол должна быть записана только после того, как все элементы базы данных, измененные транзакцией, будут записаны на диск. Для записи протокола на диск добавим команду: FLUSH LOG. Пример. № 1 2 3 4 5 6 7 8 9 10 11 12 Действие t Aв памяти Вв памяти А на диске В на диске Протокол <START T> READ(A,t) t=t*2 WRITE(A,t) READ(B,t) t=t*2 WRITE(B,t) FLUSH LOG OUTPUT(A) OUTPUT(B) 8 16 16 8 16 16 8 8 16 16 16 16 16 16 16 16 8 8 16 8 8 8 8 8 8 8 8 8 8 8 8 16 16 16 16 8 16 <T, A, 8> <T, B, 8> <COMMIT T> FLUSH LOG Правила восстановления с использование протокола-возврата. Сканируем протокол с конца, фиксируя записи <COMMIT T> и <ABORT T>. При нахождении записи <T,X,v>: Если T – транзакция, для которой есть запись <COMMIT T> или <ABORT T>, ничего не делаем. В противном случае, требуется изменить на значение v элемент X на диске. После проведения всех изменений для всех незавершенных транзакций записывается в протокол <ABORT T>. Контрольные точки. При установке контрольной точки: Запрещается прием новых транзакций. Ожидается, когда все активные транзакции будут завершены или отменены. Протокол записывается на диск. Делается запись в протокол <CKPT>. Возобновляется прием транзакций. Например, <START T1>; <COMMIT T1>; <T1, A, 5>; <COMMIT T2>; <START T2>; <CKPT>; <T2, B, 10>; <START T3>; <T2, C, 15>; <T3, E, 25>; <T1, D, 20>; <T3, F, 30> Неподвижные контрольные точки. Делается запись в протокол <START CKPT(T1… TK)>, где T1…TK – идентификаторы активных транзакций; Ожидается, пока все транзакции T1…TK не будут завершены или отменены, но не запрещается стартовать другим транзакциям. После завершения транзакций T1…TK делается запись в протокол <END CKPT> и записывается протокол на диск. Например, <START T1>; <T1, A, 5>; <START T2>; <T2, B, 10>; <START CKPT (T1, T2)>; <T2, C, 15>; <START T3>; <T1, D, 20>; <COMMIT T1>; <T3, E, 25>; <COMMIT T2>; <END CKPT>; <T3, F, 30> Протокол повтора. При выполнении команды WRITE осуществляется запись в протокол следующего типа: <T,X,v> - транзакция Т изменяет элемент базы данных X, новое значение которого v. Правило. Перед модификацией любого элемента базы данных X на диске необходимо, чтобы все записи протокола, соответствующие этой модификации, включая записи <T,X,v> и <COMMIT T>, были записаны на диск. Пример. № Действие 1 2 3 4 5 6 7 8 9 10 11 12 t Aв памяти Вв памяти А на диске В на диске Протокол <START T> READ(A,t) t=t*2 WRITE(A,t) READ(B,t) t=t*2 WRITE(B,t) 8 16 16 8 16 16 8 8 16 16 16 16 FLUSH LOG OUTPUT(A) OUTPUT(B) FLUSH LOG 16 16 16 16 8 8 16 8 8 8 8 8 8 8 8 8 8 8 8 16 16 16 16 8 16 <T, A, 16> <T, B, 16> <COMMIT T> Правила восстановления при использовании протокола-повтора. Определяем множество завершенных транзакций. Сканируем протокол с начала. При нахождении записи <T,X,v>: а) Если T - незавершенная транзакция, ничего не делать; б) Если Т – завершенная транзакция, записать значение v в элемент базы данных X. Для каждой незавершенной транзакции T записать в протокол <ABORT T> и перенести протокол на диск. Контрольные точки. Делается запись в протокол <START CKPT(T1...TK)>, где T1…TK – активные транзакции, записать протокол на диск. Записывается на диск все элементы базы данных, которые были изменены транзакциями, которые были завершены до записи START CKPT, но еще не отображены на диске. Записывается в протокол <END CKPT> и протокол переносится на диск. Например, <START T1>; <T1, A, 5>; <START T2>; <COMMIT T1>; <T2, B, 10>; <START CKPT (T2)>; <T2, C, 15>; <START T3>; <T3, D, 20>; <END CKPT>; <COMMIT T2>; <COMMIT T3>. Протокол возврата-повтора. При выполнении команды WRITE осуществляется запись в протокол следующего типа: <T,X,v,w> - транзакция Т изменяет элемент базы данных X, старое значение которого v, а новое значение - w. Правило. Перед изменением любого элемента базы данных X на диске необходимо, чтобы запись <T,X,v,w> попала на диск. Запись <COMMIT T> может, как предшествовать, так и следовать за любыми изменениями элементов на диске. Пример. № Действие 1 2 3 4 5 6 7 8 9 10 11 12 t Aв памяти Вв памяти А на диске В на диске Протокол <START T> READ(A,t) t=t*2 WRITE(A,t) READ(B,t) t=t*2 WRITE(B,t) FLUSH LOG OUTPUT(A) 8 16 16 8 16 16 8 8 16 16 16 16 16 16 8 8 16 8 8 8 8 8 8 8 8 8 8 8 8 16 16 8 <T, A, 8, 16> <T, B, 8, 16> <COMMIT T> OUTPUT(B) FLUSH LOG 16 16 16 16 16 Правила восстановления с помощью протокола возврата-повтора. Отменить все незавершенные транзакции, начиная с более поздней. Повторить все завершенные транзакции, начиная с более ранней. Контрольные точки. Записывается в протокол <START транзакции; CKPT(T1..TK)>, где T1…TK – активные Записываются на диск все буферы, содержащие измененные данные. Записывается <END CKPT> в протокол, протокол записывается на диск. Например, <START T1>; <T1, A, 4, 5>; <START T2>; <COMMIT T1>; <T2, B, 9, 10>; <START CKPT (T2)>; <T2, C, 14, 15>; <START T3>; <T3, D, 19, 20>; <END CKPT>; <COMMIT T2>; <COMMIT T3>. Архивирование. Используется протокол типа повтора или повтора-возврата. Заносится в протокол запись <START DUMP>. Выполняется контрольная точка по правилам соответствующего протокола. Выполняется полная или частичная выгрузка данных. Сохраняется протокол. Заносится в протокол <END DUMP>. Пример. (1,2,3,4). Диск Пусть элементами базы данных являются (A,B,C,D). Начальные значения Архив Копируется А А=5 Копируется В С=6 Копируется С B=7 Копируется D Конечное состояние элементов базы данных (5, 7, 6, 4). Копия базы данных в архиве – (1, 2, 6, 4). Протокол. <START DUMP>; <START CKPT(T1, T2)>; <T1, A, 1, 5>; <T2, C, 3, 6>; <COMMIT T2>; <T1, B, 2, 7>; <END CKPT>; Завершено архивирование <END DUMP>.