Как стать автором
Обновить

Гарантии видимости в распределённых хранилищах

Уровень сложностиСредний
Время на прочтение5 мин
Количество просмотров2.2K
Всего голосов 17: ↑14 и ↓3+17
Комментарии15

Комментарии 15

С уровнями изоляции у вас сильно упрощённая картинка, реальная намного сложнее. Например, в книге на странице 218.

А вот применить такой же подход к уровням согласованности в распределённых системах — отличная идея. С вашего позволения возьму на вооружение.

К сожалению, там автор сам не особо понимал о чём пишет. Например:

Тут описаны 3 шага. При этом порядок первого и второго не важен, так как их перестановка ни на что не влияет. И если их переставить местами, то транзакции получаются полностью сериализованными (изолированными). А значит никакой несогласованности получиться тут не может.

Я специально не выношу некоторые феномены (и как следствие "уровни изоляции") отдельно, так как они на самом деле являются следствием друг-друга. Например, фантомное чтение - это следствие невоспроизводимого чтения индекса.

Автор там очень хорошо понимал, о чём пишет (на всякий случай автор — это я :))

Если вы рассматриваете транзакцию только как совокупность изменений, то перестановка первого и второго шага действительно ни на что не влияет. Но транзакция — это ещё и чтения. Если первый и второй шаг поменять местами, то транзакции действительно сериализуются, а если нет — то нет.

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

А вот вы как раз пишете очень странные вещи. В реляционной теории нет понятия «индекса» и, соответственно, не может быть такой аномалии как «невоспроизводимое чтение индекса». Индекс — это всего лишь вспомогательная структура данных, абсолютно прозрачная для клиента. Клиент не может «прочитать индекс».

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

Либо второй шаг ломает согласованность, чтобы на третьем состоялось несогласованное чтение, либо не ломает, и тогда третий работает с согласованным состоянием.

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

Второй шаг не «либо», а ломает согласованность. И первая транзакция видит состояние базы, которого при сериализации не было бы.

всё хранится упорядоченно

Вас обманули. Попробуйте в PostgreSQL залить в таблицу какое-то количество строк, сделать SELECT без ORDER BY и запомнить порядок строк. Потом обновите несколько строк командой UPDATE и снова сделайте SELECT. Порядок изменится. А вот в Oracle — не изменится, но это именно что особенности физической реализации.

имеет как минимум первичный индекс

И снова вас обманули. Oracle, PostgreSQL, DB2 и Microsoft SQL Server позволяют создать таблицу без первичного ключа. В MySQL и SQLite опять же в силу особенностей так нельзя, да и в распределённых системах первичный ключ становится обязательным, но вообще реляционная таблица не обязана его иметь.

пачку вторичных

Индекс — вспомогательная структура, нужная именно что «для ускорения работы». Если вы убьёте индекс или построите новый, то все запросы, которые были корректны, так и останутся корректными, а некорректные не станут верными. СУБД исключительно сама решает, когда ей пользоваться индексами.

Реляционная теория не полноценная

Не пишите такого больше никогда.

Первая транзакция видит ровно то же самое состояние, как если бы первые две операции поменяли местами и транзакции были сериализованы. Очень жаль, что вы не понимаете даже таких простых вещей. Мне страшно за читателей вашей книги.

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

В нормальных СУБД я сам создаю индексы и сам же через них делаю выборки, а не шаманю над эксплейнами, чтобы не тормозило. Более того, в ГСУБД даже индексы практически не нужны.

Уже написал такое: Не пора ли реляционкам на свалку истории?

Вижу вы базы данных лишь как SQL-писатель трогали

Мне страшно за читателей вашей книги.

Ну то есть вы даже не просмотрели оглавление, а уже переживаете за читателей. Сами-то понимаете, как это выглядит?

Первая транзакция видит ровно то же самое состояние

Ну конечно же нет. Если погуглить «read skew example», то можно найти примеры.

Допустим, есть три строки, в которых обозначены дежурные врачи, и в первую смену дежурит врач Х: [ 1:X, 2:Y, 3:Z ]. Теперь врач X читает первую строку. В это время врач Y переносит своё дежурство на первую смену, меняя местами себя и X и подтверждает транзакцию. Теперь таблица выглядит так: [ 1:Y, 2:X, 3:Z ]. Врач X хочет перенести своё дежурство с утра и читает оставшиеся строки: [ 2:X, 3:Z ]. И теперь он видит, что у него два дежурства — утром и днём!!!

Если бы он перечитал строку 1, то увидел бы, что там теперь Y, и это была бы аномалия non-repeatable read. Но он её не читает, и натыкается на другую аномалию, read skew. Если вы внимательно посмотрите на диаграмму уровней изоляции, то увидите, что эти аномалии исчезают одновременно, и технические методы для борьбы с ними одинаковые. Но, тем не менее, это разные аномалии.

в виде смещения в файле, где все записи хранятся упорядоченно по этому ключу

Эхм... Я вам не случайно написал про PostgreSQL: там смещение может меняться обычной операцией UPDATE. Так что в качестве первичного ключа — так себе атрибут. В Oracle и MS SQL — не может. Ну а если мы возьмём всякие нетрадиционные СУБД на LSM-деревьях (Cassandra, Cockroach... тысячи их, в общем), то там и смещение, и сам файл меняются несколько раз, причём абсолютно независимо от воли администратора.

Есть, конечно, вариант, когда записи хранятся упорядоченно по ключу — в Db2, например. Вы книжку-то почитайте. Автор, может, и не понимает, о чём пишет, но рецензировали её неглупые люди :)

В нормальных СУБД

Только вот почему-то сообщество примерно полвека как «нормальными» считает именно реляционные, а всякие СУБД типа «ключ—значение» постепенно обзаводятся SQL-движками. Не знаете, почему такое происходит?

Вы сейчас на полном серьёзе предлагаете всем своим читателям гуглить определения и не верить тому, что написано у вас? Я привёл первую попавшуюся цитату в которой написана, прямо говоря, полная ахинея. И вы нам тут демонстрируете как неспособность это осознать, так и нежелание её исправлять. С высокой вероятностью глупостей там написано куда больше, чем я нашёл за 2 минуты.

Приведённый вами тут совершенно другой кейс - это самое натуральное невоспроизводимое чтение: на первом шаге вы получили один список строк и прочитали из него первую строку, а на втором получили другой список строк и прочитали из него вторую строку.

Очевидно, операция UPDATE делает на самом деле INSERT+DELETE, когда меняется смещение. Разумеется это никому не нужно, поэтому всегда добавляют более стабильный первичный ключ вручную. Надо ли говорить, что в нормальных СУБД такой ерундой страдать не приходится?

Аргумент к массовости - это вообще какой-то детский сад. Тем более, что сейчас в моде мультимодальные СУБД. Вы статью-то почитайте, там есть ответ на ваш вопрос.

Ну если читатель не верит мне, то может и погуглить. Это ж вы писали, что «автор не понимает, о чём пишет», а не абстрактный «читатель».

На первом шаге я не читал «список строк», я читал единственную строку. Когда я выбираю одну строку из базы, я вовсе не имею в виду «догадайся, что я буду читать, составь список и дай мне первую строку». Я имею в виду именно «дай мне одну строку». А уж как СУБД это реализует — совсем другой вопрос. Ещё раз повторю: физические механизмы для избавления от non-repeatable read и read skew — одни и те же, но аномалии — разные. Это вы почему-то привязались к одной физической модели данных и считаете, что по-другому не бывает. А оно бывает, ещё как.

Аргумент к массовости - это вообще какой-то детский сад. Тем более, что сейчас в моде мультимодальные СУБД

Я понимаю, что чукча не читатель, а писатель, но всё же прежде, чем писать свои статьи, ознакомьтесь хотя бы с классикой. В частности, со статьёй Майкла Стоунбрейкера 1990 года «Манифест СУБД 3 поколения». Принцип 1 — как раз про «разнообразные структуры данных», то, что позже назвали «мультимодальными СУБД». А вот принцип 2 — про то, что не надо ломать старое. То есть если что-то массово используется, это не оттого, что все дураки, а автор той статьи, на которую Стоунбрейкер отвечал, единственный д’Артаньян. А оттого, что это удобно.

Извиняюсь, что вмешиваюсь в разговор уважаемых мужей. Но в Вашем примере меняется первая строка во второй транзакции. А первую строку уже прочитала первая. А в книге написано, что меняется строка, отличная от той, что прочитала первая транзакция. Видимо в этом есть некоторое отличие в примерах

Если первая строка во второй транзакции не меняется, то нарушений нет, и транзакции сериализуются в порядке 2-1. А вот если меняется, то возникает аномалия. Какая именно аномалия - зависит от того, какую строку прочитает первая транзакция. Если повтроно первую, то будет unrepeatable read, а если вторую - то read skew. А если перечитает и первую, и вторую, то опять транзакции сериализуются как 2-1.

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

Если первая строка во второй транзакции не меняется, то нарушений нет, и транзакции сериализуются в порядке 2-1. А вот если меняется, то возникает аномалия.

Ну формально вы правы, надо будет во втором издании этот момент чуть подробнее разобрать.

Как и все его статьи ) спасибо за книгу кстати)

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации