    ЧАСТЬ IV 

    Защита данных 

    Эта часть книги посвящена защите данных, т.е. охране данных от множества 
возможных угрожающих ситуаций (как преднамеренных, так и случайных). Дело в 
том, что в ряде случаев действительно существует риск потери данных. 
    •  Система может быть разрушена во время выполнения некоторых программ, 
оставив при этом базу данных в непредсказуемом состоянии. 
    •   При выполнении двух конкурирующих программ между ними может возникнуть 
конфликт, что приведет к получению неправильных результатов. 
    •  Данные могут быть испорчены или изменены анонимным пользователем. 
    •   Обновления могут изменять базу данных недопустимым способом. 
    И т.д. (вариантов может быть бесконечное множество). Следовательно, 
система должна обеспечивать функции защиты базы данных от подобных проблем, в 
частности восстановление, параллелизм, защиту и целостность. Все эти функции 
детально описаны в главах 13-16, представленных в этой части. 

    12 Введение в системы баз данных 

    глава 13 

    Восстановление 
    
    13.1. Введение 

    Эта и следующая глава посвящены восстановлению и параллелизму. Эти функции 
во многом взаимодействуют и являются аспектами более общей проблемы, 
называемой процессом транзакции. Однако из педагогических соображений 
желательно изучать их отдельно. В настоящей главе мы остановимся на функции 
восстановления, однако время от времени ссылки на функцию параллелизма будут неизбежны. 
    Восстановление в системе управления базами данных,(СУБД) означает в первую 
очередь восстановление самой базы данных, т.е. возвращение базы данных в 
правильное состояние, если какой-либо сбой сделал текущее состояние 
неправильным или подозрительным. Основной принцип, на котором строится такое 
восстановление, достаточно прост — это избыточность. Но эта избыточность 
организуется на физическом уровне. Конечно, такая избыточность будет скрыта от 
пользователя, а следовательно, не видна на логическом уровне. Другими словами, 
если любая часть информации, содержащаяся в базе данных, может быть 
реконструирована из другой хранимой в системе избыточной информации, значит, 
база данных восстанавливаема. 
    Перед тем как идти дальше, необходимо уяснить, что принцип восстановления 
и процесс транзакции в целом не зависят от того, является ли базовая система 
реляционной или какой-либо еще. Нужно также отметить, что это весьма обширный 
предмет обсуждения, и мы можем познакомить читателя только с наиболее важными 
и базовыми принципами. Для более углубленного изучения предмета можно 
обратиться к книгам, указанным в списке литературы по рассматриваемой теме (в 
частности, обратите внимание на [13.11]). 
    План главы следующий. После короткого введения описываются процессы 
транзакции и восстановления транзакции (восстановление базы данных после 
неудачного выполнения какой-либо транзакции). Затем проблема восстановления 
обсуждается более глубоко (восстановление после одновременного нарушения всех 
текущих транзакций, вызванного неким сбоем системы). После этого 
рассматривается вопрос восстановления носителей (восстановление после 
физического повреждения базы данных, например из-за поломки головок дискового 
накопителя). Далее описывается исключительно важная проблема двухфазной 
фиксации и обсуждаются операции языка SQL. И наконец, приводится резюме и 
несколько заключительных замечаний. 

    13.2. Транзакции 

    Как уже указывалось, начнем с фундаментального изучения транзакции. 
Транзакция — это логическая единица работы. Рассмотрим пример. Предположим 
сначала, что отношение Р (отношение деталей) включает дополнительный атрибут 
TOTQTY, представляющий собой общий объем поставок для каждой детали. Значение 
TOTQTY для любой определенной детали предполагается равным сумме всех значений 
QTY для всех поставок данной детали. На рис. 13.1 показано добавление в базу 
данных новой поставки со значением 1000 для поставщика S5 и детали PI (INSERT 
добавляет новую поставку к отношению SP, a UPDATE обновляет значение TOTQTY 
для детали Р1). 

    354	Часть IV. Защита данных 

    В приведенном примере предполагается, что речь идет об одиночной, 
атомарной операции. На самом деле добавление новой поставки — это выполнение 
двух обновлений в базе данных (под обновлениями здесь, конечно, понимаются 
операции INSERT, DELETE, а также сами по себе операции DPDATE). Более того, в 
базе данных между этими двумя обновлениями временно нарушается требование, что 
значение TOTQTY для детали Р1 равно сумме всех значений QTY для этой детали. 
Таким образом, логическая единица работы (т.е. транзакция) — не просто 
одиночная операция системы баз данных, а скорее согласование нескольких таких 
операций. В общем, это преобразование одного согласованного состояния базы 
данных в другое, причем в промежуточных точках база данных находится в 
несогласованном состоянии. 

    BEGIN TRANSACTION ; 
    INSERT ( { S#:'S5', P#:'P1', QTY:1000 } } INTO SP IF возникла ошибка THEN 
GO TO UNDO ; 
    UPDATE P WHERE P# = 'PI' TOTOJY := TOTQTY + 1000 ; IF возникла ошибка THEN 
GO TO UNDO ; 
    COMMIT TRANSACTION ; GO TO FINISH ; 
    UNDO : 
    ROLLBACK TRANSACTION ; 
    FINISH : 
    RETURN ; 

    Рис. 13.1. Пример транзакции (псевдокод) 

    Из этого следует, что не допустимо, чтобы одно из обновлений было 
выполнено, а другое нет, так как база данных останется в несогласованном 
состоянии. В идеальном случае должны быть выполнены оба обновления. Однако 
нельзя обеспечить стопроцентную гарантию, что так и будет. Не исключена 
вероятность того, что дела пойдут плохо. Например, система может быть 
разрушена между двумя обновлениями, или же на втором обновлении произойдет 
арифметическое переполнение и т.п. Однако система, поддерживающая процесс 
транзакции, обеспечивает гарантию, что если во время выполнения неких 
обновлений произошла ошибка (по любой причине), то все эти обновления будут 
аннулированы. Таким образом, транзакция или выполняется полностью, или 
полностью отменяется (как будто она вообще не выполнялась). 
    Системный компонент, обеспечивающий атомарность (или ее подобие), 
называется администратором транзакций (или диспетчером транзакций), а ключами 
к его выполнению служат операторы COMMIT TRANSACTION и ROLLBACK TRANSACTION. 
    •   Оператор COMMIT TRANSACTION (для краткости COMMIT) сигнализирует об 
успешном окончании транзакции. Он сообщает администратору транзакций, что 
логическая единица работы завершена успешно, база данных вновь находится (или 
будет находиться) в согласованном состоянии, а все обновления, выполненные 
логической единицей работы, теперь могут быть зафиксированы, т.е. стать постоянными. 
    •  Оператор ROLLBACK TRANSACTION (для краткости ROLLBACK) сигнализирует о 
неудачном окончании транзакции. Он сообщает администратору транзакций, что 
произошла какая-то ошибка, база данных находится в несогласованном состоянии и 
все обновления могут быть отменены, т.е. аннулированы. 
    Следовательно, COMMIT выполняется, если оба обновления прошли успешно, 
изменения в базе данных выполнены и стали постоянными. Если что-то не так, 
если обновление прервано каким-либо условием ошибки, то выполняется ROLLBACK и 
любые изменения отменяются. 
    Обратите внимание, что при этом можно не только модифицировать базу данных 
(или попытаться это сделать), но также и выдать пользователю некоторое 

    Глава 13. Восстановление	355 

    сообщение о том, что произошло. Например, можно выдать сообщение "Пост ка 
добавлена", если выполнена операция COMMIT, или "Ошибка — поставка не , 
бавлена", если операция не выполнена. Выдача сообщений имеет дoпoлнитej ное 
значение для восстановления. Для более подробного обсуждения вопросов этой 
теме можете обратиться к [13.11]. 
    Читателя может удивить отмена обновления. Но дело в том, что система подде 
живает файл регистрации, или журнал, на ленте или (обычно) на диске, где запис 
ваются детали всех операций обновления, в частности новое и старое значения 
мод фицированного объекта. Таким образом, при необходимости отмены некоторого 
о новления система может использовать соответствующий файл регистрации д> 
возвращения объекта в первоначальное состояние. 
    (На самом деле это слишком упрощенное объяснение. На практике файл 
регистра^ состоит из двух частей: активной (или интерактивной) и архивной (или 
автономной). Hi терактивная часть используется во время нормальной системной 
операции по записи детг лей осуществляемых обновлений и обычно содержится на 
диске. После того как интера* тивная часть заполнена, ее содержимое 
перемещается в автономную часть, которая обыч но находится на ленте, поскольку 
обрабатывается последовательно.) 
    Еще один важный момент. Система должна гарантировать, что индивидуальны* 
операторы сами по себе атомарны (т.е. выполняются полностью или не выполняются 
совсем). Это особенно важно для реляционных систем, в которых операторы 
многоуровневые и обычно оперируют множеством кортежей одновременно; такой 
оператор просто не может быть нарушен посреди операции и привести систему в 
несогласованное состояние (например, если выполнена только часть необходимых 
действий). Другими словами, если произошла ошибка во время работы такого 
оператора, база данных должна остаться полностью неизмененной. Более того, это 
должно быть справедливо даже в том случае, когда действия оператора являются 
причиной дополнительной, например каскадной, операции. 

    13.3. Восстановление транзакции 

    Транзакция начинается с успешного выполнения оператора BEGIN TRANSACTION 
(для краткости BEGIN) и заканчивается успешным выполнением либо оператора 
COMMIT, либо ROLLBACK. Оператор COMMIT устанавливает так называемую точку 
фиксации (которая в коммерческих продуктах также называется точкой 
синхронизации (syncpoint)). Точка фиксации соответствует концу логической 
единицы работы и, следовательно, точке, в которой база данных находится (или 
будет находиться) в состоянии согласованности'. В противовес этому, выполнение 
оператора ROLLBACK вновь возвращает базу данных в состояние, в котором она 
была во время операции BEGIN TRANSACTION, т.е. в предыдущую точку фиксации. 
(Понятие "предыдущая точка фиксации" достаточно корректно даже в случае первой 
транзакции в программе при условии, что первый оператор BEGIN по умолчанию 
устанавливает в программе первичную точку фиксации.) Ниже перечислены случаи 
установки точки фиксации. 
    1. Все обновления, совершенные программой с тех пор, как установлена 
предыдущая точка фиксации, выполнены, т.е. стали постоянными. Во время 
выполнения все такие обновления могут расцениваться только как пробные (в том 
смысле, что они могут быть не выполнены, например прокручены назад). 
Гарантируется, что однажды зафиксированное обновление так и останется 
зафиксированным (это и есть определение понятия "зафиксировано"). 
    1 В данном случае термин "база данных" означает доступную для транзакции 
часть базы данных. Другие транзакции могут выполняться параллельно этой 
транзакции и создавать изменения в собственных частях базы данных. Таким 
образом, вся база данных может и не быть в состоянии согласованности в данный 
момент. Однако в нашем обсуждении игнорируется возможность конкуренции между 
транзакциями (поскольку такое упрощение существенно не влияет на 
рассматриваемый вопрос). 

    356	Часть IV. Защита данных 

    2.  Все позиционирование базы данных утеряно, и все блокировки кортежей 
реализованы. Позиционирование базы данных здесь означает, что в любое 
конкретное время программа обычно адресована определенным кортежам. Эта 
адресуемость в точке фиксации теряется. 
    Замечание. Некоторые системы снабжены опцией, с помощью которой программа 
может сохранять адресуемость к некоторым кортежам (и, следовательно, сохранять 
некоторые кортежи заблокированными) от одной транзакции до другой. Более 
подробно это описано несколько ниже. 
    Пункт 2, исключая возможность сохранения некоторой адресуемости и, 
следовательно, соответствующей блокировки кортежей, также применим, когда 
транзакция завершена оператором ROLLBACK, а не COMMIT. К пункту 1 это, 
конечно, не относится. 
    Обратите внимание, что COMMIT и ROLLBACK завершают транзакцию, а не 
программу. В общем, выполнение программы будет состоять из согласования 
нескольких транзакций, запущенных одна за другой, как показано на рис. 13.2. 

    * ——— Транзакция 1 ——— » 
    1 ———	| 
    | 
    Начало	BEGIN                                       COMMIT 
    программы	TRANSACTION 
    « ———— Транзакция 2 (отмененная	) ———— 
    BEGIN	' ROLLBACK 
    TRANSACTION 
    « ————— Транзакция 3 ——— » 
    
    
    ——————————— 1 
    BEGIN                                           COMMIT        Завершение 
    TRANSACTION	программы 

    Рис. 13.2. Выполнение программы — это согласование транзакций 

    А сейчас давайте вернемся к примеру предыдущего раздела (см. рис. 13.1). 
Здесь используется явный тест для определения ошибки и выполняется ROLLBACK, 
если обнаружена любая ошибка. Однако на самом деле программы не всегда могут 
использовать явные тесты для всех возможных ошибок. Следовательно, система 
будет выполнять ROLLBACK неявно для любой программы, которая по какой-либо 
причине не достигла запланированного завершения операций (на рис. 13.1 
"запланированное завершение" означает операцию RETURN, которая завершает 
программу и передает управление назад в систему). 
    Из этого видно, что транзакции — это не только логические единицы работы, 
но также и единицы восстановления при неудачном выполнении операций. При 
успешном завершении транзакции система гарантирует, что обновления постоянно 
установлены в базе данных, даже если система потерпит крах в следующий момент. 
Возможно, что в системе произойдет сбой после успешного выполнения COMMIT, но 
перед тем, как обновления будут физически записаны в базу данных (они все еще 
могут оставаться в буфере оперативной памяти и таким образом могут быть 
утеряны в момент сбоя системы). Даже если подобное случилось, процедура 
перезагрузки системы все равно должна устанавливать эти обновления в базу 
данных, исследуя соответствующие записи в файле регистрации. Из этого следует, 
что файл регистрации должен быть физически записан перед завершением операции 
COMMIT. Это важное правило ведения файла регистра-ции!5в'ёстно~как'протокол 
предварительной записи в журнал (т.е. запись об операции осуществляется перед 
ее выполнен ием). Таким образом, процедура перезагрузки сможет восстановить 
любые успешно завершенные транзакции, хотя их обновления не были записаны 
физически до аварийного отказа системы. Следовательно, как указывалось ранее, 
транзакция действительно является единицей восстановления. 

    Глава 13. Восстановление	357 

    Свойства АСИД 

    Из предыдущих разделов следует, что транзакции обладают четырьмя важными 
свойствами: атомарность, согласованность, изоляция и долговечность (назовем 
это свойствами АСИД). 
    •   Атомарность. Транзакции атомарны (выполняется все или ничего). 
    •   Согласованность. Транзакции защищают базу данных согласованно. Это 
означает, что транзакции переводят одно согласованное состояние базы данных в 
другое без обязательной поддержки согласованности во всех промежуточных 
точках. Согласованность базы данных будет детально обсуждаться в следующих 
главах этой книги. 
    •   Изоляция. Транзакции отделены одна от другой. Это означает, что, если 
даже будет запущено множество конкурирующих друг с другом транзакций, любое 
обновление определенной транзакции будет скрыто от остальных до тех пор, пока 
эта транзакция выполняется. Другими словами, для любых двух отдаленных 
транзакций Т1 и Т2 справедливо следующее утверждение: Т1 сможет увидеть 
обновление Т2 только после выполнения Т2, а Т2 сможет увидеть обновление Т1 
только после выполнения Т1. Более подробно эта тема рассматривается в 
следующих главах книги. 
    •  Долговечность. Когда транзакция выполнена, ее обновления сохраняются, 
даже если в следующий момент произойдет сбой системы. 

    13.4. Восстановление системы 

    Система должна быть готова к восстановлению не только после небольших 
локальных нарушений, таких как невыполнение операции в пределах определенной 
транзакции, но также и после глобальных нарушений типа сбоев в питании ЦПУ 
(центрального процессорного устройства). Местное нарушение по определению 
поражает только транзакцию, в которой оно собственно и произошло. Такие 
нарушения были описаны выше в этой главе. Глобальное нарушение поражает сразу 
все транзакции и, следовательно, приводит к значительным для системы 
последствиям. Далее мы кратко обсудим, что вовлечено в процесс восстановления 
при глобальном нарушении в системе. Существует два вида глобальных нарушений. 
    •   Отказы системы (например, сбои в питании), поражающие все 
выполняющиеся в данный момент транзакции, но физически не нарушающие базу 
данных в целом. Такие нарушения в системе также называют аварийным отказом 
программного обеспечения. 
    •   Отказы носителей (например, поломка головок дискового накопителя), 
которые могут представлять угрозу для базы данных или для какой-либо ее части 
и поражать, по крайней мере, те транзакции, которые используют эту часть базы 
данных. Отказы носителей также называют аварийным отказом аппаратуры. 
    Вначале остановимся на отказах системы. 
    Критической точкой в отказе системы является потеря содержимого основной 
(оперативной) памяти (в частности, рабочих буферов базы данных). Поскольку 
точное состояние какой-либо выполняющейся в момент нарушения транзакции не 
известно, транзакция может не завершиться успешно и, таким образом, будет 
отменена ("прокручена" назад) при перезагрузке системы. 
    Более того, возможно, потребуется (как указывалось выше) повторно 
выполнить определенную успешно завершившуюся до аварийного отказа транзакцию 
при перезагрузке системы, если не были физически выполнены обновления этой транзакции. 
    Возникает вопрос: как во время перезагрузки система узнает, какую 
транзакцию отменить, а какую выполнить повторно? Ответ следующий. В некотором 
предписанном интервале (когда в журнале накапливается определенное число 
записей) система автоматически принимает контрольную точку. Принятие 
контрольной точки включает физическую запись содержимого рабочих буферов базы 
данных непосред

    358	Часть IV. Защита данных 

    ственно в базу данных и специальную физическую запись контрольной точки, 
которая предоставляет список всех осуществляемых в данный момент транзакций. 
На рис. 13.3 рассматривается пять возможных вариантов выполнения транзакций до 
аварийного сбоя системы. 

    Время 

    к 
    1 "1 ——— 1 
    а 
    з                  ' а     ТЗ              1 —————————	—— 1 
    К                               ' Ч     Т4 и и     Т5	1 —— — - 1 
    
    
    1 ——— 
    Контрольная точка ( время tc) 
    Отказ системы ( время tf) 

    Рис. 13.3. Пять вариантов транзакции 

    Ниже приведены пояснения к рисунку. 
    •  Отказ системы произошел в момент времени tf. 
    •  Близлежащая к моменту времени tf контрольная точка была принята в 
момент времени tc. 
    •  Транзакция Т1 успешно завершена до момента времени tc. 
    •  Транзакция Т2 начата до момента времени tc и успешно завершена после 
момента времени tc, но до момента времени // 
    •   Транзакция ТЗ также начата до момента времени tc, но не завершена к 
моменту времени tf. 
    •   Транзакция Т4 начата после момента времени tc и успешно завершена до 
момента времени tf. 
    •   И наконец, транзакция Т5 также начата после момента времени tc, но не 
завершена к моменту времени tf. 
    Очевидно, что при перезагрузке системы транзакции типа ТЗ и Т5 должны быть 
отменены, а транзакции типа Т2 и Т4 — выполнены повторно. Тем не менее 
заметьте, что транзакции типа Т1 вообще не включаются в процесс перезагрузки, 
так как обновления попали в базу данных еще до момента времени tc (т.е. 
зафиксированы еще до принятия контрольной точки). Отметьте также, что 
транзакции, завершившиеся неудачно (в том числе отмененные) перед моментом 
времени tf, вообще не будут вовлечены в процесс перезагрузки (подумайте, почему). 
    Следовательно, во время перезагрузки система вначале проходит через 
процедуру идентификации всех транзакций типа Т2-Т5. При этом выполняются 
перечисленные ниже шаги. 
    1.  Создается два списка транзакций: назовем их UNDO (отменить) и REDO 
(выполнить повторно). В список UNDO заносятся все транзакции, предоставленные 
из записи контрольной точки (т.е. все транзакции, выполняющиеся в момент 
времени tc), а список REDO остается пустым. 
    2.  Осуществляется поиск в файле регистрации (журнале), начиная с записи 
контрольной точки. 
    3.  Если в файле регистрации обнаружена запись BEGIN TRANSACTION о начале 
транзакции Т, то эта транзакция также добавляется в список UNDO. 

    Глава 13. Восстановление 359 

    4.  Если в файле регистрации обнаружена запись COMMIT об окончании 
транзакции Т, то эта транзакция добавляется в список REDO. 
    5.   Когда достигается конец файла регистрации, списки UNDO и REDO 
анализируются для идентификации транзакций типа Т2 и Т4, появившихся в списке 
REDO, и транзакций типа ТЗ и Т5, оставшихся в списке UNDO. 
    После этого система просматривает назад файл регистрации, отменяя 
транзакции из списка UNDO, а затем просматривает снова вперед, повторно 
выполняя транзакции из списка REDO. 
    Замечание. Восстановление базы данных в правильное состояние путем отмены 
выполненных операций иногда называется обратным восстановлением. Аналогично, 
восстановление ее в правильное состояние повторным выполнением называется прям 
ым во ест ан овл гнием. 
    И наконец, когда такая восстановительная работа завершена, система готова 
приступить к дальнейшей работе. 

    13.5. Восстановление носителей 

    Замечание. Процесс восстановления носителей в корне отличается от 
восстановления транзакции и системы. Он включен в обсуждение для завершенности 
рассматриваемой темы. 
    Как уже отмечалось, отказы носителей — это нарушения типа поломки головок 
дискового накопителя или дискового контроллера, когда некоторая часть базы 
данных разрушается физически. Восстановление после такого нарушения включает 
перезапись (или восстановление) базы данных с резервной копии (или дампа) и 
последующее использование файла регистрации — как его активной, так и архивной 
части. В общем, такое восстановление — это повторное выполнение всех 
транзакций, вызванное применением резервной копии. При этом нет необходимости 
отмены транзакций, которые выполнялись в момент отказа носителей, поскольку по 
определению все обновления таких транзакций полностью утеряны. 
    Таким образом, восстановление средств подразумевает наличие утилиты дамп/ 
восстановление. Дамп-часть этой утилиты используется для сохранения резервной 
копии. Такие копии могут сохраняться либо на ленте, либо другим архивным 
способом. После отказа носителей восстановительная часть утилиты используется 
для создания базы данных со специализированной резервной копии. 

    13.6. Двухфазная фиксация 

    В этом разделе описывается очень важная разработка двухфазной фиксации. 
Двухфазная фиксация важна всякий раз, когда определенная транзакция может 
взаимодействовать с несколькими независимыми администраторами ресурсов, каждый 
из которых руководит своим собственным набором восстанавливаемых ресурсов и 
поддерживает собственный файл регистрации (журнал). Например, пусть 
транзакция, запущенная в среде MVS компьютера IBM, модифицирует как базу 
данных IMS, так и базу данных DB2 (между прочим, такая транзакция вполне 
допустима). Если транзакция завершается успешно, то все ее обновления, как для 
данных IMS, так и для данных DB2, могут быть выполнены. В противном случае все 
ее обновления могут быть отменены или транзакция перестанет быть атомарной. 
    Для транзакции не имеет смысла выполнять COMMIT для IMS и ROLLBACK для 
DB2, и, даже если подобная инструкция будет выполнена для обеих баз, система 
все равно может дать сбой между двумя этими операциями. Вместо этого 
транзакция выполняет общесистемную команду COMMIT (или ROLLBACK). Этими 
операциями руководит системный компонент, называемый координатором. Он 
гарантирует, что оба администратора ресурсов (т.е. IMS и DB2 в примере) 
передают или отменяют обновления, за которые они 

    360	Часть IV. Защита данных 

    ответственны. Более того, он обеспечивает такую гарантию, даже если 
система отказала в середине процесса. Это происходит благодаря протоколу 
двухфазной фиксации. 
    Ниже приведена последовательность работы координатора. Для простоты 
примем, что транзакция в базе данных выполнена успешно, а значит, выдана 
системная операция COMMIT, а не ROLLBACK. После получения запроса на 
выполнение COMMIT координатор осуществляет следующий двухфазный процесс. 
    1. Во-первых, он дает указание всем администраторам ресурсов быть готовыми 
действовать на транзакцию "любым способом". На практике это означает, что 
каждый участник процесса, т.е. каждый администратор ресурсов, должен насильно 
сохранить все записи журнала (файла регистрации) для локальных ресурсов, 
используемых транзакцией вне собственных физических файлов регистрации (т.е. 
вне энергозависимой памяти). Теперь, что бы ни случилось, администратор 
ресурсов не будет выполнять постоянной записи от имени транзакции, а сможет 
при необходимости передавать свои обновления и отменять их. Если 
насильственная запись прошла успешно, администратор ресурсов отвечает 
координатору, что все "ОК" или, наоборот, — "Not OK". 
    2.  Когда координатор получил соответствующие ответы от всех участников, 
он насильственно заносит записи в собственный физический файл регистрации, 
указывая свое решение относительно транзакции. Если все ответы были "ОК", то 
решение будет "выполнить", а если был ответ "Not OK", то — "прокрутить назад". 
Затем координатор любым способом информирует каждого участника о своем 
решении, и каждый участник согласно инструкции должен локально зафиксировать 
или аннулировать транзакцию. Отметьте, что каждый участник должен делать то, 
что ему велел координатор во время фазы 2, — в этом и состоит протокол. 
Обратите также внимание, что именно появление записи решения в физическом 
файле регистрации координатора и отмечает переход с фазы 1 на фазу 2. 
    Теперь, если система дает сбой в какой-либо точке во время полного 
процесса, процедура перезагрузки будет искать запись решения в файле 
регистрации координатора. Если она ее обнаружит, то сможет указать, где 
произошла остановка. Если эта запись не будет обнаружена, значит, принятым 
решением будет откат и, следовательно, процесс будет завершен. 
    Замечание. Стоит подчеркнуть, что если координатор и участники выполняют 
свою работу на различных механизмах (поскольку они могут представлять собой 
распределенную систему), то ошибка в работе координатора может привести к 
тому, что некий участник довольно долго будет ожидать решения координатора. Во 
время ожидания ни одно обновление, произведенное транзакцией, не сможет 
произойти с помощью этого участника, оно будет как бы скрыто от других 
транзакций (иными словами, такое обновление будет заблокировано, об этом еще 
будет идти речь в следующих главах). 
    Отметим, что диспетчер передачи данных (см. главу 2), также называемый 
администратором передачи данных, может считаться администратором ресурсов в 
описанном выше смысле. Это означает, что сообщения можно считать такими же 
восстанавливаемыми ресурсами, как и базу данных, а администратор передачи 
данных способен участвовать в процессе двухфазной фиксации. Для дальнейшего 
изучения этого вопроса, а также общей идеи двухфазной фиксации, можете 
обратиться к [13.11]. 

    13.7. Поддержка языка SQL 

    SQL поддерживает обычные операции COMMIT и ROLLBACK; эти операции, в свою 
очередь, вызывают операцию CLOSE (закрыть). При этом происходит потеря всего 
позиционирования базы данных. 
    Замечание. Некоторые версии языка SQL обеспечивают опцию защиты от потери 
позиционирования при автоматической операции CLOSE (по операции COMMIT, но не 
по ROLLBACK). Подобная опция в некоторых будущих разработках станет стандартной. 

    Глава 13. Восстановление	361 

    Различие между поддержкой SQL для транзакций и общей иерархической стр> 
турой состоит в том, что SQL не включает никакой явной операции BEGIN 
TRANSACTK Вместо этого транзакция начинается неявно тогда,  когда программа 
выполня операцию инициации транзакции. (Подобно описанной выше опции поддержки 
п зиционирования, явная операция BEGIN TRANSACTION будет включена в новые 
разрабо ки.) Детальное описание операций инициации транзакции здесь не 
приводится, дост; точно сказать, что операции определения и манипулирования 
данными, обсуждаемы в предыдущих главах книги, относятся к операциям 
инициации. Специальный оперг тор SET TRANSACTION используется для определения 
некоторых характеристик трата* ции, которую нужно будет инициировать. Здесь мы 
обсудим только две характери стики: режим доступа ч уровень изоляции. 
Синтаксис оператора следующий: 
    SET TRANSACTION список опций ; 
    (где список опций должен включать хотя бы одну опцию). 
    •  Опция режима доступа — это либо READ CNLY, либо READ WRITE. Если ничего 
не оговорено,   то   используется   READ   WRITE;   если   оговорен  уровень   
изоляции   REAE 
    UNCOMMITTED, ТО ИСПОЛЬЗуСТСЯ READ  ONLY. ЕСЛИ ИСПОЛЬЗуСТСЯ READ  WRITE, 
урОВВНЬ ИЗОЛЯЦИИ не должен быть READ UNCOMMITTED. 
    •  Опция уровня изоляции принимает форму ISOLATION LEVEL изоляция, где 
изоляция — 
    ЭТО READ UNCOMMITTED, READ COMMITTED, REPEATABLE  READ ИЛИ SERIALIZABLE. 
Более ПОДрОбные пояснения приведены в главе 14. 

    13.8. Резюме 

    В этой главе кратко приведена необходимая информация по теме управления 
транзакциями. Транзакция — это логическая единица работы, а также единица 
восстановления (кроме того, единица параллелизма и целостности — см. главы 14 
ч 16 соответственно). Транзакции имеют свойства АСИД — атомарность, 
согласованность, изоляция и долговечность. Управление транзакциями — это 
наблюдение за выполнением гарантии этих важных свойств. Коротко говоря, общую 
функцию системы можно определить как надежное выполнение транзакции. 
    Транзакции инициируются операцией BEGIN TRANSACTION и завершаются либо 
операцией осмят TRANSACTION (в случае успешного завершения), либо ROLLBACK 
TRANSACTICN (в случае неудачного завершения). Оператор COMMIT устанавливает 
точку фиксации (при этом обновления становятся постоянными). Выполнение 
оператора ROLLBACK возвращает базу данных в предыдущую точку фиксации 
(обновления отменены). Если транзакция не достигает запланированного 
завершения, система обеспечит для нее выполнение операции ROLLBACK 
(восстановление транзакции). Для отмены обновлений система поддерживает 
ведение файла регистрации (также называемого журналом). Более того, записи 
журнала для данной транзакции должны быть занесены в физический файл 
регистрации до выполнения операции COMMIT для данной транзакции (это 
называется правилом предварительной записи в журнал). 
    Система также гарантирует сохранение свойств АСИД даже в случае аварийного 
отказа системы. Для обеспечения такой гарантии система должна, во-первых, 
повторно выполнить всю работу, выполняемую транзакциями, которые успешно 
завершились до момента отказа, и, во-вторых, отменить всю работу, выполняемую 
транзакциями, которые начались, но не закончились до момента сбоя. 
Восстановление системы осуществляется как часть процедуры перезагрузки (также 
называется процедурой перезагрузки/восстановления). Анализируя последнюю 
запись контрольной точки, система определяет, какую работу необходимо 
выполнить повторно, а какую отменить. Записи контрольных точек заносятся в 
журнал в предписанной последовательности. 
    Система также обеспечивает восстановление носителей путем восстановления 
базы данных со специализированной резервной копии (дампа) с последующим исполь

    362	Часть IV. Защита данных 

    зованием журнала и повторным выполнением работы, завершенной после 
сохранения резервной копии. Утилиты восстановления с резервной копии 
необходимы для поддержки восстановления носителей. 
    Системы, позволяющие транзакциям взаимодействовать с многоуровневыми 
администраторами ресурсов (например, две различных СУБД), должны использовать 
протокол, называемый двухфазной фиксацией, так как он поддерживает свойство 
атомарности транзакции. Две фазы — это подготовительная фаза, на которой 
координатор дает указание всем участникам быть готовыми "действовать любым 
способом", и фаза фиксации, на которой координатор, полагая, что все участники 
получили удовлетворительный ответ, инструктирует их, как провести фиксацию. 
    Касаясь поддержки восстановления в стандарте SQL, необходимо отметить, что 
SQL действительно обеспечивает явные операции сомгг и ROLLBACK (но не явную 
операцию BEGIN). Он также поддерживает операцию SET TRANSACTION, которая 
позволяет пользователю определить режим доступа и уровень изоляции для 
следующей начинающейся транзакции. 
    И еще один момент. По умолчанию считалось, что в данной главе речь идет о 
прикладных программах. Тем не менее, все описанное применимо также и к 
операционной среде конечного пользователя (хотя в такой среде это может быть 
несколько скрыто). Например, продукты SQL обычно позволяют пользователю 
вводить SQL-операции интерактивно с терминала. Обычно каждая такая 
интерактивная SQL-операция обрабатывается как транзакция; система будет по 
умолчанию выполнять от имени пользователя автоматическую операцию COMMIT, 
после того как SQL-операция выполнена (и конечно, автоматическую операцию 
ROLLBACK, если произойдет сбой). Тем не менее, в некоторых системах 
пользователи могут запрещать такие автоматические операции COMMIT, а вместо 
этого выполнять целую серию операций SQL (за чем следует явная операция 
COMMIT) как единую транзакцию. Однако на практике этого делать не 
рекомендуется, так как это может заблокировать часть базы данных и тем самым 
сделать ее недоступной для других пользователей на длите льное время. Более 
того, в подобной операционной среде для конечных пользователей возможна 
тупиковая ситуация, что является еще одним аргументом в пользу отказа от такой 
практики (это еще будет обсуждаться в следующей главе). 

    Упражнения 

    13.1. Система не позволяет данной транзакции зафиксировать изменения в 
определенной базе данных, т.е. без одновременного фиксирования во всех других 
базах данных. Почему? 
    13.2. Транзакции не могут быть вложены одна в другую. Почему? 
    13.3. Изложите правило предварительной записи в журнал. Для чего оно нужно? 
    13.4. Что такое логическая операция восстановления: а) насильственно 
записанных буферов в базу данных во время операции COMMIT; б) буферов, которые 
никогда физически не записывались в базу данных до выполнения операции COMMIT? 
    13.5. Изложите протокол двухфазной фиксации и поясните логические операции 
отказа во время каждой фазы а) координатора, б) участника. 

    Список литературы 

    13.1. Bernstein P.A., Hadzilacos V., Goodman N. Concurrency Control and 
Recovery in Database Systems. — Reading, Mass.: Addison-Wesley, 1987. 
    В этой книге намного шире, чем в представленной главе, описывается не 
только восстановление, но и полное управление транзакцией. 

    Глава 13. Восстановление	363 

    13.2. Bjork L.A. Recovery Scenario for a DB/DC System // Proc. ACM 
National Conference. —Atlanta, Ga, 1973. 
    Эта и аналогичная статья Дэвиса (Davies) [13.6] представляют собой, 
наверное, наиболее ранние работы в области восстановления. 
    13.3. Cms R.A. Data Recovery in IBM DATABASE 2 // IBM Sys. J. — 1984. —23, 
№ 2. 
    Здесь детально описан механизм восстановления DB2 (тем самым дано очень 
хорошее общее описание механизма восстановления). В частности, объясняется, 
как DB2 восстанавливается во время самого процесса восстановления после сбоя в 
системе, в то время как сама транзакция находится посередине отката. Такая 
проблема требует специального обеспечения для уверенности в том, что 
нефиксированные обновления от транзакции в процессе отката будут действительно отменены. 
    13.4. Date C.J. Recovery // An Introduction to Database Systems: Vol. II.— 
Reading, Mass.: Addison-Wesley, 1983. 
    Эта часть книги основана на более раннем изучении обучающей программы. 
    13.5. Date C.J. Distributed Database: A closer Look // C.J. Date and Hugh 
Darwen. Relational Database Writings 1989-1991. — Reading, Mass.: 
Addison-Wesley, 1992. 
    В этой работе описан базисный протокол двухфазной фиксации. Возможны 
некоторые усовершенствования базисного протокола. Например, если участник Р 
отвечает координатору С в фазе 1, что при рассмотрении он не совершал 
обновлений для транзакции (т.е. он был только для чтения), то С может просто 
игнорировать Р на фазе 2. Соответственно, если все участники в фазе 1 отвечают 
"только для чтения", фаза 2 может быть опущена. 
    Также возможны и другие усовершенствования. В статье приводится вводное 
описание некоторых из них. Специально описаны протоколы предположительной 
фиксации и предположительного отката (улучшенные версии базисного протокола), 
модель дерева операций (когда участник отвечает за несколько частей транзакции 
координатора), а также ситуация, при которой во время процесса подтверждения 
от участника к координатору происходит коммуникационны и сбой. 
    13.6. Davies C.T., Recovery Jr. Semantics for a DB/DC System // Proc. ACM 
National Conf. — Atlanta, Ga, 1973. 
    См. комментарий к [13.2]. 
    13.7. Davies С.Т., Recovery Jr. Data Processing Spheres of Control // IBM 
Sys. J. — 1978.—17, №2. 
    Сферы управления (Spheres of Control) были первой попыткой изучить и 
формализовать то, что в дальнейшем стало управлением транзакциями. Сфера 
управления — это абстракция, представляющая часть работы, которая снаружи 
может выглядеть атомарной. В отличие от транзакций, сферы управления могут 
вкладываться одна в другую до любого уровня (в упражнениях к данной главе 
рассмотрен вопрос, почему транзакции не могут быть вложены одна в другую). 
    13.8. Garcia-Molina H., Salem К. Sagas // Proc. 1987 ACM SIGMOD Intern. 
Conf. on Management of Data. — San Francisco, Calif., 1987. 
    Большинство проблем, связанных с транзакциями, состоит в том, что по 
умолчанию транзакции длятся очень короткое время (милли- или даже 
микросекунды). Но если транзакция длится долго (часы, дни, недели), то в 
случае ее отката будет отменена большая часть работы; но, даже если все 
пройдет успешно, она все еще должна удерживать ресурсы системы на 
неопределенно долгое время, тем самым блокируя других пользователей (этот 
вопрос под

    364	Часть IV. Защита данных 

    робнее обсуждается в следующей главе). К сожалению, множество реальных 
транзакций стремится к увеличению времени своего действия, особенно в новейших 
сферах применения, таких как аппаратные средства и разработка программного обеспечения. 
    Саги — попытка решить эту проблему. Сага (saga) — это согласование 
коротких транзакций при условии гарантии со стороны системы, что либо все 
транзакции в согласовании будут выполнены успешно, либо будут выполнены 
некоторые компенсационные транзакции, чтобы отменить эффект успешно 
выполненных транзакций в случае незавершенного выполнения саги (таким образом, 
делается так, как будто сага не была выполнена). Например, в банковских 
системах можно иметь транзакцию "Добавить $100 на счет А", компенсационной 
транзакцией, очевидно, будет "Вычесть $100 со счета А". Протяженность операции 
COMMIT позволяет пользователю информировать систему о том, что в случае отмены 
только что завершенной транзакции будет запущена компенсационная транзакция. 
Отметьте, что компенсационная транзакция в идеале никогда не завершается откатом. 
    13.9. Gray J. Notes on Data Base Operating System // Operating Systems: An 
Advanced Course. —New York, N.Y.: Springer-Verlag, 1978. 
    Это один из первых источников литературы о транзакциях, содержащий первое 
общедоступное описание протокола двухфазной фиксации. Очевидно, оно не столь 
всеобъемлюще, как более новые работы [13.11], но тем не менее, мы все еще 
рекомендуем ознакомиться с ним. 
    13.10. Gray J. The Transaction Concept: Virtues and Limitations // Proc. 
7th Intern. Conf. on Very Large Data Bases. — Cannes, France, 1981. 
    Краткое описание проблем, связанных с транзакциями, включая их реализацию. 
Как обычно полагают, транзакции не могут вкладываться одна в другую (в 
упражнениях к данной главе рассмотрен вопрос, почему транзакции не могут быть 
вложены одна в другую). А может, все-таки возможно, чтобы транзакция состояла 
из нескольких "подтранзакций"? Краткий ответ таков: "Да!" В некоторых случаях 
транзакции во время своего выполнения могут устанавливать промежуточные точки 
сохранения и соответственно в случае необходимости откатываться в такую 
предыдущую точку вместо того, чтобы откатиться полностью к началу транзакции. 
Такая концепция представляется наиболее близкой к реальному понятию 
транзакции. Обратите внимание, что установка точек сохранения — это не то же 
самое, что осуществление операции COMMIT; обновления, осуществленные 
транзакцией, все еще не становятся видимыми для других транзакций, до тех пор 
пока не будет успешного завершения всей транзакции. 
    13.11. Gray J., Reuter A. Transaction Processing: Concepts and 
Techniques.— San Mateo, Calif: Morgan Kaufrnann, 1993. 
    Если какой-либо научный текст по компьютерам заслуживает эпитета 
"классический", то это, наверное, данная книга. Ее размер просто устрашающий 
(1000 страниц), однако авторы сумели пролить свет даже на самые темные аспекты 
обсуждаемой темы и сделать чтение достаточно легким. Надо отдать должное 
авторам в их попытке помочь в решении большинства реальных проблем; книга 
практична и освещает базисные проблемы транзакции весьма детально, здесь 
представлены фрагменты программ, показывающие базисные алгоритмы и структуры 
данных. Настоятельно рекомендуем вам эту книгу. 
    13.12. Gray J. et al. The Recovery Manager of the System R Data Manager // 
ACM Сотр. Surv. — 1981. — 13, № 2. 
    Работы [13.12, 13.15] имеют отношение к особенностям восстановления 
системы R. В [13.12] дается краткий обзор всей подсистемы восстановления, а в 
[13.15] детально описывается механизм затененной страницы (см. ниже). 

    Глава 13. Восстановление	365 

    13.13. Harder Т., Reuter A. Principles of Transaction-Oriented Database 
Recovery // Ibid.— 1983.— 15, №4. 
    Описаны основные свойства восстановления — атомарность, согласованность, 
изоляция, долговечность. Статья дает очень четкое и подробное представление о 
принципах восстановления. Здесь приведена терминология и классификация 
множества случаев восстановления. 
    Также приведены эмпирические рисунки, показывающие частоту возникновения и 
типичное время восстановления для трех видов сбоев (локальных, системных и 
сбоев носителей) в больших системах. 
    Тип сбоя	Частота возникновения	Время восстановления 
    Локальный Системный Сбой носителей	10-100 в минуту Несколько раз в неделю 
Один или два раза в год	Равно времени выполнения транзакции Несколько минут 
1-2 часа 
    13.14. Korth H.F., Levy E., Silberschatz A. A Formal Approach to Recovery 
by Compensating Transactions // Proc. 16th Intern. Conf. on Very Large Data 
Bases. — Brisbane, Australia, 1990. 
    Здесь идет речь о компенсационных транзакциях, которые используются в 
сагах [13.8] и в других случаях для "отмены" зафиксированных (а также и 
незафиксированных) транзакций. 
    13.15. Lorie R. A. Physical Integrity in a Large Segmented Database // ACM 
TODS. — 
    1977.— 2, № 1. 
    Как уже объяснялось в комментариях к [13.12], в этой статье описывается 
механизм затененной страницы — один из наиболее важных аспектов восстановления 
системы R. (Отметим, что термин целостность (Integrity) в заглавии статьи 
имеет значение, несколько отличное от описанного в данной книге.) 
    Идея механизма затененной страницы очень проста. Когда незафиксированное 
обновление первый раз записывается в базу данных, система не переписывает уже 
существующую страницу, а сохраняет новую где-нибудь на диске. Старая страница 
— это "тень" новой. Фиксация обновления включает установку различных 
указателей на новую страницу и отбрасывание затененной; наоборот, откат 
обновления назад— это переустановка указателей на затененную страницу и 
отбрасывание новой. 
    Несмотря на простоту, механизм затененной страницы имеет один серьезный 
недостаток, который разрушает любую физическую кластеризацию, существовавшую 
до этого в данных, и потому этот механизм не используется в DB2. 
    13.16. Mohan С., Haderle D., Lindsay В. et al. ARIES: A Transaction 
Recovery Method Supporting Fine-Granularity Locking and Partial Rollbacks 
Using Write-Ahead Logging // Ibid. — 1992. — 17, № 1. 
    В статье описан алгоритм ARIES, который применяется в некоторых 
коммерческих и экспериментальных системах, в частности DB2. Алгоритм ARIES 
(Algorithm for Recovery and Isolation Exploiting Semantics) расшифровывается 
как алгоритм восстановления и использующей изоляцию семантики. 

    Ответы к некоторым упражнениям 

    13.1. Это будет конфликтовать со свойством атомарности транзакции. Если бы 
транзакция зафиксировала некоторые, но не все свои обновления, то 
незафиксированные обновления можно было впоследствии аннулировать, в то время 
как зафиксированные, конечно же, нельзя отменить. Таким образом, для 
транзакции не будет выполнено условие атомарности "выполнить все или ничего". 

    366 Часть IV, Защита данных 

    13.2. Это будет конфликтовать со свойством атомарности для внешней 
транзакции. Предположим, транзакция В была вложена в транзакцию А, тогда 
последовательность событий будет такой: 

    BEGIN TRANSACTION (транзакция А) транзакция А обновляет кортеж а 
    BEGIN TRANSACTION (транзакция В) 

    транзакция В обновляет кортеж Ь 

    CCMMIT (транзакция В) ROLLBACK (транзакция А) 

    Если кортеж b восстанавливается в свое предыдущее значение (назовем его 
pre-А), то COMMIT транзакции В, по сути, не происходит полностью. Однако если 
операция COMMIT транзакции В была истинной, то кортеж b не может быть 
восстановлен в свое значение pre-А и, следовательно, операция ROLLBACK 
транзакции А не может быть успешной. 
    Таким образом, транзакции не могут вкладываться одна в другую. 
    Однако многие авторы (например, в [13.6]) предложили возможность 
вкладывания транзакций методом отбрасывания требования долговечности (свойство 
"Д" в АСИД) для внутренней транзакции. Это означает, что операция COMMIT, 
выполняемая внутренней транзакцией, зафиксирует обновления этой транзакции, но 
только для следующего внешнего уровня. Если же этот внешний уровень 
завершается откатом назад, то внутренняя транзакция также завершается откатом. 
В данном примере операция COMMIT для транзакции В зафиксировала бы обновления 
только до окончания транзакции А, но не для внешнего мира, и впоследствии 
действительно могла бы быть отменена. 
    Отметим, что вложенные транзакции в языках, подобных SQL, весьма неудобны 
для выполнения, так как в этих языках имеется один серьезный недостаток — 
отсутствие операции BEGIN TRANSACTION (необходим некоторый явный способ 
определения начала внутренней транзакции или точки фиксации для отката, если 
транзакция потерпела неудачу). 
    13.4. а) операция REDO (не является необходимым следствием отказа 
системы); б) физическая операция UNDO (не является необходимой, следовательно, 
запись журнала UNDO также не является необходимой). 

    Глава 13. Восстановление	367 
