Обработка с помощью транзакций
🕛 22.05.2009, 11:53
На основе транзакций строится безопасная работа, а также обеспечивается изолированность пользователей.Транзакцией является неделимая с точки зрения БД операция модификации. Транзакция включает набор действий. Результаты всех действий и операций, образующих этот набор, либо гарантированно фиксируются во внешней памяти, либо гарантированно в ней отсутствуют.
Т: а1, а2, …, аn; Commit (зафиксировать во внешней памяти); - транзакция закончена;
Т: а1, а2, …, аn; Rollback (все действия отменяются);
Рассмотрим следующие проблемы:
1. целостности данных в БД: транзакции появились в ответ на ограничения целостности.
СОТРУДНИКИ (СОТР_ИМЯ, СОТР_ОТД, …)
ОТДЕЛЫ (ОТД_№, ОТД_НАЧ, ОТД_ КОЛ, …)
При изменении числа сотрудников будет нарушаться условие целостности: число кортежей = значению атрибута. Чтобы не нарушать ограничение целостности надо ввести транзакцию: Т(добавление в СОТРУДНИКИ; модификация атрибута в ОТДЕЛЫ; COMMIT). Для поддержания ограничений целостности можно допустить нарушение их в ходе транзакций, но в конце транзакции Commit должен проверить все отложенные ограничения.
Ограничения целостности можно разделить на 2 группы:
А) откладываемые;
Б) неотложные (которые прямо препятствуют выполнению операций), связанные с типом и значением.
Проверку А) можно организовать проверкой только тех ограничений, которые касаются модифицированных данных.
2. изолированность пользователей необходимо в многопользовательских системах. Главная задача изолированности пользователей - создать у каждого пользователя иллюзию, что он работает с БД в одиночку. Изолированная работа означает, что пользователь не видит нарушения данных, связанных с работой других пользователей.
Уровни изолированности:
I. обеспечивает отсутствие потерянных изменений;
II. отсутствие чтения «грязных данных»;
III. отсутствие неповторяющихся чтение.
Рассмотрим I.
Т1 модифицирует объект А БД. После окончания Т1 - А’ (модифицированный). Если во время Т1 выполняется Т2, который тоже модифицирует объект, а по окончании Т2 Rollback (откат), то произойдёт восстановление А, т.е. потаря изменения Т1 (А -> А’).
Рассмотрим II.
Т1 изменяет объект А и параллельно с этим Т2 читает объект А. Т.к. Т1 ещё не завершена, то Т2 видит объект А в несогласованном («грязном») состоянии. Чтобы этого избежать, необходимо, чтобы до завершения модификации никакая транзакция на имела право читать объект.
Рассмотрим III.
Вторая операция чтения даёт неповторяющиеся данные, т.к. Т2 закончилась commit. Чтобы этого избежать: до завершения Т1 никакая другая транзакция не должна изменять объект А.
Итак, чтобы избежать I, необходимо запретить модификацию, если объект начал модифицироваться другими транзакциями - это минимальное требование для независимости параллельно выполняемых транзакций. Если рассмотреть III, то можно сказать, что условие запрещения модификаций является максимальным требованием. II является промежуточным.
Требование I-го уровня является достаточным для поддержания целостности в простых системах. Чем сложнее связи между данными, тем выше должны быть соблюдаемые условия.
При выполнении всех условий теряется выгода от параллельного использования транзакций. Поэтому запрещать целиком выполнение транзакций - это неэффективное решение.
Параллелизм выполнения транзакций описывается термином: сериализация транзакций.
Сериализация транзакций
Сериализация - параллельное выполнение транзакций, но не произвольных, а в виде набора - сериального плана.
Сериализация - выполнение транзакций в соответствие с сериальным планом. Сериальный план соответствует таким действиям, когда результат совместного выполнения транзакций соответствует результату строго последовательного их выполнения.
Как транзакции объединить в сериальный план?
Существуют ситуации, когда транзакции можно выполнить в любой последовательности вне зависимости от их результатов. Такими неконфликтующими являются только читающие транзакции или транзакции, не конфликтующие по объектам БД.
Виды конфликтов между транзакциями:
1. WW - транзакция пытается изменить объект, изменённый незакончившейся транзакцией;
2. WR - транзакция пытается читать объект, изменённый незакончившейся транзакцией;
3. RW - транзакция изменяет объект, прочитанный незакончившейся транзакцией.
Учёт конфликтов происходит двумя методами:
синхронизационных захватов;
временных меток.
Любые методы сериализации могут быть рассмотрены в двух вариантах:
1) оптимистическом;
2) пессимистическом.
В 1): предположение о том, что конфликтов возникает немного; все результаты изменения сохраняются в рабочей области транзакции, а проверять отсутствие конфликтов и применять все методы по сериализации нужно применять после завершения транзакций. В 2): конфликты возникают часто и методы сериализации, т.е. устранения, нужно применять немедленно при возникновении конфликта.
Синхронизационные захваты
Основой является захват транзакциями объектов БД. Захват состоит в том, что каким-то образом транзакция фиксирует намерение работа с объектом в каком-то режиме, а режим определяется видом операции. Существует два режима:
a) совместный S (Shared): требуется, когда транзакция собирается читать объект;
b) монопольный X (eXclusive): соответствует операциям занесения, удаления и модификации информации.
Если есть транзакция Т, объект БД r, то синхронизация над объектом может проходить либо в совместном режиме, либо в монопольном режиме.
При синхронизационных захватах транзакция должна предварительно захватить объект, а потом выполняться.
На сколько захваты разными транзакциями одного объекта совместимы друг с другом?
Таблица совместимости захватов в разных режимах: Т1
T2 S X - Да Да S Да Нет X Нет Нет
В соответствие с таблицей, если какой-то объект уже закончен, то последующие захваты проверяются по таблице и либо разрешаются, либо запрещаются, т.е. транзакция блокируется, т.к. не может осуществить захват требуемого объекта в требуемом режиме. «Нет» соответствует конфликтам WW, WR, RW.
Чтобы это реализовать используется двухфазный протокол синхронизационных захватов (2PL). В соответствие с ним выполнение транзакции разбивается на 2 фазы:
I. накопление захватов;
II. фиксация/откат и освобождение захватов.
При этом важно отметить уровень захвата объектов, т.е. что следует считать объектом захвата. Выделяют несколько логических уровней:
- БД;
- Файл; - Отношение; |- страница;
- Кортеж;
- Атрибут;
Что из них захватывать?
Чем выше уровень захвата, тем меньше возможность организовать параллельную работу. Но чем меньше уровень, тем сложнее обнаруживать конфликты. Наиболее распространённым решением этой проблемы является захват на уровне кортежей или на уровне страниц. Но такие захваты позволяют проникнуть нарушениям целостности. Методом борьбы с этими нарушениями являются гранулированные синхронизационные захваты.
Гранулированные синхронизационные захваты
Гранулированный захват - это выделение групп объектов; если какая-то транзакция намеревается захватить объект. Она предварительно должна захватить объект более высокого уровня.
Введём несколько дополнительных режимов захватов:
IS (Intented for Shared Lode) - захватить в совместном режиме; смысл: если транзакция хочет читать кортежи из отношения, то предварительно это отношение должно быть захвачено в режиме IS;
IX (Intented for eXclusive Lode): если транзакция собирается удалять кортежи икортеж должен быть захвачен в режиме Х, то и всё отношение должно быть захвачено в режиме IX;
SIX (Shared Intented for eXclusive): составной объект захватывается совместно и в последствие его составляющие будут захвачены в монопольном режиме. Например, выполняется длинная операция просмотра отношения с возможностью удаления некоторых кортежей, то надо захватить это отношение в режиме SIX, а до этого захватить файл в режиме IS.
Таблица совместимости: Т1
Т2 X S IX IS SIX - Да Да Да Да Да X Нет Нет Нет Нет Нет S Нет Да Нет Да Нет IX Нет Нет Да Да Нет IS Нет Да Да Да Да SIX Нет Нет Нет Да Да
Метод синхронизационных захватов не ликвидирует проблемы взаимных блокировок и главной проблемой для СУБД является поиск заблокированных транзакций, а для этого СУБД должна строить графы, где вершинами будут транзакции и объекты, и выявлять кольцевые пути.
Временные метки
Этот метод не требует построения графов, основан на присвоении каждой транзакции некоторой временной метки.
Идея метода заключается в том, что если Т1 началась раньше Т2, то СУБД обеспечивает такой режим выполнения, как если бы Т1 целиком закончилась до начала выполнения Т2. Т.е. с каждой транзакцией надо связать метку её начала.
Если транзакция Т выполняется над объектом R, то Т свою метку начала помещает на этот объект R, кроме метки она добавляет тип операции. Если Т1 собирается также работать с R, то она проверяет не закончилась ли Т, которая пометила этот объект; если закончилась, то Т1 метит объект своей меткой и продолжает выполняться, если Т ещё не закончилась, то Т1 проверяет конфликтность операций. Если операции неконфликтны, то на объекте остаётся метка с меньшим значением и Т1 выполняет свои неконфликтные операции. Если по операциям конфликт, тогда сравниваются метки транзакций и для более молодой транзакции (значение которой больше) производится откат, а более старая транзакция продолжает работать.
Недостатки: необходимость выполнять откаты, которые происходят очень часто.
Журнализация и откаты
Журнализация - средство восстановления данных при сбоях. Журнализация - ведение специальной структуры, в которую записываются все изменения, происходящие в БД.
Модно выделить 3 случая, когда восстановление данных необходимо:
- индивидуальный откат транзакций;
- мягкий сбой (программный сбой, перебой в питании);
- жёсткий сбой (утрата внешнего носителя).
Основой такого восстановления является хранение избыточной информации - журнальной информации. Т.к. обработка данных связана с буферизацией, то и журнализация связана с ней, следовательно, возникают проблемы: если изменения проведены только в буфере, то такие изменения в журнале не фиксируются, а в журнал вносятся изменения только когда буфер выталкивается во внешнюю память. Если такая стратегия не подходит, то поддерживается 2 буфера: буфер журнала и буфер страниц.
Изменения в журнал вносить необходимо согласованным образом - алгоритм WAL (Write Ahead Log), т.е. запись первоначально в журнал. Это предполагает простой способ: если транзакция завершается успешно, то выталкивание буфера журнала и выталкивание из буфера данных тех страниц, которые были изменены данной транзакции.
Индивидуальный откат транзакций
Выполняется следующим образом: чтобы по журналу выполнить откат транзакции, все записи, касающиеся изменений, вносимых данной транзакцией, связываются в специальный обратный список:
Начало списка: для незакончившейся транзакции - это запись о последнем изменении, которое выполнено; для закончившейся транзакции - это запись о конце транзакции, которая обязательно вытолкнута во внешнюю память.
Конец списка: запись о первом изменении.
Алгоритм отката:
- выборка очередной записи;
- выполнение обратных действий (INSERTDELETE);
- любая из выполненных операций журнализируется (это надо, если во время отката произойдёт мягкий сбой и нужно повторить процедуру);
- когда достигается конец списка, вносится запись о завершении отката.
Восстановление при мягком сбое
Основная проблема состоит в том, что при этом может быть потеряна согласованность данных. Согласованность данных выражается в следующем: страницы связаны с данными и страницы связаны с индексами. Если изменили данные и не изменили индексы, а при этом произошёл мягкий сбой, то при восстановлении БД будет не согласована (новые данные и старые индексы).
Для корректного выполнения логических операций необходимо, чтобы во внешней памяти всегда был набор физически согласованных страниц. Набор физических страниц должен описывать объект БД либо после изменения, либо до изменения. Чтобы отмечать состояние согласованности БД вводится понятие 'точка физической согласованности'. Эти точки отмечают моменты времени, когда во внешней памяти отмечаются согласованные результаты изменений.
В случае мягкого сбоя должно происходить восстановление ОП. ОП восстанавливается то точкам согласованности из внешней памяти. Восстановление транзакций:
Т1 - ничего;
Т2 - повторно выполнить те операции, которые должны быть выполнены после точки согласованности (redo);
Т3 - корректно выполнить операцию отката (undo) и, если необходимо, то произвести повторные действия с этой транзакции;
Т4 - выполнить полную повторную прямую интерпретацию (redo);
Т5 - ничего.
Для фиксации точек согласованности существует 2 подхода:
1. теневой механизм;
2. журнализация/учёт постраничных изменений БД.
Теневой механизм
При открытии файла с БД создаётся таблица отображения (ТО) номеров логических блоков в физические блоки внешней памяти. При модификации любого логического блока во внешней памяти выделяется новый блок, в котором эти изменения отражаются. И эти изменения фиксируются в текущей ТО во внешней памяти. Во внешней памяти поддерживается копия ТО - это теневая таблица. Теневая таблица остаётся неизменной до тех пор, пока не будет закрыт соответствующий файл. РИС.*.
Использование теневого механизма: периодически выполняется операция, которая устанавливает физическую согласованность. Установка физической согласованности - check point. Смысл этой операции состоит в том, что все логические операции над БД завершаются, все буферы выталкиваются во внешнюю память, текущая ТО заменяет собой теневую таблицу. Здесь восстановление происходит мгновенно: текущая ТО восстанавливается по теневой.
Проблема: перерасход внешней памяти: восстанавливается вся ВЗУ, когда достаточно всего-навсего восстановить согласованный набор внешних страниц.
Журнализация постраничных изменений
При восстановлении после мягкого сбоя вначале выполняется постраничный откат незавершённых логических операций, т.е. всё сводится к уровню страниц.
С каждой страницей данных связывается метка о сделанных изменениях.
Если страница не получила изменений, то это не сохраняется; если есть изменения, то надо записать эту страницу в ВЗУ.
Вводят 2 журнала:
- глобальный журнал транзакций;
- локальный журнал страничных изменений, связанный с данной транзакцией.