КОНЦЕПЦИЯ многоверсионной модели согласованности по чтению
Модель конкурентного доступа Oracle или многоверсионная модель согласованности по чтению (MVRC) гарантирует, что пользователь всегда видит непротиворечивое представление запрошенных данных. Если другой пользователь изменяет запрошенные данные в процессе выполнения запроса, Oracle хранит версию данных в том виде, в каком они находились на момент начала выполнения запроса. Если на момент начала запроса какие-то транзакции уже начали выполняться, но ещё не были зафиксированы, сервер Oracle обеспечивает недоступность для запроса изменений внесённых такими транзакциями. Возвращенные в запрос данные будут отражать результаты выполнения всех транзакций, которые были зафиксированы на момент начала выполнения запроса.
Эта особенность MVRC влияет на производительность СУБД и на то, как запросы обращаются с базой данных. Основная концепция MVRC заключается в следующем:
1. Oracle не устанавливает на данные какие бы то ни было блокировки для операций чтения. Другими словами, операция чтения никогда не будет препятствовать операции записи. Даже если СУБД помещает одну-единственную блокировку всего на одну строку для операции чтения, это уже может привести к конфликтным ситуациям; к тому же для большей части таблиц БД операции обновления обычно производятся для небольшого количества “горячих точек” активных данных.
2. Операция записи никогда не будет препятствовать выполнению операции чтения. MVRC просто предоставит версию данных, которая существовала до начала выполнения операции записи.
3. Пользователь получает полный моментальный снимок данных точно на момент начала выполнения запроса. Строка, извлекаемая в конце результирующего множества, могла быть изменена за время получения всего результирующего множества. Но поскольку сервер Oracle хранит версию строки в том виде, в котором она существовала в момент начала запроса, вы всегда получаете непротиворечивую картину данных на конкретный момент времени.
4. Операция записи блокирует другую операцию записи, только если вторая пытается записать туже самую строку.
Для реализации мноверсионной согласованности по чтению в сервере Oracle применяются три специальные структуры данных:
1. Cегменты отката (rollback segments) – это структуры СУБД Oracle, служащие для хранения информации, необходимой для возврата данных в исходное состояние в случае отката транзакции. Такая информация нужна для восстановления строк БД в состояние, в котором они находились в момент начала выполнения рассматриваемой транзакции. Начиная изменять данные в блоке, транзакция сначала записывает старый образ данных в сегмент отката. Хранящаяся в сегменте отката информация в основном используется в двух целях: для предоставления необходимых для отката транзакции сведений и для поддержки многоверсионной согласованности.
Сегмент отката – это не то же самое, что журнал. Журнал предназначен для регистрации всех транзакций базы данных и для её восстановления в случае сбоя системы, тогда как сегмент отката служит для обеспечения отката транзакций и согласованности чтения.
Блоки сегментов отката кэшируются в SGA вместе с блоками таблиц и индексов. Если блоки сегментов отката долгое время не используются, то самые старые из них могут быть удалены из кэша и записаны на диск.
2. Системные номера изменений (SCN). Для того чтобы обеспечить целостность данных в базе данных необходимо отслеживать порядок выполнения транзакций. Механизм, применяемый сервером Orarcle для поддержания упорядоченности транзакций во времени, называется системным номером изменения (System Change Number – SCN).
SCN – это логическая временная метка, предназначенная для отслеживания порядка транзакций. Oracle считывает метки SCN из журнала, когда требуется воспроизвести транзакции в их корректном первоначальном порядке. На основе меток SCN Oracle также определяет, когда можно удалять уже ненужную информацию из сегментов отката.
3. Блокировки в блоках данных. СУБД должна каким-то способом узнавать о том, что некоторая строка заблокирована. Большая часть СУБД хранит в памяти список блокировок, управляемых процессом Lock Manager. Oracle хранит блокировки с помощью индикатора в том блоке данных, в котором хранится строка. Для СУБД Oracle блок данных – это наименьший объём данных, который может быть прочитан с диска, поэтому при каждом запросе строки считывается блок, а внутри него возможна блокировка. Индикаторы блокировок хранятся в блоке данных, но при этом каждая блокировка действует только для отдельной строки из блока.
В дополнение к уже упомянутым структурам данных, которые непосредственно относятся к обеспечению многоверсионной согласованности чтения, Oracle характеризуется ещё одной особенностью, позволяющей достичь большей степени параллелизма в условиях большого количества пользователей. Это нерасширяемые блокировки строк (nonescalating locks).
Для того чтобы снизить накладные расходы процесса управления блокировками, некоторые СУБД иногда распространяют блокировки на большее количество данных. Например, если какая-то определённая часть строк таблицы заблокирована СУБД расширяет блокировку до целой таблицы, блокируя уже все строки таблицы, в том числе и те, которые не затрагиваются выполняемой командой SQL. Этот механизм уменьшает количество блокировок, которыми управляет процесс Lock Manager, но приводит к блокировке не затрагиваемых операцией строк. Но поскольку сервер Oracle хранит блокировку каждой строки в её блоке данных, у него нет необходимости в расширении блокировок—и Oracle никогда этого не делает.
Синтаксис MVRC.По большей части механизм MVRC работает “за кулисами”, так что относящихся к нему синтаксических конструкций очень немного. Однако пользователям следует знать, какие существуют уровни изоляции, и уметь их устанавливать.
Уровень изоляции (isolation level) определяет, в какой мере операции одного пользователя изолированы от операций другого пользователя. В Oracle применяются два основных уровня изоляции, которые оказывают различное влияние на разработчиков и на пользователей.
Уровень READ COMMITTED вводит сериализацию на уровне команды. Иначе говоря, любой запрос получает непротиворечивое представление данных в том состоянии, в котором они существовали на момент начала запроса. Но транзакция может включать в себя несколько команд, поэтому в рамках выполняемой транзакции может произойти невоспроизводимое или фантомное чтение. Данный уровень изоляции транзакций устанавливается Oracle по умолчанию.
Уровень SERIALIZABLE вводит сериализацию на уровне транзакций. То есть любой запрос внутри транзакции получает непротиворечивое представление данных в том виде, в каком они существовали на момент начала транзакции.
Эти два уровня изоляции по-разному реагируют на транзакцию, которая при помощи блокировки запрошенной строки приостанавливает их работу. Оба уровня изоляции ждут снятия блокировки. Когда блокировка снята, операция, выполняемая с уровнем изоляции READ COMMITTED, просто повторяет попытку выполнения. Это вполне логичный подход для операций, которым важно только состояние данных на момент начала выполнения команды.
С другой стороны, если блокирующая транзакция фиксирует изменения данных, то операция, выполняющаяся с уровнем изоляции SERIALIZABLE, возвращает ошибку, указывающую на то, что сериализовать операции невозможно. Это также разумно, ведь после изменения блокирующей транзакцией состояния данных по сравнению с тем, каким оно было на момент начала транзакции SERIALIZABLE, операции записи для изменённых строк становятся невозможны. В подобной ситуации программист добавляет в программу дополнительную логику, чтобы вернуться к началу транзакции SERIALIZABLE и начать её заново.
Oracle поддерживает ещё один дополнительный уровень изоляции: READ ONLY, когда пользователь может объявить для транзакции или сеанса уровень изоляции READ ONLY. Такой уровень явно запрещает операции записи. Как и уровень сериализации транзакций, READ ONLY обеспечивает точное представление данных на момент начала транзакции.
Уровни изоляции можно устанавливать при помощи команд SQL: ALTER SESSION – устанавливает уровень изоляции для сеанса; SET TRANSACTION – устанавливает уровень изоляции для транзакции.
Синтаксис команд следующий:
ALTER SESSION
SET ISOLATION_LEVEL=SERIALIZABLE | READ COMMITTED;
где ключевое слово SERIALIZABLE вводит сериализацию на уровне транзакций; а READ COMMITTED – на уровне команд(это значение по умолчанию для Oracle).
SET TRANSACTION
ISOLATION LEVEL SERIALIZABLE | READ COMMITTED;
где SERIALIZABLE вводит сериализацию на уровне транзакции для данной транзакции, READ COMMITTED – на уровне команды для данной транзакции. Это значение по умолчанию для Oracle.
Дата добавления: 2015-08-26; просмотров: 937;