Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Управление данными (пособие).pdf
Скачиваний:
280
Добавлен:
21.05.2015
Размер:
5.42 Mб
Скачать

12.Управление транзакциями и целостность баз данных

Одним из важнейших требований к функционированию любых информационных систем с базами данных является поддержание хранимых данных в целостном, логически согласованном состоянии. Только при выполнении этого требования данные представляют какую-либо ценность для пользователей. База данных находится в согласованном (целостном) состоянии, если в ней выполнены (удовлетворены) все ограничения целостности, определенные для базы данных. На практике, однако, в случае, когда данные в базе данных не являются статическими, а изменяются во времени, обеспечение этого требования сопряжено с целым рядом серьезных трудностей.

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

Рассмотрим пример. Пусть в базе данных имеются два отношения: отношение Студент, имеющее два атрибута Имя_студента и Средний_балл, и отношение Успеваемость с атрибутами Имя_студента, Дисциплина, Оценка. Значение атрибута Средний_балл отношения студент представляет собой среднее значение оценок конкретного студента, полученных им по всем сданным дисциплинам. Если теперь, мы производим ввод в отношение Успеваемость данных об оценке, полученной неким студентом по сданной им новой дисциплине, то помимо ввода соответствующего нового кортежа в отношение Успеваемость, в отношении

СТУДЕНТ должно быть скорректировано и значение атрибута СРЕДНИЙ БАЛЛ для этого студента. Очевидно, что из-за последовательного во времени выполнения этих двух действий, имеется момент времени, когда база данных находится в рассогласованном, не целостном состоянии, т.е. когда находящееся

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

Таким образом, в процессе выполнения операций над хранимыми данными происходит переход базы данных из одного согласованного состояния

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

155

причин (например, аварийного сбоя системы) операция по модификации данных не выполняется до конца, и база данных остается в рассогласованном состоянии.

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

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

Транзакция – это логическая единица работы СУБД, это последовательность операторов манипулирования данными, выполняющаяся как единое целое и переводящая базу данных из одного согласованного состояния в другое. Лозунг транзакции – «все или ничего».

Транзакция обладает четырьмя важными свойствами:

Атомарность,

Согласованность,

Изолированность и

Долговечность.

Их обычно называют свойствами АСИД (по первым буквам свойств). Атомарность. Транзакция выполняется как атомарная, неделимая

операция – либо выполняется вся операция целиком, либо она целиком не выполняется (все или ничего).

Согласованность. Транзакция переводит базу данных из одного согласованного (целостного) состояния в другое согласованное (целостное) состояние, без обязательной поддержки согласованности данных во все промежуточные моменты времени.

Изолированность. Транзакции отделены (изолированы) одна от другой. Это означает, что транзакции, инициированные разными пользователями не должны влиять друг на друга (тем более мешать друг другу), т.е. они должны выполняться так, как если бы они выполнялись по очереди, последовательно друг за другом.

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

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

156

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

Подана команда ROLLBACK – откатить транзакцию. По этой команде результат работы неудачной транзакции, т.е. транзакции, в процессе выполнения которой возникла какая-либо ошибка, полностью аннулируются. Тем самым база данных приводится к состоянию, в котором она находилась перед началом неудачной транзакции.

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

Таким образом, наличие в СУБД механизма поддержки транзакций подразумевает, что система гарантирует нахождение базы данных в логически согласованном (целостном) состоянии до начала и после окончания выполнения транзакции или автоматическое приведение данных в целостное согласование при восстановлении работоспособности системы.

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

Следует заметить, что не любая СУБД и не всегда обеспечивает выполнение всех свойств АСИД в полном объеме. Ниже, проблемы реализации механизма управления транзакциями рассматриваются более подробно. Эти проблемы можно разделить на две группы. Это:

1)обеспечение согласованности данных, т.е. фактически обеспечение восстановления данных, при сбоях системы, и

2)обеспечение согласованности данных при совместной работе с базой данных нескольких пользователей.

13.Откат транзакций и восстановление данных после сбоев. Журнализация изменений базы данных

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

Общими принципами восстановления согласованного состояния данных являются следующие:

Результаты зафиксированных транзакций должны быть сохранены в восстановленном состоянии базы данных;

Результаты незафиксированных транзакций должны отсутствовать в восстановленном состоянии базы данных.

Именно это и означает, что восстанавливается последнее во времени согласованное состояние базы данных.

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

Индивидуальный откат транзакции. Откат транзакции может быть

инициирован при выполнении транзакции путем подачи команды ROLLBACK. Например, откат транзакции может быть инициирован самой СУБД в случае возникновения какой-либо ошибки (деление на ноль и др.), или при выборе транзакции в качестве «жертвы» при обнаружении ситуации синхронизационного тупика (см. ниже).

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

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

158

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

Восстановление после отказа внешнего устройства долговременного хранения данных (дисков) – жесткий сбой системы. Эта ситуация может возникнуть из-за разрушения структуры записанных на дисках данных, повреждения поверхности дисков, головок записи (чтения и т.д.).

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

Журнализация изменений базы данных тесно связана не только с механизмом управления транзакциями, но и с буферизацией страниц базы данных в оперативной памяти. Проблема восстановления данных решилась бы гораздо проще, если бы все изменения данных сразу же фиксировались во внешней памяти системы. Такое решение, однако, привело бы к резкому падению эффективности системы из-за объективно существенной разницы в скорости доступа к данным в оперативной памяти и в устройствах внешней памяти. Буферизация страниц базы данных в оперативной памяти является единственным реальным способом достижения удовлетворительной производительности СУБД.

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

Таким образом, система поддерживает в оперативной памяти два типа буферов – буферы страниц базы данных и буферы журнала транзакций.

Страницы базы данных, содержимое которых в буфере (в оперативной памяти) отличается от содержимого страниц во внешней памяти, называют «грязными» (dirty) страницами. Система должна поддерживать список «грязных» страниц и обеспечивать время от времени их выталкивание из оперативной памяти во внешнюю память, осуществляя, тем самым, фиксацию изменений базы данных.

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

159

Другое дело – ситуация мягкого сбоя системы, когда содержимое буферов оперативной памяти (как буферов данных, так и буферов журнала) утрачивается. В этом случае для обеспечения возможности восстановления данных необходимо выполнение определенных правил выталкивания во внешнюю память буферов базы данных и буферов журнала транзакций.

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

Соответствующий протокол журнализации (и управления буферизацией)

называется Write Ahead Log (WAL) – «пиши сначала в журнал». Суть этого протокола состоит в том, что, если требуется вытолкнуть во внешнюю память измененный объект базы данных, то перед этим нужно гарантировать выталкивание во внешнюю память журнала записи о его изменении. Это означает, что если во внешней памяти базы данных содержится объект, к которому применена некоторая команда модификации, то во внешней памяти журнала транзакций содержится запись об этой операции. Обратное неверно, если во внешней памяти журнала содержится запись о некотором изменении объекта, то во внешней памяти базы данных может и не быть самого измененного объекта.

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

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

транзакций.

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

Периодически или при наступлении определенного события (например,

количество страниц в dirty-списке превысило определенный порог, или количество свободных страниц в буфере уменьшилось и достигло критического значения) система принимает так называемую контрольную точку.

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

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

160

этом последней записью в журнал, производимой от имени данной транзакции, является специальная запись о конце этой транзакции.

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

Индивидуальный откат транзакции.

Для того чтобы можно было выполнить по журналу транзакций индивидуальный откат транзакции, все записи в журнале относящиеся к данной транзакции связываются в обратный список. Началом списка для не закончившихся транзакций является запись о последнем изменении базы данных, произведенной данной транзакцией. Для закончившихся транзакций (индивидуальные откаты которых уже невозможны) началом списка является запись о конце транзакции, которая обязательно вытолкнута во внешнюю память журнала. Концом списка всегда служит первая запись об изменении базы данных, произведенном данной транзакцией. В каждой записи имеется уникальный системный номер транзакции, чтобы можно было восстановить прямой список записей об изменениях базы данных данной транзакцией.

Индивидуальный откат транзакции (речь идет о не закончившихся транзакциях) выполняется следующим образом:

Просматривается список записей, сделанных данной транзакцией в журнале транзакций (от последнего изменения к первому изменению).

Выбирается очередная запись из списка данной транзакции.

Выполняется противоположная по смыслу операция: вместо операции INSERT выполняется соответствующая операция DELETE, вместо операции

DELETE выполняется INSERT, и вместо прямой операции UPDATE обратная операция UPDATE, восстанавливающая предыдущее состояние объекта базы данных.

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

При успешном завершении отката в журнал заносится запись о конце транзакции.

Восстановление после мягкого сбоя.

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

161

оперативной памяти и выталкиваются во внешнюю независимо. Вследствие этого, несмотря на применение протокола WAL, после мягкого сбоя часть набора страниц внешней памяти соответствует объекту до изменения, а часть – после изменения, так как не все «грязные» страницы базы данных были вытолкнуты во внешнюю память.

Состояние внешней памяти базы данных называется физически согласованным, если наборы страниц всех объектов согласованы, т.е. соответствуют состоянию объекта либо после его изменения, либо до изменения.

В журнале транзакций отмечаются точки физической согласованности базы данных, так называемые контрольные точки – моменты времени, в которые во внешней памяти содержатся согласованные результаты операций, завершившихся до соответствующего момента времени, и отсутствуют результаты операций, которые не завершились, и при этом во внешнюю память полностью вытолкнут буфер журнала транзакций. Такие точки обозначают tpc

(time of physical consistency).

Последний момент, когда гарантированно были вытолкнуты «грязные» страницы – это момент принятия последней контрольной точки. К моменту мягкого сбоя возможны пять вариантов состояния транзакций по отношению к моменту последней контрольной точки, которые представлены на рис. 13.1.

Время

tpc

tf

T1

T2

T3

T4

T5

Контрольная точка

Отказ системы

(время tpc)

(время tf)

Рис. 13.1. Пять вариантов состояний транзакций к моменту мягкого сбоя.

Как показано на рис 13.1, последняя контрольная точка принималась в момент tpc . Мягкий сбой системы произошел в момент tf (time of fatal).

162

Транзакции T1-T5 характеризуются следующими свойствами:

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

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

Т3-транзакция начата до принятия контрольной точки и не завершена в результате сбоя. Такую транзакцию необходимо откатить. Проблема, однако, в том, что часть страниц данных, измененных этой транзакцией, уже содержится во внешней памяти – это те страницы, которые были обновлены до принятия контрольной точки. Следов изменений, внесенных после контрольной точки в базе данных нет. Записи журнала транзакций, сделанные до принятия контрольной точки, вытолкнуты во внешнюю память, те записи журнала, которые были сделаны после контрольной точки, отсутствуют во внешней памяти журнала. Поэтому для этой транзакции должны быть аннулированы изменения данных, произведенные до контрольной точки.

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

T5-транзакция начата после принятия контрольной точки и не завершена в результате сбоя. Никаких следов этой транзакции нет ни во внешней памяти журнала транзакций, ни во внешней памяти базы данных. Для такой транзакции никаких действий предпринимать не нужно, ее как бы и не было

вовсе.

Восстановление системы после мягкого сбоя осуществляется как часть процедуры перезагрузки системы при перезагрузке системы: транзакции Т2 и Т4 необходимо частично или полностью повторить, транзакцию Т3-частично откатить, для транзакций Т1 иТ5 никаких действий предпринимать не нужно. Отметим, что транзакции, завершившиеся неудачно и, следовательно, отмененные перед моментом времени tf, вообще не будут вовлечены в процесс перезагрузки, т.к. все изменения, которые были произведены в ходе их выполнения, к этому моменту уже скомпенсированы.

При перезагрузке системы выполняются следующие действия. Создается два списка транзакций UNDO (отменить) и REDO (повторить).В

список UNDO заносятся все транзакции из последней записи контрольной точки (т.е. все транзакции, выполнявшиеся в момент принятия контрольной точки).

163

Список REDO остается пустым. В нашем случае будет: UNDO={T2, T3},

REDO={}.

Журнал транзакций просматривается вперед, начиная с записи контрольной точки.

Если в журнале транзакций обнаруживается запись о начале транзакции, то эта транзакция добавляется в список UNDO. В нашем случае эти списки имеют вид: UNDO={T2, T3, T4}, REDO={}. Заметим, что следов транзакции Т5 в журнале нет.

Если в файле регистрации обнаруживается запись COMMIT об окончании транзакции, то эта транзакция добавляется в список REDO. В нашем случае будет: UNDO={T2, T3, T4}, REDO={T2, T4}. Заметим, что записи о конце этих транзакций имеются во внешней памяти журнала транзакций в соответствии с минимальным требованием выталкивания записей журнала при фиксации транзакции.

Когда будет достигнут конец журнала транзакций, оба списка анализируются. При этом из списка UNDO удаляются те транзакции, которые попали в список REDO. В нашем случае будет: UNDO={T3}, REDO={T2, T4}.

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

Окончательно, система просматривает журнал транзакций вперед, начиная с момента контрольной точки, и повторно выполняет все операции транзакций из списка REDO. В нашем случае, система выполнит повторно все операции транзакции Т4 и те операции транзакции Т2, которые были выполнены после принятия контрольной точки.

Восстановление после жесткого сбоя

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

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

164

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

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

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