MVCC
(Управление многоверсионным параллелизмом) 1. Сначала обратитесь к введению в MVCC в «Высокопроизводительном MySQL».
- Большинство транзакционных механизмов хранения MySQL на самом деле не реализуют простые блокировки на уровне строк.На основе соображений улучшения параллельной производительности, они обычно одновременно реализуют управление параллелизмом нескольких версий (MVCC). Не только MySQL, но и другие системы баз данных, такие как Oracle и PostgreSQL, также реализуют MVCC, но механизмы их реализации различаются, поскольку не существует единого стандарта реализации для MVCC.
- MVCC можно рассматривать как вариант блокировки на уровне строк, но во многих случаях он позволяет избежать операций блокировки и, следовательно, дешевле. Хотя механизм реализации отличается, большинство из них реализуют неблокирующие операции чтения, а операции записи блокируют только необходимые строки.
- Существует множество способов реализации MVCC, обычно оптимистичный контроль параллелизма и пессимистичный контроль параллелизма.
- MVCC есть только в
READ COMMITTED
иREPEATABLE READ
Работает при двух уровнях изоляции. Два других уровня изоляции несовместимы с MVCC, потому чтоREAD UNCOMMITTED
Всегда читайте последнюю строку данных, а не строку данных, соответствующую текущей версии транзакции. иSERIALIZABLE
Все прочитанные строки блокируются.
2. Вы можете узнать:
- MVCC используется Mysql
事务型存储引擎InnoDB
поддерживается; - Для работы с большим количеством одновременных транзакций MVCC более эффективен и менее затратен, чем простое добавление блокировок строк.;
- MVCC есть только в
READ COMMITTED
иREPEATABLE READ
работа под двумя уровнями изоляции; - MVCC может использовать
乐观(optimistic)锁
и悲观(pessimistic)锁
реализовать;
3. Кроме того, как упоминалось в «Высокопроизводительном MySQL», MVCC InnoDB сохраняется после каждой строки записей.два скрытых столбцаДля достижения... Это, кажется, отличается от многих представлений в Интернете, для получения подробной информации см.Официальное объяснение MySQL InnoDB-MVCC
Как видите, механизм хранения InnoDB добавляет три поля в конце каждой строки данных в базе данных, а не два!!
анализировать
1. Механизм хранения InnoDB добавляет три поля после каждой строки данных в базе данных.
- 6-байтовый идентификатор транзакции (
DB_TRX_ID
) поле: отметьте идентификатор транзакции последнего обновления этой записи строки, каждый раз, когда транзакция обрабатывается, ее значение автоматически +1
Кроме того, удаление рассматривается как обновление внутренне, где специальные биты в строке устанавливаются, чтобы пометить его как удаленное. - 7-байтовый указатель отката (
DB_ROLL_PTR
) поле: указывает на сегмент отката текущего элемента записиundo log
(отмена регистрации), по этому указателю находится предыдущая версия данных. - 6 байт
DB_ROW_ID
Поле: когда кластерный индекс автоматически генерируется innodb, кластерный индекс включает значение DB_ROW_ID, в противном случае кластерный индекс не включает это значение, и оно используется в индексе.
В сочетании с соответствующими знаниями о кластерном индексе я понимаю, что если в нашей таблице есть первичный ключ или подходящий уникальный индекс, то есть когда кластерный индекс не может быть сгенерирован, InnoDB автоматически сгенерирует для нас кластеризованный индекс, но кластерный индекс будет использовать значение DB_ROW_ID в качестве первичного ключа; если у нас есть собственный первичный ключ или подходящий уникальный индекс, то кластерный индекс не будет содержать DB_ROW_ID .
Насчет кластерных индексов, места в "High Performance MySQL" мне уже достаточно, и разберу предыдущие учебные заметки, а потом обновлю.
2. Продемонстрируем процесс обновления записи строки транзакцией:
3.read view
- Определить, виден ли элемент данных текущей версии
- В innodb каждый раз, когда создается новая транзакция, механизм хранения создает копию списка активных транзакций (trx_sys->trx_list) в текущей системе (
read view
), копия сохраняет список идентификаторов других транзакций в системе, которые не должны быть видны этой транзакции. - Когда пользователь хочет прочитать строку записей в транзакции, innodb сравнивает номер текущей версии строки с представлением для чтения, как описано ниже.
比较算法
;
Сравните алгоритмы:
Пусть текущий идентификатор транзакции строки будетtrx_id_current
, read view
Идентификатор самой ранней транзакции в строкеtrx_id_first
, идентификатор последней транзакцииtrx_id_last
- если
trx_id_current < trx_id_first
, это означает
Когда текущая транзакция читает строку записей, значение скрытого поля идентификатора транзакции, заданное для строки данных, меньше, чемread view
Записанный в «идентификатор транзакции, установленный другими транзакциями в текущей системе, для этой записи строки должен быть меньше».
Это означает, что среди всех текущих транзакций, связанных с этой строкой записей, текущая транзакция является первой, кто прочитал эту строку записей, и нет транзакции, которая изменила строку данных перед текущей транзакцией, но еще не зафиксировала. , так что текущую транзакцию можно получить напрямую из таблицыстабильные данные! - если
trx_id_current > trx_id_last
, то значит
Когда текущая транзакция читает строку записей, значение скрытого поля идентификатора транзакции, заданное для строки данных, меньше, чемread view
Записано в «идентификатор транзакции, установленный другими транзакциями в текущей системе для этой записи строки, должен быть больше».
Это означает, что среди всех текущих транзакций, связанных с этой строкой записей, текущая транзакция является последней, читающей эту строку записей, поэтому необходимо прочитать записи из этой строки записей.DB_ROLL_PTR
Выньте номер версии последнего журнала отмены из сегмента отката, на который указывает указатель, назначить егоtrx_id_current
, а затем продолжить перезапуск всего набора алгоритмов сравнения. Если эта итерация продолжится, она будет искать слой за слоем в журнале отмены и, наконец, получитстабильные данные! - если
trx_id_first < trx_id_current < trx_id_last
, там же;
В сравненииREAD COMMITED
иREPEATABLE READ
-
read view
Если вы хотите узнать больше о принципе генерации, вы можете обратиться к Baidu или самостоятельно.блог fxliutao - Ранее было известно, что MVCC — это только
READ COMMITTED
иREPEATABLE READ
работа под двумя уровнями изоляции; -
и согласно
read view
Принцип генерации , приводящий к двум различным уровням изоляции,read committed
Всегда считывайте последние данные моментального снимка, в то время как при повторном чтении считывается версия данных строки в начале транзакции;- сделать
READ COMMITED
уровень гарантирован, пока он актуаленперед выполнением инструкцииВсе отправленные данные видны**. Примечание иREPEATABLE READ
зона уровня!!! - сделать
REPEATABLE READ
уровень гарантирован, пока он актуаленПеред выполнением транзакцииВсе отправленные данные видны.
- сделать
резюме
-
Как правило, мы считаем, что MVCC имеет следующие характеристики:
- Для каждой строки данных существует версия, которая обновляется каждый раз при обновлении данных.
- Копируйте текущую версию при изменении, а затем изменяйте ее по своему желанию, без вмешательства между каждой транзакцией
- Сравните номер версии при сохранении, в случае успеха (commit) перезапишет исходную запись, а в случае неудачи откажется от копирования (rollback)
- То есть у каждой строки есть номер версии, и успешность определяется по номеру версии при сохранении.Это звучит как оптимистическая блокировка, потому что кажется, что только когда сделана фиксация, становится известно, была ли фиксация успешной или нет.
-
Способ, которым InnoDB реализует MVCC:
- Транзакция изменяет исходные данные в виде эксклюзивной блокировки.
- Сохраняйте данные перед модификацией в журнале отмены и связывайте их с основными данными через указатель отката.
- Если модификация прошла успешно (коммит), ничего не делать, а если не удалось, восстановить данные в журнале отмены (откат)
- Самое существенное различие между ними состоит в том,: менять ли данные при изменении данных
排他锁定
, если он заблокирован, это все еще MVCC?
- Реализация Innodb на самом деле не MVCC, потому что она не реализует сосуществование нескольких версий ядра,
undo log
Содержимое является только результатом сериализации, которая записывает процесс нескольких транзакций и не относится к сосуществованию нескольких версий. Однако идеального MVCC достичь трудно. Когда транзакция изменяет только одну строку записей, можно без проблем использовать идеальный режим MVCC. Его можно откатить, сравнив номер версии, но когда транзакция затрагивает несколько строк данных , идеальный MVCC ничего не может. - Например, если транзакция A выполняет идеальный MVCC, модификация Row1 завершается успешно, но модификация Row2 завершается неудачей, тогда Row1 необходимо откатить, но поскольку Row1 не заблокирована, ее данные могут быть снова изменены транзакцией B. , он уничтожит результат модификации транзакции B, в результате чего транзакция B нарушит ACID. Это также называется
第一类更新丢失
Случай. - Именно потому, что MVCC, используемый InnoDB, сочетается с эксклюзивной блокировкой, а не с чистым MVCC, поэтому потеря первого типа не произойдет.Вообще говоря, потеря обновления относится ко второму типу потерянного обновления.
Эта статья в основном ссылается и цитирует следующие статьи
Официальное объяснение MySQL InnoDB-MVCC
блог fxliutaoЗатем я реорганизовал новую статью, основываясь на собственном понимании;