45802 (Версионность в Yukon), страница 2

2016-07-31СтудИзба

Описание файла

Документ из архива "Версионность в Yukon", который расположен в категории "". Всё это находится в предмете "информатика" из , которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "рефераты, доклады и презентации", в предмете "информатика, программирование" в общих файлах.

Онлайн просмотр документа "45802"

Текст 2 страницы из документа "45802"

Физически механизм версионности в Yukon отслеживает изменение данных отдельно для каждой записи. Для этого к записи добавляется кусочек длиной в 14 байт, в котором хранится идентификатор транзакции, изменившей эту запись, и ссылка на предыдущую зафиксированную версию. Таким образом, все версии одной записи образуют связный список, и серверу в случае необходимости не составляет никакого труда спуститься по цепочке ссылок к нужным данным.

ПРИМЕЧАНИЕ

В том случае, если на странице данных не хватает места под дополнительные 14 байт на каждую запись, то во время перевода базы в «версионное» состояние данные будут автоматически перераспределены по страницам.

Все версии записи собираются в специальном хранилище (version store heaps), которое расположено в tempdb. При любом изменении записи предыдущая версия копируется в это хранилище.

Благодаря особенностям tempdb и отсутствию журналирования для хранилища версий при обслуживании и чтении копий данных, нагрузка на операции ввода/вывода обещает быть минимальной.

Те устаревшие копии данных, которые уже точно не будут нужны ни одной транзакции, удаляются из tempdb автоматически. При этом отслеживается старейшая заинтересованная транзакция. Поэтому исключается вероятность того, что сервер в какой-то момент не найдет нужную версию. Удаление производит специальный механизм, который учитывает текущую нагрузку, через количество активных версионных транзакций, и процент свободного места в tempdb.

Для оценки предполагаемого размера хранилища версий предлагается следующая формула: Size (KB) = частота обновления версий (Version generation rate) Kb/sec. * время выполнения самой длинной транзакции (the longest transaction time) sec.

Как это работает

Здесь опять-таки проще всего разобрать по очереди все уровни изоляции предлагаемые Yukon снизу вверх.

Read uncommitted

В чистом версионнике, как уже говорилось, read uncommitted обычно не предусмотрен, да и не нужен. В Yukon при запросах к БД с включенной поддержкой версионности такой фокус тоже провернуть не получится. Даже при явном указании соответствующих подсказок оптимизатору в запросе, возвращается предыдущая зафиксированная версия, а не грязные данные транзакции, заблокировавшей запись от изменений.

Read committed

С read committed все несколько сложнее. После включения поддержки версионности все запросы на чтение при этом уровне изоляции автоматически начинают работать как версионные. То есть если транзакция при чтении натыкается на заблокированную запись, то она читает предыдущую версию этой записи из tempdb.

ПРИМЕЧАНИЕ

На самом деле в alpha-версии Yukon для поддержки версионности при read committed необходимо включить специальный трейс-флаг (3970). Но Microsoft торжественно клянется, что в финальном продукте все будет происходить автоматически.

Можно провести простенький эксперимент. Пусть есть небольшая табличка tst в БД с поддержкой версионности, например, AdventureWork, созданная с помощью вот такого скрипта:

CREATE TABLE tst(x int, y int)

GO

INSERT INTO tst(x, y) VALUES(1, 5)

INSERT INTO tst(x, y) VALUES(2, 4)

INSERT INTO tst(x, y) VALUES(3, 3)

INSERT INTO tst(x, y) VALUES(4, 2)

INSERT INTO tst(x, y) VALUES(5, 1)

Сначала откроем новое подключение, откроем read committed-транзакцию и сделаем выборку, транзакцию при этом закрывать не будем.

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

BEGIN TRAN

SELECT * FROM tst WHERE x = 3

Получим то, что и ожидалось: x = 3, y = 3.

Теперь в другой транзакции попытаемся обновить эту запись, также не фиксируя транзакцию.

BEGIN TRAN

UPDATE tst SET y = -1 WHERE x = 3

Если после этого взглянуть на блокировки, наложенные на табличку tst, то, как и при использовании предыдущих версий SQL Server, можно заметить эксклюзивную блокировку на запись и две блокировки намерения выше по иерархии, на страницу и таблицу.

Тип

Описание

Объект

Режим

Статус

spid

TAB

1963154039

IX

GRANT

52

RID

1:1357:2

72057594057326592

X

GRANT

52

PAG

1:1357

72057594057326592

IX

GRANT

52

Таблица 1

То есть картина совпадает с той, которую можно видеть при использовании предыдущей версии SQL Server или БД без поддержки версионности.

Однако дальше начинаются отличия. Если сейчас вернуться к первой транзакции и попытаться опять выполнить тот же самый запрос, то он совершенно спокойно отработает.

SELECT * FROM tst WHERE x = 3

И результат будет точно таким же: x=3, y=3. Если попробовать сделать то же самое на БД без включенной поддержки версионности, то второй запрос из первой транзакции не выполнится. Он будет ожидать фиксации или отката второй транзакции. То есть он попросту не сможет прочитать нужную запись, поскольку она заблокирована. Но в данном случае блокировка нисколько не мешает прочитать версию данных, существовавшую на момент начала выборки.

Более того, в силу особенностей работы с неиндексированными таблицами (а для тестовой таблицы индексов не создавалось), в базе без поддержки версионности второй запрос в первой транзакции не смог бы выбрать не только заблокированную запись, но и любую другую. Из-за блокировки ему все равно бы пришлось ждать завершения работы первой транзакции. Говоря проще, у блокировочника, в случае отсутствия индексов, блокировка одной записи превращается фактически в блокировку всей таблицы.

Если теперь зафиксировать изменения тестовой таблицы, произведенные второй транзакцией:

COMMIT TRAN

и сделать опять выборку тех же данных в транзакции номер один:

SELECT * FROM tst WHERE x = 3

то мы уже получим результат x = 3, y = (-1), феномен неповторимого чтения (non-repeatable read) в действии. Нам удалось дважды обратиться к одним и тем же данным из одной транзакции и получить различные результаты.

Итак, для читающих запросов все работает просто здорово, перейдем теперь к пишущим запросам все при том же уровне изоляции.

Допустим, версионник пытается обновить несколько записей из read committed-транзакции и натыкается на то, что кто-то в данный момент из другой транзакции обновил, но еще не зафиксировал одну из нужных записей. Просто подождать, пока вражеская транзакция зафиксируется, и затем поменять запись, нельзя, так как к этому времени запись может быть изменена таким образом, что перестанет удовлетворять критериям запроса. Чтобы этого не произошло, необходимо, как минимум, перечитать эту запись заново - чтобы изменять актуальную версию, а не устаревшую.

Таким образом возникает некоторый парадокс – при одном и том же уровне изоляции читающие запросы получаются согласованнее, чем пишущие. Формально все в порядке – требования уровня изоляции не нарушены. Чтобы избежать такого парадокса, в некоторых коммерческих реализациях в таких случаях делается откат запроса, а затем запрос выполняется заново, чтобы обеспечить обновление на согласованном срезе данных.

Разработчики Yukon не стали добавлять таких сложностей, и все изменения делаются по старинке, точно так же, как их делает обычный блокировочник. Вплоть до побочного эффекта, связанного с блокированием всей таблицы по причине отсутствия индекса.

Если, например, в одном подключении выполнить часть транзакции, изменив в тестовой табличке одну запись, но не фиксировать транзакцию, удерживая тем самым блокировку…

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

BEGIN TRAN

UPDATE tst SET y=3 WHERE x=3

А в другой транзакции попытаться изменить другую запись…

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

BEGIN TRAN

UPDATE tst SET y=-1 WHERE x=4

COMMIT

То вторая транзакция не завершится, а подвиснет в задумчивости. Если же в этот момент взглянуть на блокировки, наложенные на таблицу tst:

Тип

Описание

Объект

Режим

Статус

spid

PAG

1:1357

72057594057326592

IU

GRANT

54

PAG

1:1357

72057594057326592

IX

GRANT

53

RID

1:1357:2

72057594057326592

X

GRANT

53

RID

1:1357:2

72057594057326592

U

WAIT

54

TAB

1963154039

IX

GRANT

54

TAB

1963154039

IX

GRANT

53

Таблица 2

то можно наблюдать картину, характерную для самого обычного блокировочника, хотя версионности никто не отменял, в чем можно убедиться, выполнив в еще одной параллельной read committed-транзакции читающий запрос:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

BEGIN TRAN

SELECT * FROM tst

COMMIT

Этот запрос совершенно спокойно выполнится, никого не потревожив, и вернет при этом состояние таблицы на момент, предшествующий изменениям, так как ни одна из изменяющих таблицу транзакций на время выполнения этого запроса еще не зафиксирована. Все дело в том, что обычно версионник выполняет изменения данных примерно по такому сценарию:

Делается версионное сканирование таблицы, и выясняется, какие записи необходимо изменить.

Предпринимаются попытки изменить отобранные записи.

Если запись изменилась с момента версионного скана, то проверяется, не перестала ли она удовлетворять критерию отбора, и если не перестала, то запись меняется, если перестала, то пропускается. (Некоторые реализации применяют здесь более хитрые алгоритмы, но этот вопрос выходит за рамки данной статьи).

Если запись меняется в настоящий момент, то сервер дожидается конца изменений и опять-таки проверяет соответствие записи условиям выборки.

То есть ожидание , если и происходит, то только из-за того, что в процессе обновления встретилась запись, которая меняется в данный момент.

Чистый же блокировочник работает немного по другому сценарию. Сканирование данных ему не имеет смысла делать, так как все запросы на чтение у него блокирующие. Поэтому он просто перебирает все записи в таблице по очереди (напомню, речь идет о таблице без индексов), проверяя их на соответствие условию выборки, и накладывая при этом блокировку обновления (update lock). Такая блокировка совместима с блокировками чтения, но несовместима сама с собой и с монопольными блокировками. Таким образом, читающим запросам подобный перебор не мешает, но другие блокировки обновления и монопольные будут помехой этому запросу. Следовательно, если в момент перебора в таблице монопольно заблокирована хотя бы одна запись (что и имеет место в данном примере, так как запись была изменена, но транзакция еще не зафиксирована), то рано или поздно изменяющий запрос до нее доберется и зависнет на блокировке, ожидая фиксации «вражеской» транзакции.

Несмотря на возможность версионных запросов, Yukon все равно при записи данных поступает как блокировочник, что и приводит к вышеописанному эффекту.

Repeatable read

Уровень изоляции repeatable read в базе с включенной поддержкой версионности работает точно так же, как и на базе без оной. Совершенно спокойно накладываются и удерживаются должное время все положенные по статусу разделяемые (share) блокировки. Да в общем-то, вряд ли тут вообще что-то могло измениться. Но появилась одна полезная возможность: Если запрос выполняется по базе с включенной поддержкой версионности, то при указании оптимизатору хинта READCOMMITTED в читающем запросе, выборка будет версионной. Возможность действительно довольно полезная - в связи с некоторыми особенностями уровня изоляции snapshot.

Snapshot

Уровень изоляции snapshot, является чисто версионным, в отличие от предыдущего, чисто блокировочного, и вообще совершенно новым для SQL Server.

Читающие запросы при этом уровне изоляции выполняются так, как и положено им выполняться в честном версионнике при этом уровне изоляции. Если вернуться все к той же тестовой табличке и в одном из подключений начать транзакцию, в которой изменить какую-нибудь запись, но саму транзакцию не фиксировать…

BEGIN TRAN

UPDATE tst SET y = 2 WHERE x = 4

А в другом подключении начать snapshot транзакцию с читающим запросом к той же табличке…

SET TRANSACTION ISOLATION LEVEL SNAPSHOT

BEGIN TRAN

SELECT * FROM tst

То snapshot-транзакция, как, впрочем, и версионный read committed, совершенно спокойно отработает, вернув предыдущее значение измененной записи. Однако если сейчас зафиксировать первую, изменяющую транзакцию…

COMMIT TRAN

А затем повторить ту же самую выборку из snapshot транзакции…

SELECT * FROM tst

То эта выборка вернет все еще старые значения записей, существовавшие до фиксации первой транзакции. То есть здесь чтение полностью воспроизводимо, в отличие от read committed. Более того, этот уровень изоляции не допускает появления фантомов, в отличие от блокировочного repeatable read. Например, если выполнить третью транзакцию, в которой в таблицу добавляются записи…

BEGIN TRAN

INSERT INTO tst (x, y) VALUES (6, 0)

COMMIT TRAN

То очередная выборка всех записей таблицы tst из snapshot-транзакции вернет все те же записи, что и в первый раз, просто потому, что на момент первого запроса нового значения еще не было. В общем, с таблицей можно делать все что угодно, все выборки из snapshot-транзакции будут одними и теми же.

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
5173
Авторов
на СтудИзбе
436
Средний доход
с одного платного файла
Обучение Подробнее