Тема 2 Транзакции и блокировки.
Цель: Изучить понятие транзакции и блокировки. Познакомится с различными
видами управления.
Вопросы лекции:
1.
Понятие транзакции и блокировки
2.
Управление транзакциями.
3.
Управление блокировками, уровни блокировки, уровни
изоляции
4.
Управление блокировками в запросе.
5.
Журнал транзакции.
1. При
одновременном обращении множества пользователей к одной базе данных нередко возникают ситуации, когда несколько пользователей
пытаются работать с одними и теми же данными. Сама простая и безболезненная
ситуация - это когда несколько пользователей пытаются одновременно прочитать одни и те же данные. Проблемы
начинаются, когда пользователи начинают изменять или удалять данные.
Если это пытаются проделать одновременно несколько пользователей, то возникает конфликт. Кроме того, если один из пользователей
изменяет данные, а другой пытается их прочитать, то второй пользователь
может получить неверные значения. А если операция изменения данных оказалась неуспешной или изменение вообще неверно, то
целостность и достоверность данных в таблице могут быть нарушены.
Транзакция представляет собой последовательный набор
команд Transact-SQL (одна или
несколько команд), образующих логически
завершенный блок, который выполняется как единое целое. В транзакцию может быть включено как несколько
команд (или даже одна команда), так и несколько тысяч команд. Независимо от
количества команд в транзакции либо все они будут выполнены, либо ни одна из них не выполнится. Если хотя бы одна из команд
транзакции не выполнена, происходит откат транзакции. При откате транзакции система восстанавливается в состоянии,
в котором она была до начала
транзакции. Информация о первоначальном состоянии системы хранится в журнале транзакций.
Большинство действий, выполняемых пользователями в SQL Server
7.0, производятся в теле транзакций. По
умолчанию каждая команда выполняется как самостоятельная транзакция. При необходимости
пользователь может явно указать начало и конец транзакции, чтобы иметь
возможность включить в нее несколько
команд.
Набор команд, включенный в
транзакцию, должен удовлетворять следующим четырем требованиям:
Atomicity - атомарность. Блок команд, включенных в транзакцию,
выполняется или не выполняется только целиком.
Consistency - согласованность (или постоянство). Все данные после
выполнения транзакции должны находиться в
согласованном состоянии, то есть все правила и ограничения целостности должны
быть соблюдены. Все внешние структуры данных (например, индексы) после
окончания транзакции также должны находиться в корректном состоянии.
Isolation - изолированность. Изменения данных, выполняемые
одной транзакцией, не должны зависеть от изменений, выполняемых другой
транзакцией, то есть изменения данных различными транзакциями должны быть изолированными. В противном случае возможны
«мертвые блокировки», в результате
чего работа обеих транзакций будет блокирована. Транзакция видит данные либо в состоянии, которое было до начала
работы другой транзакции, либо в состоянии после того, как работа второй
транзакции была завершена. Одна транзакция не может просмотреть промежуточное состояние данных, изменяемых другой
транзакцией. Если транзакция читает несколько раз одни и те же данные,
то она должна видеть их каждый раз в том состоянии, в котором они были при первом обращении.
Durability - устойчивость (или долговечность). После того как
транзакция завершена, она сохраняется в
системе и ничто не может вернуть систему в состояние, в котором она была до
начала транзакции. Это утверждение верно и в случае неожиданного
останова или краха системы.
Начиная выполнение изменения данных, SQL Server
накладывает на данные в таблице блокировку таким образом, что ни одна другая
транзакция не сможет их прочитать или изменить. Только после того, как
транзакция будет завершена или отменена, другая транзакция сможет получить
доступ к данным. После завершения транзакции SQL Server
гарантирует, что изменения данных будут зафиксированы, даже если сразу же после завершения транзакции произойдет
сбой компьютера, операционной системы или самого SQL Server.
При следующем старте сервер выполнит восстановление изменений данных, используя
журнал транзакций.
Программист должен решить, какие
команды должны выполняться как одна транзакция, а какие могут быть разбиты на несколько последовательно
выполняемых транзакций. В первом случае (при выполнении множества команд в
одной транзакции) на данные накладывается блокировка. Некоторые режимы блокирования запрещают обращение и
изменение данных до тех пор, пока вся транзакция не будет завершена. Таким образом, другие пользователи
не смогут обратиться к данным, с которыми работает транзакция, до тех пор, пока эта транзакция не будет завершена.
Если к базе данных одновременно обращаются множество пользователей, использующих
некорректно написанную хранимую
процедуру, возможны длительные простои в ожидании выполнения начатых
транзакций. В этом случае необходимо написать хранимую процедуру таким образом,
чтобы она по возможности выполняла
изменение данных не как единую большую транзакцию, а как несколько более
мелких, быстрее выполняемых и
блокирующих меньше данных. В этом случае множество пользователей одновременно
смогут успешно работать с одной и той же хранимой процедурой.
Блокировкой называется временно
накладываемое ограничение на выполнение некоторых операций обработки данных. Блокировка может быть
наложена как на отдельную строку таблицы, так и на всю базу данных. Управлением
блокировками занимается менеджер блокировок (Lock Manager),
контролирующий их наложение и разрешение конфликтов. Транзакции и блокировки
тесно связаны друг с другом. Транзакции
накладывают блокировки на данные, чтобы обеспечить изолированность изменений. Без использования блокировок несколько
транзакций могли бы изменять одни и те же данные. SQL Server
7.0 автоматически блокирует необходимые данные и при необходимости может
расширить зону охвата для повышения производительности.
Если в системе управления базами данных не реализованы
механизмы блокирования, то при одновременном
чтении и изменении одних и тех же данных несколькими пользователями возникает четыре проблемы одновременного доступа: проблема
последнего изменения -• когда несколько пользователей изменяют одну и ту же
строку, основываясь на ее начальном
значении, то часть данных будет потеряна, так как каждая последующая транзакция перезапишет изменения,
сделанные предыдущей транзакцией. Проблема «грязного» чтения -
предположим, что пользователь выполняет сложные операции обработки данных,
требующие множественного изменения данных перед тем, как данные будут находиться в логически верном состоянии. Если во
время изменения данных другой пользователь будет считывать данные, то может оказаться, что он получит логически
неверную информацию. Для избежания
подобных проблем лучшим выходом было бы дождаться окончания изменения всех данных, а уже потом считывать их.
Проблема неповторяемого чтения - эта проблема
возникает, когда пользователь считывает одни и те же данные несколько раз.
Другой пользователь может в это время внести изменения, так что при повторном
чтении первый пользователь получит уже другой набор данных. Если между первым и
вторым обращением к таблице используемые строки были изменены другими
пользователями, то результаты вычислений станут неактуальными и изменение строк
на их основе может привести к нарушению
целостности или логической согласованности данных.
Проблема фантомов - эта проблема возникает, когда
транзакция выбирает данные из таблицы, а другая
транзакция вставляет новые строки до завершения первой транзакции. Если первая транзакция выполняет сложные многошаговые
изменения данных, это может вызвать серьезные проблемы. Полученные на первом этапе значения будут некорректными, и их
дальнейшее использование может
привести к непредсказуемым результатам.
Для решения перечисленных проблем разработан стандарт ANSI, определяющий четыре уровня блокирования. Каждый последующий уровень поддерживает требования
предыдущего уровня и налагает дополнительные ограничения:
уровень 1 - запрещение «загрязнения» данных. Этот уровень
требует, чтобы изменять данные могла только одна транзакция. Если другая транзакция
пытается изменить эти же данные, то она должна ожидать завершения первой транзакции
уровень 2 - запрещение «грязного» чтения. Если транзакция
начала изменение данных, то никакая другая
транзакция не сможет прочитать эти данные до тех пор, пока первая транзакция не
завершится
уровень 3 - запрещение неповторяемого чтения. Если транзакция
считывает данные, то никакая другая транзакция не сможет их изменить. Таким образом,
при повторном чтении данных они будут находиться
в первоначальном состоянии
уровень 4 - запрещение фантомов. Если транзакция обращается к
данным, то никакая другая транзакция не
сможет добавить новые или удалить имеющиеся строки, которые могут быть считаны при
выполнении транзакции
2. SQL Server
поддерживает три вида определения транзакций: явное, автоматическое и
подразумеваемое. Кроме того, помимо
транзакций, выполняемых в одной базе данных, существуют распределенные
транзакции, с помощью которых в одной транзакции можно обращаться к нескольким
базам данных, расположенных на разных серверах.
Явные транзакции
Явные транзакции требуют, чтобы
пользователь явно указал начало и конец транзакции, используя команды Transact-SQL. Для управления явными транзакциями используются
следующие команды:
ü
начало транзакции; в журнале транзакции фиксируются первоначальные
значения изменяемых данных и указывается,
что транзакция начата
BEGIN TRANSACTION]
[transaction_name | @tran_name_variable]
Где
Transaction_name -
используется для указания имени транзакции, обычно используется только
для вложенных транзакций
@tran_name_variable -
задает имя переменной, в которой хранится имя транзакции.
Использование переменной
для указания
имени транзакции позволяет
нескольким
пользователям создавать множество транзакций,
используя один и тот же код
ü
конец транзакции. Если в теле транзакции не было ошибок, то эта команда
предписывает серверу зафиксировать
все изменения, сделанные в транзакции, после чего в журнале транзакции помечается, что изменения
зафиксированы и транзакция завершена:
COMMIT [WORK]
COMMIT
[TRANSACTION] [translation_name | @ tran_name_variable] ]
ü
откат транзакции.
Используется, когда пользователю необходимо прервать транзакцию, например, при выполнении определенного логического условия.
Когда сервер встречает эту команду, происходит откат транзакции,
восстанавливается первоначальное состояние системы и в журнале транзакции
отмечается, что транзакция отменена.
ROLLBACK [WORK]
ROLLBACK
[TRANSACTION] [transaction_name | @ tran_name_variable |
@ savepointname | @
savepointvariable]] где
savepointname - указывает имя контрольной точки транзакции, созданной командой SAVE TRANSACTION. Откат
транзакции до контрольной точки позволяет отменить только часть транзакции
(изменения, сделанные после контрольной точки).
@ savepointvariable
- используется для указания имени контрольной точки транзакции через
переменную.
Автоматические транзакции.
По умолчанию SQL Server 7.0 работает в режиме
автоматического начала транзакций. В этом режиме каждая команда рассматривается как отдельная транзакция. Пользователю не
нужно явно указывать начало и конец транзакции, так как это за него
делает SQL Server.
Если команда выполнена успешно, то сделанные
ею изменения фиксируются. Если же при выполнении команды произошла ошибка, то сделанные
изменения отменяются и система возвращается в первоначальное состояние.
Если пользователю необходимо
создать транзакцию, включающую несколько команд, то он должен явно указать транзакцию.
При этом используются те же команды, что были описаны в предыдущем разделе.
Вообще сервер работает только в
одном из двух режимов определения транзакции: автоматическом или подразумевающимся. Сервер не
может находиться в режиме исключительно явного определения транзакций. Этот режим работает поверх двух других.
Для установки режима
автоматического определения транзакций используется следующая команда Transact-SQL:
SET IMPLICITJTRANSACTION OFF
Неявные транзакции.
При работе в режиме неявного (или подразумеваемого)
начала транзакции SQL Server автоматически начинает
новую транзакцию, как только завершена предыдущая. Пользователь ничего не должен делать, чтобы указать начало транзакции.
Транзакция продолжается до тех пор, пока пользователь явно не укажет
команду отката (ROLLBACK TRANSACTION) или конца (COMMIT TRANSACTION) транзакции, после чего сервер автоматически начинает
новую транзакцию. В итоге генерируется непрерывная цепь транзакций.
После того как для соединения
установлен режим подразумевающегося начала транзакции, сервер автоматически заканчивает
текущую транзакцию и начинает новую, если встречается одна из следующих команд:
ALTER TABLE - изменение структуры таблицы
CREATE - создание
объекта базы данных
DELETE -
удаление строк данных из таблицы
DROP -
удаление объектов базы данных
FETCH -
извлечение указанной колонки из курсора
GRANT -
разрешение доступа к объектам базы данных
INSERT -
добавление строк в таблицу
OPEN - открытие
курсора
REVOKE -
неявное отклонение доступа к объектам базы данных
SELECT - выборка
данных из таблиц
TRUNCATE TABLE - усечение таблицы
UPDATE -
изменение данных в таблице
Для установки режима подразумевающегося
определения транзакций используется следующая команда Transact-SQL:
SET IMPLICIT TRANSACTION ON
3. Всю работу по установке,
снятию и разрешению конфликтов выполняет специальный компонент сервера,
называемый менеджером блокировок (Lock Manager).
Однако при необходимости в запросе можно явно указывать, какой тип блокировки
необходимо использовать в том или ином случае.
Рассмотрим алгоритм наложения
блокировок. Перед тем как транзакция сможет выполнить изменение данных, она запрашивает
менеджер транзакций о возможности установки соответствующей блокировки. Менеджер блокировок
просматривает свои таблицы и на основе содержащихся в них данных принимает решение об
удовлетворении или отклонении требования на установку блокировки. Если требуемый ресурс в настоящее
время используется другим процессом, то менеджер блокировок либо отклоняет запрос на
блокировку, либо ставит его в очередь и выполняет его после того, как текущий процесс завершит работу и
разблокирует ресурс. Если ресурс на момент запроса свободен, менеджер
блокировок удовлетворяет запрос и устанавливает блокировку. После того как
блокировка установлена, транзакция может выполнять обработку данных.
Время ожидания разблокирования
ресурса можно свободно регулировать командой:
SET LOCKJTIMEOUT timeout_period
Где в качестве параметра задается количество
миллисекунд, в течение которых транзакция будет ждать разблокирования ресурса. По истечении указанного времени будет
сгенерировано сообщение об ошибке. Бесконечное ожидание моделируется
значением -1.
Уровни блокировок.
SQL Server 7.0 поддерживает различные уровни блокирования
объектов, начиная с отдельной строки и заканчивая
базой данных в целом. Менеджер блокировок автоматически оценивает, какое
количество данных необходимо блокировать, и устанавливает соответствующий тип
блокировки. Это позволяет поддерживать равновесие между производительностью
работы системы блокирования и возможностью множества пользователей получать доступ к данным. Блокирование на уровне
строки позволяет наиболее точно управлять
доступом пользователей к данным, так как блокируются только те строки, которые
действительно изменяются. Множество пользователей могут одновременно работать с
данными, испытывая при этом минимальные
задержки. При использовании блокировки на уровне таблицы производительность системы блокирования резко
увеличивается, так как необходимо установить лишь одну блокировку и снять ее
только после завершения транзакции.
Пользователь при этом имеет максимальную
скорость доступа к данным. В то же время остальные пользователи не смогут получать доступ к данным, так как
вся таблица заблокирована. Им приходится ждать, пока текущий пользователь не
закончит работу.
В SQL Server поддерживаются следующие уровни
блокирования данных:
·
RID –блокировка на уровне строки таблицы; используется
при вставке в таблицу новых строк
·
KEY- блокировка на уровне индекса. Блокируется часть
индекса, соответствующая изменяемым в
транзакции данным.
·
Page- блокировка на уровне страницы.
·
Extent- блокировка на уровне экстента
·
Table- блокировка на уровне таблицы.
·
DB-блокировка на уровне базы данных
SQL
Server может
динамически управлять уровнем блокирования, устанавливаемым для конкретной
транзакции, при необходимости уменьшая уровень детализации.
Уровень изоляции.
Уровень изоляции определяет
степень независимости транзакции друг от друга. Наивысшим уровнем изоляции
является сериализуемость, обеспечивающая полную независимость транзакции друг
от друга. Тем не менее, полная изоляция транзакций требуется не всегда. Например.
При чтении несколькими транзакциями одних и тех же данных достаточно запретить
всем транзакциям изменять эти данные, а не блокировать их полностью.
Уровни изоляции соответствуют
уровням стандарта ANSI, и решают 4 проблемы одновременного доступа.
ü
READ Unicomitted –незавершенное чтение. Низший
уровень, соответствующий уровню 0 стандарта ANSI . Этот уровень гарантирует только
физическую целостность данных, т.е. если несколько пользователей одновременно
изменяют одну и ту же строку, то после всех изменений строка будет иметь
определенное значение. По сути, для транзакций не устанавливается никакая
блокировка, что гарантировало бы целостность данных Для установки этого уровня
используется следующая команда:
SET
TRANSACTION ISOLATION LEVEL READ UNICOMITTED
ü
RED COMITTED – завершенное чтение. Этот
уровень изоляции гарантирует, что не возникнет проблемы «грязного» чтения. Для
этого сервер использует коллективные блокировки. Тем не менее, в процессе
работы одной транзакции другая транзакция может быть успешно завершена и
сделанные ею изменения будут зафиксированы. В итоге первая транзакция будет
работать с другим набором данных. Это так называемая проблема неповторяемого
чтения. Этот уровень изоляции используется SQL Server по умолчанию . Для установки
данного уровня используется следующая команда:
SET
TRANSACTION ISOLATION LEVEL READ COMITTED
ü
REPEATABLE READ – повторяющее чтение. Помимо
решения проблемы «грязного чтения», решается проблема неповторяемого чтения.
Для этого используется монопольная блокировка. Тем не менее, на этом уровне
изоляции возможно возникновение фантомов. Хотя этот уровень изоляции
обеспечивает большую целостность данных, его использование не всегда оправдано,
так как снижается степень параллелизма. Для установки используется команда:
SET
TRANSACTION ISOLATION LEVEL REPEATABLE
READ
ü
SERIALIZABLE- сериализуемость. Этот уровень
изоляции является максимальным и обеспечивает полную изоляцию транзакции друг
от друга. Проблема возникновения фантомов решается использованием блокировки
диапазона ключа. Как и при установке предыдущего уровня, следует внимательно
оценить необходимость установки этого уровня, исходя из допустимого снижения
уровня параллелизма. Команда
SET
TRANSACTION ISOLATION LEVEL SERIALIZABLE
Помимо установки уровня изоляции
на уровне соединения с помощью команды SET
TRANSACTION ISOLATION LEVEL при выполнение этого запроса можно использовать специальные ключевые
слова для указания в этом запросе соответствующего уровня изоляции.
Основные типы блокировки
Действия, выполняемые пользователями при работе с
данными, сводятся к операциям двух типов: чтения " изменения. В операции
изменения включаются действия по добавлению, удалению и собственно изменению данных. В зависимости от выполняемых
действий сервер накладывает определенный тип блокировки. В SQL Server 7.0 поддерживаются следующие четыре основных вида
блокировок:
ü
Коллективные
блокировки - этот тип блокировок накладывается при выполнении операций чтения
данных, таких например, как SELECT.
Коллективную блокировку на одни и те же данные могут одновременно устанавливать несколько пользователей, за что она и
получила свое название. Если сервер
установил на ресурс коллективную блокировку, то пользователь может быть уверен,
что никакой другой пользователь не сможет изменить данные.
ü
Блокировки
обновления. Когда транзакция пытается изменить данные, то для избежания
появления «мертвых» блокировок сервер
сначала устанавливает блокировку обновления. Блокировку обновления можно
рассматривать как переходный этап от коллективной блокировки к монопольной блокировке. Если на ресурс была установлена
коллективная блокировка и для этого ресурса устанавливается блокировка
обновления, то никакая транзакция не сможет наложить коллективную блокировку на
блокировку обновления. После того как все блокировки, установленные другими транзакциями, сняты, блокировка обновления
заменяется на монопольную блокировку. Если транзакция не изменяет данные, то блокировка обновления заменяется на
коллективную блокировку.
ü
Монопольная блокировка. Этот тип блокировок используется, когда
транзакция изменяет данные. Когда
менеджер блокировок устанавливает монопольную блокировку на ресурс, то никакая
другая транзакция не может прочитать или
изменить заблокированные данные. Монопольная блокировка несовместима ни
с какими другими блокировками и ни одна блокировка, включая монопольную, не может быть наложена на ресурс.
ü
Блокировка массированного обновления. Блокировки этого типа
накладываются сервером при выполнении
операций массированного копирования в таблицу. Блокировка массивного обновления
запрещает обращение к таблице любым
процессам, не выполняющим массивное копирование. В то же время, несколько процессов, выполняющих
массивное копирование, могут одновременно вставлять строки в таблицу.
«Мертвые» блокировки.
«Мертвые», или тупиковые,
блокировки характерны для многопользовательских систем. «Мертвая» блокировка возникает, когда две транзакции
блокируют два блока данных и для завершения работы каждой из транзакций
необходим доступ к данным, заблокированным ранее другой транзакцией. Для завершения каждой из транзакций необходимо
дождаться, пока часть данных, блокированная другой транзакцией, будет разблокирована. Но это
невозможно, так как вторая транзакция ожидает разблокирования ресурсов,
используемых первой транзакцией.
Для решения возникшего конфликта
сервер периодически сканирует журнал блокировок и устанавливает специальный
флаг для каждой активной блокировки. Если при сканировании сервер обнаруживает блокировку с уже установленным флагом,
это значит, что данная блокировка существует уже
продолжительное время и для нее запускается механизм обнаружения «мертвых»
блокировок. Сервер анализирует
цепочку зависимостей блокировок, и если при этом обнаруживается, что в системе существует «мертвая» блокировка, то
предпринимаются соответствующие действия для ее уничтожения. При выборе блокировки, которой необходимо
пожертвовать, сервер исходит из соображений минимальной стоимости.
4. По
умолчанию при выполнении запроса используется уровень изоляции, установленной командой SET TRANSACTION ISOLATION LEVEL. Если в запросе необходимо использовать отличный от установленного по умолчанию уровень изоляции,
то в коде запроса можно использовать специальные ключевые слова,
используемые оптимизатором запросов.
Специальные ключевые слова, или хинты (hints), можно использовать не только для команды SELECT, но и в командах DELETE, UPDATE и INSERT.
HOLDLOCK - менеджер блокировок удерживает коллективную
блокировку до конца транзакции. В обычной ситуации при выполнении транзакции
блокировка устанавливается только на время чтения ресурса и затем сразу же
снимается. За время транзакции может быть последовательно блокировано множество
различных ресурсов - строк, страниц, таблиц. Указание ключевого слова HOLDLOCK устанавливает для транзакции минимальный уровень изоляции
- SERIALIZABLE. Никакая внешняя транзакция не сможет изменить
данные, к которым было произведено обращение в теле транзакции
NOLOCK - использование этого параметра разрешает «грязное»
чтение. При этом в транзакции устанавливается низший (нулевой) уровень изоляции
- RAD
UNCOMITTED. Данные, изменяемые транзакцией, могут быть прочитаны другими
транзакциями до того, как они будут стабилизированы.
PAGLOCK. При указании этого ключевого слова менеджер
блокировок будет использовать блокировки на
уровне страницы в тех случаях, где обычно используется блокировка на уровне таблицы.
READCOMITTED. При использовании этого параметра менеджер
блокировок устанавливает первый уровень изоляции - READ COMITTED. Данный уровень используется сервером по умолчанию.
На этом уровне изоляции запрещено «грязное»
чтение, но не решена проблема неповторяющегося чтения.
5. Большинство
современных систем управления реляционными базами данных для обеспечения целостности данных использует
журнал транзакций. Это гарантирует, что базы данных не будут содержать промежуточных или
неопределенных значений. Журнал транзакций используется для выполнения всех промежуточных
модификаций, и только после того, как транзакция завершится и целостность
данных будет проверена, происходит фиксация изменений в самой базе данных. Для
этого используется буферный кэш, в который считываются требуемые транзакцией
страницы. Все изменения выполняются
транзакцией в буферном кэше, а не на диске. Это позволяет выполнять откат
транзакций в случае ошибке или принудительного
завершения транзакции. После завершения транзакции все измененные
страницы сбрасываются на диск - таким образом происходит фиксация транзакции.
Если транзакция завершена, но страница не
записана на диск, то такая страница называется «грязной» страницей. Если в этот момент произойдет
неожиданный останов или крах сервера, то транзакция останется незафиксированной, хотя она и была
завершена. С целью фиксации таких транзакций сервер при каждом старте
просматривает журнал транзакций для поиска несоответствий между базой данных и
журналом. При нахождении незафиксированных транзакций происходит их
автоматическая фиксация.
Если в результате сбоя сама база
данных была потеряна, но журнал транзакций остался неповрежденным, то можно
восстановить практически все данные. Для этого необходимо сначала восстановить
базу данных из резервной копии, а затем применить журнал транзакций. В
результате все изменения, внесенные после
выполнения последнего резервного копирования, будут восстановлены.
Логическая
архитектура журнала транзакций.
Журнал транзакций имеет простую
структуру, представляющую собой последовательность записей. Каждая запись содержит
информацию о транзакции, например данные о начале транзакции, производимых с помощью команд UPDATE, DELETE и INSERT изменениях, конце транзакции, создании индекса или
таблицы, выделении и изъятии экстента.
Каждая запись в журнале маркируется порядковым номером
(Log
Sequence Number - LSN) и ID транзакции, которой она принадлежит. Записи, принадлежащие одной
транзакции, связываются в цепь для
ускорения повторного прогона транзакции. Каждая запись транзакции имеет ссылку
на LSN следующей записи этой же транзакции. LSN последовательно увеличивается каждый раз, когда в журнале
транзакций создается новая запись.
Хотя для пользователя журнал
транзакций выглядит как постоянно увеличивающаяся последовательность записей, в
результате чего создается иллюзия, что все записи сохраняются в конце журнала
транзакций, на самом деле записи записываются по кругу. Неактивные записи
завершенных транзакций постепенно заменяются данными активных транзакций.
Процесс освобождения неактивных
виртуальных журналов называется урезанием журнала транзакций. Если не выполнять
урезание журнала транзакций, то со временем свободное место кончится и необходимо будет увеличивать
размер файлов журнала транзакции. После того как все свободное место на диске закончится, работа
с базой данных станет невозможна, так как ни одна транзакция не сможет быть выполнена.
Для уменьшения количества
транзакций, которое необходимо будет фиксировать при восстановлении базы данных, SQL Server 7.0 выполняет процесс, называемый контрольной точки.
При выполнении контрольной точки сервер
сбрасывает из буферного кеша на диск все «грязные» страницы, тем самым
принудительно фиксируя транзакции. Процесс контрольной точки выполняется в
следующей последовательности:
o
сервер записывает на диск все страницы, помеченные как «грязные», то
есть страницы, которые были изменены со времени выполнения последней контрольной точки;
o
в журнале транзакций записывается факт фиксации сделок;
o
записываются на
диск все «грязные» страницы журнала транзакций, обеспечивая целостность самого
журнала транзакций;
o
в журнале транзакций сохраняется информация обо всех «грязных» страницах,
не записанных на диск;
o
сохраняется
последовательный номер записи (LSN), с которой
будет начат процесс восстановления базы данных. Этот номер называется
минимальным номером и обозначается как MinLSN. MinLSN -это номер первой записи, принадлежащей самой
старой транзакции;
o
сохраняется
информация о выполнении процесса контрольной точки. Журнал транзакций хранит
информацию обо всех контрольных точках, выполняемых в базе данных. Эти записи
связываются в цепочку. Номер первой записи этой цепочки хранится в загрузочной
странице (boot page) самой базы данных;
o
если в базе
данных установлена опция trunc.log on chkpt, происходит удаление всей информации о
зафиксированных транзакциях (это и есть урезание журнала транзакций), то есть
освобождение виртуальных журналов . Если опция trunc.log on chkpt не
установлена, то информация о выполненных
транзакциях сохраняется и виртуальные журналы не освобождаются.
Параметр trunc.log on chkpt устанавливается для каждой базы данных индивидуально
с помощью хранимой процедуры sp_dboption:
EXEC sp_dboption
'pubs', 'trunc. log on chkpt', off
Литература:
1 Е. Мамаев
«Microsoft SQL Server 2000», БХВ-Петербург,
2004г.
Контрольные вопросы:
1 Что такое транзакция и блокировка?
2 Опишите уровни блокировок.
3 Опишите логическую
архитектуру журнала транзакции.
4 Что такое «мертвые»
блокировки?