Серия MySql: Как MySQL решает проблему фантомного чтения? | Испытание августовского обновления

задняя часть MySQL
Серия MySql: Как MySQL решает проблему фантомного чтения? | Испытание августовского обновления

Это 11-й день моего участия в августовском испытании обновлений. Узнайте подробности события:Испытание августовского обновления


📖Предисловие

寻找光的过程,就是向上爬的过程

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

Что такое фантомное чтение? В транзакции, после нескольких запросов количество наборов результатов несовместимо, это называется фантомным чтением. А какая линия больше или меньше называется магической линией.

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

Как MySQL решает фантомные чтения? Если вы читаете эту статью, то я предполагаю, что вы понимаете грязное чтение, неповторяемое чтение и повторяемое чтение.


😎Что такое фантомное чтение, грязное чтение и неповторяемое чтение?

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

🎊Разница между неповторяемым чтением (может быть решена блокировкой строки) и фантомным чтением (требуется блокировка таблицы для решения)

Многие люди легко путают неповторяемое чтение (суть неповторяемого чтения в том,update, то есть сравнение модификации конкретного содержимого данных до и после транзакции, а также фантомное чтение.insertа такжеdelete, то есть сравнение количества данных до и после транзакции) и фантомных чтений, которые действительно чем-то похожи.

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

ноMySQL、ORACLE、PostgreSQLДругие зрелые базы данных по соображениям производительности используют оптимистическую блокировку в качестве теоретической основы.MVCC(多版本并发控制)чтобы избежать обеих проблем.


🎎 Пессимистическая блокировка и оптимистичная блокировка

Порталы: оптимистичные замки и пессимистичные замки

  • пессимистический замок

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

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

  • оптимистическая блокировка

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

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

Следует отметить, что не существует фиксированной спецификации для реализации MVCC, и каждая база данных будет иметь свой метод реализации.Здесь обсуждается MVCC InnoDB.


🎇1. Многоверсионный контроль параллелизма (MVCC) (чтение моментальных снимков/согласованное чтение)

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

Одна — это созданная версия строки, а другая — удаленная (с истекшим сроком действия) версия строки. конкретный номер версии (trx_id)существуетinformation_schema.INNODB_TRXв таблице. номер версии(trx_id) увеличивается с каждой транзакцией.

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

обычныйselectЭто моментальное чтение.

SELECT id FROM T WHERE number = 1;

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


🎈2.next-keyблокировка (текущее чтение)

Замок следующего ключа состоит из двух частей:

  • блокировка записи (блокировка строки)

  • гэп замок

Блокировка записи — это блокировка, применяемая к индексу, а между индексами применяется блокировка промежутка. (Подумав: что произойдет, если в столбце нет индекса?)

SELECT id FROM T WHERE number = 1 for update;
SELECT id FROM T WHERE number = 1 lock in share mode;
insert
update
delete

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


🤳Другое:MySQL InnoDBдвигательRRРазрешает ли уровень изоляции фантомное чтение?

Адрес комментария на github:

Официальное объяснение фантомного чтения, данное Mysql, таково: пока есть больше строк во втором выборе в транзакции, это фантомное чтение.
Транзакция а выбирает первой, а вставка транзакции b действительно добавит блокировку пробела, но если транзакция b зафиксируется, блокировка пробела будет снята (после освобождения транзакция а может управляться по желанию с помощью dml), и результат, выбранный транзакцией a, будет согласован с MVCC. Первый выбор такой же, а затем транзакция a обновляется безоговорочно. Это обновление будет действовать на все строки (включая новые, добавленные транзакцией b). Если транзакция a выбирает снова появится новая строка в транзакции b, и эта новая строка появится. Она была изменена обновлением, и фактическое измерение верно на уровне RR.
Если вы понимаете это таким образом, уровень RR Mysql не может предотвратить фантомное чтение.

Друг-даос ответил по адресу:

В случае чтения моментальных снимков mysql использует mvcc, чтобы избежать фантомных чтений. В текущей ситуации чтение-чтение mysql использует следующий ключ, чтобы избежать фантомных чтений. Выбрать * from t, где a=1; принадлежит моментальному снимку read select * from t, где a=1 блокировка общего доступа режим; принадлежит текущему чтению Ситуацию, когда результаты чтения моментального снимка и текущего чтения различаются, нельзя рассматривать как фантомное чтение, поскольку это два разных использования. Поэтому я думаю, что уровень rr mysql решает фантомное чтение.

Вывод первый,MySQLмеханизм храненияInnoDBуровень изоляцииRRРешена проблема с фантомным чтением. Плохие вопросы на собеседованииMySQLСуществует четыре уровня изоляции, и вам рекомендуется учиться все больше и больше.

Как указано в цитируемом вопросе,T1 selectПозжеupdate, будуT2серединаinsertЕсли данные обновляются вместе, то считается, что есть лишняя строка, поэтому предотвратить фантомное чтение невозможно. Кажется, что утверждение безупречно, но на самом деле оно ошибочно.InnoDBДва режима чтения моментального снимка и текущего чтения установлены в .Если есть только чтение моментального снимка, то проблемы с фантомным чтением нет, но если оператор повышается до текущего чтения, тоT1существуетselectПри использовании следующего синтаксиса:select * from t for update (lock in share mode)Введите текущие показания, то естественно нетT2Пришло время вставить данные.


👏 Внимание

next-keyХотя он очень хорошо решает проблему фантомного чтения, он все же следует общему закону: чем выше уровень изоляции, тем ниже параллелизм.


🎉 Наконец-то

  • Дополнительные справочные сообщения в блоге см. здесь:"Блог Чен Юнцзя"
  • Друзья, которым нравятся блогеры, могут подписаться, поставить лайк и продолжать обновлять, хе-хе!