Базы Данных - Сибилев, 2007
.pdf71
4.8.3 Аутентификация.
С каждым идентификатором связывается пароль, выбираемый поль-
зователем и известный только ему и системе. Пароль сохраняется в за-
шифрованном виде в защищённой части системного каталога и недоступен для просмотра никакому пользователю, в том числе и владельцу. Пароль используется при подключении пользователя к системе для аутентифика-
ции, т.е., для проверки того, является ли пытающийся подключиться тем,
за кого он себя выдаёт.
Существуют и другие способы аутентификации, однако парольный является наиболее распространённым, хотя и не даёт абсолютной гарантии аутентификации. Для того чтобы уменьшить вероятность раскрытия паро-
ля, обычно вводят ограничения на его минимальную длину, на состав сим-
волов, обязывают пользователей периодически изменять пароли, запре-
щают использовать в качестве паролей собственные имена и применяют другие административные ограничения.
4.8.4 Привилегии доступа
С каждым идентификатором авторизации связывается набор приви-
легий. Выделяют системные и объектные привилегии.
Системная привилегия это право создания и модификации объектов БД – схем, таблиц, приложений, правил и т.п. Пользователь, создавший объект, является его владельцем. Он имеет право использовать его в любых операциях.
Объектная привилегия это право использования объекта в операциях определённого типа. Например, право просмотра конкретной таблицы или её отдельных столбцов, или некоторого подмножества её строк, право вставки строк в конкретную таблицу, право запуска приложения и т.п. Го-
воря обобщённо, объектная привилегия есть тройка (идентификатор авторизации, объект БД, действие).
72
По умолчанию все системные и объектные привилегии принадлежат Администратору БД. Он может предоставлять отдельные привилегии дру-
гим пользователям.
Сведения о привилегиях сохраняются в системном каталоге в виде
матрицы управления доступом. Она может выглядеть, например, так:
user’s ID |
Идентификатор |
Идентификатор |
… |
Идентификатор |
|
объекта1 |
объекта2 |
|
объектаN |
… |
… |
… |
… |
… |
Иван |
0001 |
0101 |
… |
1111 |
Пётр |
0000 |
1101 |
… |
0001 |
… |
… |
… |
… |
… |
Здесь двоичные числа – это коды наборов привилегий. Отдельные
типы привилегий закодированы так:
RETREIVE |
UPDATE |
INSERT |
DELETE |
ALL |
|
|
|
|
|
0001 |
0010 |
0100 |
1000 |
1111 |
|
|
|
|
|
Код набора привилегий есть сумма кодов типов привилегий. Пользователь
Иван имеет право извлекать строки объекта1, извлекать и добавлять строки объекта2, выполнять все виды действий над объектомN.
Пётр не имеет доступа к объекту1 и т.д.
Матрица управления доступом может содержать и другие ограничения,
например, на число выбираемых строк, на время доступа (с 9:00 до 17:00 по рабочим дням недели) и т.п.
Приняв запрос пользователя, СУБД извлекает соответствующую строку матрицы управления доступом, и проверяет, имеет ли пользователь все необходимые привилегии на вовлечённые в запрос объекты. Запрос обрабатывается, только если проверка дала положительный результат.
4.8.5 Подсхемы
Подсхема (внешняя схема) представляет собой набор виртуальных записей, реально не существующих в БД. Эти записи создаются в систем-
ном буфере тогда, когда пользователь запускает своё приложение. Под-
схема является мощным и гибким средством ограничения доступа к дан-
ным. Она отображает для пользователя только ту часть БД, которая необ-
ходима ему для работы. Если пользователь имеет единственную привиле-
73
гию – запуск своего приложения, то его доступ к данным ограничен рам-
ками внешней схемы. Ни о каких данных, кроме тех, которые отображает внешняя схема, он может и не подозревать. Для него это и есть вся БД.
4.8.6 Сеанс
Сеанс – это промежуток времени между моментом подключения пользователя к системе и моментом отключения. Подключив пользователя,
система готова предоставить ему все свои ресурсы в рамках его привиле-
гий. Момент начала, и момент окончания сеанса пользователя регистри-
руются в системном журнале. Кроме того, система протоколирует в жур-
нале все действия пользователя в течение сеанса во всех деталях.
4.9 Управление параллелизмом
4.9.1 Необходимость управления параллелизмом
СУБД одновременно контролирует сеансы и обрабатывает транзак-
ции многих пользователей. Операции различных транзакций чередуются,
за счёт чего достигается их параллельное исполнение. Это, в свою очередь,
приводит к повышению общей производительности системы.
Однако при чередовании операций различных транзакций результа-
ты параллельно выполняемых обновлений данных могут оказаться несо-
гласованными, несмотря на то, что каждая транзакция выполнялась вполне корректно.
Рассмотрим типичные ситуации, которые могу возникать при парал-
лельном исполнении транзакций.
1) Потеря обновлений. Эта ситуация может возникнуть, если две транзакции пытаются параллельно обновлять один и тот же объект.
Вариант 1. Транзакция Т1 должна увеличить остаток счёта А на
1000 руб., а Т2 – снять со этого же счёта 100 руб. Пусть в исходном со-
стоянии на счёте А 1000 руб. Если бы транзакции исполнялись последова-
тельно, то после исполнения обеих на счёте А оказалось бы 1900 руб. не-
зависимо от порядка исполнения. Если же отдельные операции транзакций чередуются, то результат может быть иным.
74
|
READ(А) А = A + 1000 |
WRITE(A) |
COMMIT |
|
|
|
|
|
|
|
|||||||
|
Т1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
t |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
t1 |
t2 |
t3 |
t4 |
|
|
|
|
|
|
|
||||
|
|
|
|
|
READ(А) А = A - 100 |
WRITE(A) COMMIT |
|
||||||||||
|
Т2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
t |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
t2 |
t3 |
t4 |
t5 |
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
|||||||
Время |
Действие |
|
|
|
|
Рез. Т1 |
|
|
Рез. Т2 |
Р. буф. |
|||||||
|
Т1 |
Т2 |
|
|
|
|
|
|
|
|
|
|
|
||||
t1 |
READ(A) |
|
|
|
|
А = 1000 |
|
|
|
|
|
|
А = 1000 |
||||
t2 |
А = А + 1000 |
READ(A) |
|
|
А = 2000 |
|
|
А = 1000 |
А = 1000 |
||||||||
t3 |
WRITE (A) |
А = А – 100 |
А = 2000 |
|
|
A = 900 |
А = 2000 |
||||||||||
t4 |
COMMIT |
WRITE (A) |
|
|
|
|
A = 900 |
А = 900 |
|||||||||
t5 |
|
|
|
|
COMMIT |
|
|
|
|
|
|
|
|
|
|
А = 900 |
Рис. 4.5 Потеря обновлений, вариант 1
Тысяча рублей со счёта исчезла.
Вариант 2. Транзакция Т1 уменьшает остаток счёта на 100 руб., а
Т2 ошибочно увеличивает его на 1000 руб. и отменяется.
|
READ(А) А = A - 100 |
WRITE(A) |
COMMIT |
|
|
|
|
|||||||
|
Т1 |
|
|
|
|
|
|
|
|
|
|
|
t |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
t1 |
t2 |
t3 |
t4 |
|
|
|
|
|||||
|
|
|
|
READ(А) А = A + 1000 |
|
ROLLBACK |
|
|
|
|
||||
|
Т2 |
|
|
|
|
|
|
|
|
|
|
|
t |
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
t2 |
t3 |
|
t5 |
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
||||||
Время |
Действие |
|
|
|
|
Рез. Т1 |
Рез. Т2 |
Р. буф. |
||||||
|
Т1 |
Т2 |
|
|
|
|
|
|
|
|
|
|||
t1 |
READ(A) |
|
|
|
|
А = 1000 |
|
|
|
А = 1000 |
||||
t2 |
А = А – 100 |
READ(A) |
|
|
А = 900 |
А = 1000 |
А = 1000 |
|||||||
t3 |
WRITE (A) |
А = А + 1000 |
A = 900 |
А = 2000 |
А = 900 |
|||||||||
t4 |
COMMIT |
|
|
|
|
|
|
|
|
|
|
А = 900 |
||
t5 |
|
|
|
ROLLBACK |
|
|
|
|
|
|
А = 1000 |
Рис. 4.6 Потеря обновлений, вариант 2
На счёте осталась лишняя сотня.
Избежать потери обновлений можно, если до завершения транзак-
ции, изменяющей объект A, никакая другая транзакция не сможет его изменять.
Ни первый, ни второй вариант потери обновлений был бы невозмо-
жен, если бы при попытке изменения объекта А (момент t2) объект был за-
75
блокирован для транзакции Т1, а транзакция Т2 была бы приостановлена до его освобождения.
2) Чтение «грязных» данных. Эта ситуация может возникнуть, если транзакция имеет доступ к промежуточным результатам другой транзак-
ции.
|
READ(А) |
А = A - 100 |
WRITE(А) |
|
|
|
|
|
ROLLBACK |
|
|
||||||||
|
Т1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
t |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
t1 |
t2 |
t3 |
|
|
|
|
|
|
t8 |
|
|
||||||
|
|
|
|
|
|
|
READ(А) |
А = A + 1000 |
WRITE(А) COMMIT |
|
|
||||||||
|
Т2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
t |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
t4 |
t5 |
t6 |
t7 |
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||
Время |
Действие |
|
|
|
|
|
|
|
|
Рез. Т1 |
Рез. Т2 |
|
Р. буф. |
||||||
|
Т1 |
|
|
Т2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
||
t1 |
READ(A) |
|
|
|
|
|
|
|
|
А = 1000 |
|
|
|
|
А = 1000 |
||||
t2 |
А = А – 100 |
|
|
|
|
|
|
А = 900 |
|
|
|
|
А = 1000 |
||||||
t3 |
WRITE (A) |
|
|
|
|
|
|
|
|
A = 900 |
|
|
|
|
А = 900 |
||||
t4 |
… |
|
|
READ(A) |
|
|
… |
|
|
A = 900 |
|
А = 900 |
|||||||
t5 |
… |
|
|
A = A + 1000 |
|
|
… |
|
|
A = 1900 |
|
А = 900 |
|||||||
t6 |
… |
|
|
WRITE (A) |
|
|
… |
|
|
A = 1900 |
|
A = 1900 |
|||||||
t7 |
… |
|
|
COMMIT |
|
|
… |
|
|
|
|
|
|
A = 1900 |
|||||
|
ROLLBACK |
|
|
|
|
|
|
|
|
|
|
|
|
|
А = 1000 |
Рис. 4.7 Чтение «грязных» данных
На самом деле должно быть 2000 руб. Транзакция Т2 работала с
«несуществующими» данными, не зафиксированными в БД. Даже если бы объект А был заблокирован в момент t2, но освобождён после сохранения в буфере (к моменту t4), положение не изменилось бы.
Грязные чтения невозможны, если до завершения транзакции, из-
меняющей некоторый объект, никакая другая транзакция не сможет чи-
тать этот объект.
3) Несогласованная обработка. В двух предыдущих примерах речь шла о параллельном исполнении транзакций, изменяющих состояние БД.
Однако проблемы возникают и в том случае, если одна из двух параллель-
но исполняемых транзакций обновляет состояние БД, а другая только из-
влекает данные, и выполняет какие-либо преобразования.
76
Пример. Пусть транзакция Т1 переводит деньги со счёта А1 на А3, а
транзакция Т2 вычисляет сумму остатков счетов А1, А2 и А3. Возможна показанная ниже последовательность исполнения операций транзакций.
|
|
|
READ(А1) A1 = A1 - 100 W RITE(A1) |
READ(А3) |
A3 = A3 + 100 W RITE(A3) COMMIT |
|
|
|
|
|
|
|
||||||||||||||
Т1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
t |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
t2 |
t3 |
|
t4 |
t5 |
t6 |
t7 |
|
t8 |
|
|
|
|
|
|
|
||||||||
sum = 0 READ(А1) |
|
|
READ(А2) |
|
|
|
|
|
|
READ(А3) |
|
|
sum = |
|
|
|
|
|||||||||
sum = A1 |
sum = A1 + A2 |
|
|
A1 + A2 + A3 COMMIT |
||||||||||||||||||||||
Т2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
t |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
t1 |
t2 |
t3 |
|
t4 |
t5 |
|
|
|
|
|
|
t9 |
|
t10 |
t11 |
||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||
Время |
Действие |
|
|
|
|
|
|
|
|
|
|
Состояние буфера |
||||||||||||||
|
|
|
Т1 |
|
|
|
Т2 |
|
|
|
|
sum |
|
A1 |
|
|
A2 |
A3 |
||||||||
t1 |
|
|
|
|
|
sum = 0 |
|
|
0 |
|
1000 |
|
500 |
250 |
|
|
||||||||||
t2 |
READ(A1) |
|
READ(A1) |
|
|
0 |
|
1000 |
|
500 |
250 |
|
|
|||||||||||||
t3 |
A1 = A1 - 100 |
|
sum = sum + A1 |
1000 |
|
1000 |
|
500 |
250 |
|
|
|||||||||||||||
t4 |
WRITE (A1) |
|
READ(A2) |
|
|
1000 |
|
900 |
|
|
500 |
250 |
|
|
||||||||||||
t5 |
READ(A3) |
|
sum = sum + A2 |
1500 |
|
900 |
|
|
500 |
250 |
|
|
||||||||||||||
t6 |
A3 = A3 + 100 |
|
|
|
|
|
|
|
1500 |
|
900 |
|
|
500 |
250 |
|
|
|||||||||
t7 |
WRITE (A3) |
|
|
|
|
|
|
|
1500 |
|
900 |
|
|
500 |
350 |
|
|
|||||||||
t8 |
COMMIT |
|
|
|
|
|
|
|
1500 |
|
900 |
|
|
500 |
350 |
|
|
|||||||||
t9 |
|
|
|
|
|
READ(A3) |
|
|
1500 |
|
900 |
|
|
500 |
350 |
|
|
|||||||||
t9 |
|
|
|
|
|
sum = sum + A3 |
1850 |
|
900 |
|
|
500 |
350 |
|
|
|||||||||||
t10 |
|
|
|
|
|
COMMIT |
|
|
1850 |
|
900 |
|
|
500 |
350 |
|
|
Рис. 4.8 Несогласованная обработка
А должно быть 1750.
Несогласованная обработка невозможна, если до завершения тран-
закции, читающей некоторый объект, никакая другая транзакция не мо-
жет изменять его.
4.9.2 Изолированность транзакций
Из сказанного следует, что транзакции являются не только единица-
ми работы в БД, но и единицами управления. СУБД должна обеспечить та-
кой режим обработки транзакций, при котором результат их параллельного исполнения совпадал бы с результатом последовательного исполнения в каком-либо порядке. В этом случае транзакции будут изолированы, т.е.,
никакая из них не будет влиять на результаты других.
77
Для обеспечения изолированности транзакций система должна под-
держивать определённую дисциплину блокировок объектов. Рассмотрим
наиболее распространённый подход к реализации блокировок.
4.9.3 Двухфазный протокол блокировки
Идея, лежащая в основе этого подхода, состоит в следующем. Преж-
де чем выполнять какую-либо операцию над объектом базы данных А,
транзакция Т должна запросить блокировку (захват) А. В зависимости от вида предполагаемой операции объект может быть заблокирован в одном
из двух режимов:
S (Shared lock) – разделяемый захват, необходимый для выполне-
ния операции чтения;
X (eXclusive lock) – монопольный захват, необходимый для выпол-
нения операций добавления, удаления и модификации объекта.
Если объект захвачен некоторой транзакцией в режиме S, то его мо-
жет захватить в этом же режиме любая другая транзакция, однако захват
в режимеX невозможен.
Объект, захваченный в режиме X, не может быть захвачен другой транзакцией ни в каком режиме. Ниже приводится таблица совместимости
блокировок.
Таблица совместимости S/X-блокировок
|
X |
S |
|
|
|
X |
нет |
нет |
|
|
|
S |
нет |
да |
Транзакция, запросившая блокировку объекта, заблокированного другой транзакцией в несовместимом режиме, ожидает до тех пор, пока блокировка с этого объекта не будет снята. Отметьте, что транзакции,
конфликтующие по доступу, запрашивают несовместимые блокировки.
Поскольку конфликта по чтению не существует, S-захваты совместимы.
Сформулируем теперь протокол доступа к данным.
78
• Перед операцией извлечения объекта транзакция должна заблоки-
ровать его в S-режиме.
• Перед операцией обновления объекта транзакция должна заблоки-
ровать его в X-режиме. Если она уже заблокировала его в S-режиме, то эта блокировка должна быть заменена X-блокировкой.
• Если запрашиваемая транзакцией Т1 блокировка отвергается из-за несовместимости с блокировкой, наложенной на объект транзакцией Т2, то
Т1 переходит в состояние ожидания. Она находится в этом состоянии до тех пор, пока наложенная транзакцией Т2 блокировка не будет снята.
• Все наложенные транзакцией блокировки сохраняются вплоть до завершения транзакции оператором COMMIT или ROLLBACK.
Замечание 1. На практике используются неявные запросы блокиро-
вок по типу операции. Система автоматически блокирует участвующие в операции объекты в соответствующем типу запрошенной операции (про-
смотр/обновление) режиме.
Замечание 2. Нетрудно заметить, что протокол допускает возникно-
вение тупиковых ситуаций (взаимных блокировок), когда две транзакции могут сколь угодно долго ждать завершения друг друга.
Протокол предусматривает две фазы выполнения транзакции: фазу
наложения блокировок и фазу снятия блокировок. В первой происходит накопление захватов, во второй – освобождение всех захваченных объек-
тов. Транзакция не может запросить ни одной блокировки после того, как она сняла хотя бы одну наложенную ранее.
Если все транзакции соблюдают двухфазный протокол блокировки,
то коллизии потерянных изменений, «грязных» чтений и несогласованной обработки невозможны.
79
4.10 Восстановление БД
4.10.1 Необходимость восстановления
В процессе эксплуатации СБД могут возникать ситуации, в результа-
те которых база данных может быть частично или даже полностью разру-
шена. Обсудим их.
Локальный сбой – это аварийное прекращение одной транзакции.
Причиной может быть, например, попытка деления на ноль или нарушение ограничений целостности. В этот же ряд следует поставить явное заверше-
ние транзакции оператором ROLLBACK и взаимную блокировку транзак-
ций. Если транзакция выполняла обновление данных, то состояние БД в момент локального сбоя может оказаться несогласованным. Для восста-
новления согласованности необходимо устранить изменения данных, про-
изведённые прерванной транзакцией – выполнить индивидуальный откат
транзакции.
Мягкий сбой системы может произойти, например, вследствие ава-
рийного отключения питания или при возникновении неустранимого сбоя процессора и т.п. В этом случае теряется содержимое оперативной памяти.
Аварийно прерываются все существующие транзакции. Могут оказаться не зафиксированными в ФБД результаты транзакций, завершившихся опера-
тором COMMIT. При перезагрузке системы должен быть выполнен откат
всех, не завершившихся к моменту сбоя транзакций. Зафиксированные
транзакции, результаты которых к моменту сбоя не попали во внешнюю память, должны быть автоматически исполнены повторно.
Жёсткий сбой – это физическое разрушение базы данных. Ситуация весьма маловероятная, но её последствия для организации–владельца дан-
ных могут быть катастрофическими. Поэтому система должна быть в со-
стоянии восстановить базу данных даже в этом случае.
80
4.10.2 Системный журнал
Для восстановления согласованного состояния БД необходима неко-
торая информация. Посмотрим, какая именно информация необходима и как она должна использоваться.
Все фрагменты ФБД, которые обрабатываются транзакциями, счи-
тываются системой в рабочие буферы СУБД в оперативной памяти. Тран-
закции выполняют все обновления данных в этих буферах. Таким образом,
состояние рабочих буферов отражает текущее состояние той части базы данных, которая доступна для действующих транзакций.
Если происходит локальный сбой (или транзакция завершается опе-
ратором ROLLBACK), то необходимо восстановить состояние рабочих бу-
феров на момент начала транзакции. Для отмены обновлений достаточно иметь полную информацию об операциях обновления, выполнявшихся транзакцией, а именно: тип операции, объект обновления, детали обновле-
ния. Тогда, проделав в обратном порядке обратные по смыслу операции,
можно восстановить состояние изменявшихся транзакцией буферов БД.
Таким образом, для восстановления согласованного состояния БД при программном откате транзакции или после локального сбоя должна сохраняться полная информация обо всех операциях обновления, выпол-
ненных транзакцией.
Эта информация хранится в системном журнале. Записи журнала содержат детальные сведения обо всех операциях каждой транзакции. В
них для каждой транзакции фиксируется
−идентификатор транзакции,
−идентификатор пользователя, запустившего транзакцию,
−время начала транзакции,
−время и способ завершения транзакции.
Для каждой операции фиксируется
− идентификатор транзакции, в которой выполнялась операция,