- •Часть IV
- •Глава 13 Восстановление
- •13.1. Введение
- •13.2. Транзакции
- •13.3. Восстановление транзакции
- •13.4. Восстановление системы
- •13.5. Восстановление носителей
- •13.6. Двухфазная фиксация
- •13.7. Поддержка языка sql
- •13.8. Резюме
- •Глава 14 Параллелизм
- •14.1. Введение
- •14.2. Три проблемы параллелизма
- •14.3. Блокировка
- •14.4. Решение проблем параллелизма
- •14.5. Тупиковая ситуация
- •14.6. Способность к упорядочению
- •14.7. Уровни изоляции
- •14.8. Преднамеренная блокировка
- •IX s
- •14.9. Поддержка блокировок в sql
- •14.10. Резюме
- •14.13. Papadimitriou с. The Theory of Database Concurrency Control.— Rockville, Md.: Computer Science Press, 1986.
- •Глава 15 Безопасность
- •15.1. Введение
- •15.2. Общие соображения
- •15.3. Избирательное управление доступом
- •15.4. Модификация запроса
- •15.5. Обязательное управление доступом
- •15.6. Шифрование данных
- •Стандарт шифрования данных
- •15.7. Поддержка мер обеспечения безопасности в языке sql
- •15.8. Резюме
IX s
IS
Рис. 14.12. Диаграмма приоритета различных типов блокировок
Стоит отметить, что (согласно протоколу преднамеренной блокировки) на уровне отношений блокировки обычно задаются неявным образом. Например, для транзакции считывания система может неявным образом наложить IS-блокировку на каждое отношение, к которому обращается данная транзакция. А для транзакции обновления вместо этого, вероятно, потребуется задать IX-блокировку. Однако в системе также может быть предусмотрено явное задание блокировок с помощью разного рода утвержденийLOCK, для того чтобы в случае необходимости позволить транзакциям наложитьS-, Х- и SIX-блокировки на заданном уровне отношений. Например, такое заданное явным образом утверждениеLOCKподдерживается системойDB2 (хотя это и не является стандартом языкаSQL).
Наконец, необходимо сделать замечание об эскалации блокировок, которая реализована во многих системах и представляет собой попытку балансирования между вступающими в конфликт требованиями высокого параллелизма и низкими накладными расходами на управление блокировками. Основная идея заключается в том, что, когда система достигает некоторого заранее заданного порога, она автоматически заменяет множество мелких блокировок одной крупной блокировкой. Например, набор отдельных S-блокировок на уровне кортежа, составляющий IS-блокировку на уровне отношения, можно преобразовать в S-блокировку на уровне отношения. На практике это решение часто оказывается весьма полезным.
14.9. Поддержка блокировок в sql
В стандарте языка SQL не предусмотрена поддержка явным образом возможности блокировки (фактически, блокировка в нем вообще не упоминается). Однако она необходима, чтобы гарантировать отсутствие конфликтных ситуаций при параллельном выполнении нескольких транзакций. Точнее, требуется, чтобы обновления, выполняемые данной транзакцией T1, не были доступны для любой другой транзакции Т2 до тех и только до тех пор, пока не будет завершено выполнение транзакции T1. Завершение выполнения транзакции открывает доступ ко всем обновлениям, выполненным данной транзакцией. А отмена выполнения транзакции приведет к тому, что все обновления будут отменены.
Замечание. Сказанное выше относится к случаям, когда все транзакции выполняются на уровне изоляции READ COMMITTED (завершенное считывание), REPEATABLE READ (повторяемое считывание) и SERIALIZABLE (способность к упорядочению). Особые рассуждения относятся к транзакциям, выполняемым на уровне изоляции READ UNCOMMITTED (незавершенное считывание) и предназначенным для выполнения "неаккуратных считываний" (об этом речь идет ниже), но только в режиме считывания READ ONLY (подробнее это описано в главе 13).
Уровни изоляции
В главе 13 уже упоминалось утверждение SET TRANSACTION из языка SQL, которое используется для указания некоторых характеристик запускаемой на выполнение транзакции. Одной из таких характеристик является уровень изоляции, который включает уровень завершенного считывания (READ COMMITTED), повторяемого считывания (REPEATABLE READ) и способности к упорядочению (SERIALIZABLE). По умолчанию устанавливается SERIALIZABLE, хотя, если задан один из трех перечисленных уровней, всегда можно использовать более высокий уровень, где выражение "более высокий" подразумевает следующий приоритет уровней: SERIALIZABLE > REPEATABLE READ > READ COMMITTED > READ UNCOMMITTED.
Если все транзакции выполняются на уровне способности к упорядочению (принятом по умолчанию), то чередующееся выполнение любого множества параллельных транзакций может быть упорядочено. Однако, если любая транзакция выполняется на более низком уровне изоляции, то существует множество различных способов нарушения способности к упорядочению. В данном стандарте указано три особых случая нарушения способности к упорядочению, а именно:
• Неаккуратное считывание. Допустим, что транзакция T1 выполняет обновление с некоторой строкой, затем транзакция Т2 извлекает эту строку, после чего выполнение транзакции T1 отменяется. В результате транзакция Т2 обнаружит, что данной строки больше не существует в том смысле, что она никогда не существовала (поскольку транзакция T1 действительно не была выполнена).
• Неповторяемое считывание. Допустим, транзакция T1 извлекает некоторую строку, транзакция Т2 затем обновляет эту строку, после чего транзакция T1 вновь извлекает "ту" строку. В результате транзакция T1 извлечет из "одной и той же" строки два совершенно разных значения.
• Фиктивные элементы. Допустим, что транзакция T1 извлекает множество всех строк, которые удовлетворяют некоторому условию (например, строки всех поставщиков из Парижа). Допустим, что транзакция Т2 вставляет новую строку, которая удовлетворяет тому же условию. Если транзакция T1 вновь повторит ту же операцию извлечения, что и раньше, то ею будет обнаружена ранее отсутствовавшая строка — "фиктивная строка".
Различные уровни изоляции определяются на основе приведенных выше случаев нарушения способности к упорядочению, и эти определения схематически представлены на рис. 14.13.
Уровень изоляции
|
Неаккуратное считывание
|
Неповторяемое считывание
|
Фиктивные элементы
|
READ UNCOMMITTED
|
Y
|
Y
|
Y
|
READ COMMITTED
|
N
|
Y
|
Y
|
REPEATABLE READ
|
N
|
N
|
Y
|
SERIALIZABLE
|
N
|
N
|
N
|
Рис. 14.13. Уровни изоляции языка SQL
Здесь может возникнуть очевидный вопрос: каким образом система может предотвратить появление "фиктивных элементов"? Для этого в ней должна быть предусмотрена блокировка пути доступа к этим данным. Если в приведенном выше примере с поставщиками из Парижа путем доступа к данным служит индекс по городам поставщиков, то в системе должен быть заблокирован индекс Парижа. Благодаря такой блокировке не будет возникать фиктивных элементов, поскольку для их создания потребуется обратиться к пути доступа (т.е. в приведенном примере к конкретному значению индекса). Более подробно этот вопрос рассматривается в [13.11, 14.4].
Как уже упоминалось выше в этой главе, в системе, поддерживающей помимо уровня SERIALIZABLE (который, по сути, является единственным безопасным уровнем) также и другие уровни, могут быть предусмотрены некоторые инструменты для явного управления параллелизмом. Обычно такие инструменты имеют вид задаваемых явным образом выражений LOCK и применяются пользователями для обеспечения безопасности, если такая безопасность не обеспечивается самой системой. Однако в стандарте языка SQL не предусмотрен такой способ явного управления блокировками.
В заключение следует повторить, что формулировки уровня REPEATABLE READ в стандарте языка SQL и в системе DB2 являются совершенно разными. На самом деле уровню REPEATABLE READ в системе DB2 соответствует уровень SERIALIZABLE в стандарте SQL.