Многоверсионный контроль MySQL-InnoDB-MVCC

база данных MySQL

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

  1. еслиtrx_id_current < trx_id_first, это означает
    Когда текущая транзакция читает строку записей, значение скрытого поля идентификатора транзакции, заданное для строки данных, меньше, чемread viewЗаписанный в «идентификатор транзакции, установленный другими транзакциями в текущей системе, для этой записи строки должен быть меньше».
    Это означает, что среди всех текущих транзакций, связанных с этой строкой записей, текущая транзакция является первой, кто прочитал эту строку записей, и нет транзакции, которая изменила строку данных перед текущей транзакцией, но еще не зафиксировала. , так что текущую транзакцию можно получить напрямую из таблицыстабильные данные!
  2. еслиtrx_id_current > trx_id_last, то значит
    Когда текущая транзакция читает строку записей, значение скрытого поля идентификатора транзакции, заданное для строки данных, меньше, чемread viewЗаписано в «идентификатор транзакции, установленный другими транзакциями в текущей системе для этой записи строки, должен быть больше».
    Это означает, что среди всех текущих транзакций, связанных с этой строкой записей, текущая транзакция является последней, читающей эту строку записей, поэтому необходимо прочитать записи из этой строки записей.DB_ROLL_PTRВыньте номер версии последнего журнала отмены из сегмента отката, на который указывает указатель, назначить егоtrx_id_current, а затем продолжить перезапуск всего набора алгоритмов сравнения. Если эта итерация продолжится, она будет искать слой за слоем в журнале отмены и, наконец, получитстабильные данные!
  3. еслиtrx_id_first < trx_id_current < trx_id_last, там же;

В сравненииREAD COMMITEDиREPEATABLE READ

  1. read viewЕсли вы хотите узнать больше о принципе генерации, вы можете обратиться к Baidu или самостоятельно.блог fxliutao
  2. Ранее было известно, что MVCC — это толькоREAD COMMITTEDиREPEATABLE READработа под двумя уровнями изоляции;
  3. и согласноread viewПринцип генерации , приводящий к двум различным уровням изоляции,read committedВсегда считывайте последние данные моментального снимка, в то время как при повторном чтении считывается версия данных строки в начале транзакции;

    • сделатьREAD COMMITEDуровень гарантирован, пока он актуаленперед выполнением инструкцииВсе отправленные данные видны**. Примечание иREPEATABLE READзона уровня!!!
    • сделатьREPEATABLE READуровень гарантирован, пока он актуаленПеред выполнением транзакцииВсе отправленные данные видны.

резюме

  1. Как правило, мы считаем, что MVCC имеет следующие характеристики:

    • Для каждой строки данных существует версия, которая обновляется каждый раз при обновлении данных.
    • Копируйте текущую версию при изменении, а затем изменяйте ее по своему желанию, без вмешательства между каждой транзакцией
    • Сравните номер версии при сохранении, в случае успеха (commit) перезапишет исходную запись, а в случае неудачи откажется от копирования (rollback)
    • То есть у каждой строки есть номер версии, и успешность определяется по номеру версии при сохранении.Это звучит как оптимистическая блокировка, потому что кажется, что только когда сделана фиксация, становится известно, была ли фиксация успешной или нет.
  2. Способ, которым InnoDB реализует MVCC:

    • Транзакция изменяет исходные данные в виде эксклюзивной блокировки.
    • Сохраняйте данные перед модификацией в журнале отмены и связывайте их с основными данными через указатель отката.
    • Если модификация прошла успешно (коммит), ничего не делать, а если не удалось, восстановить данные в журнале отмены (откат)
  3. Самое существенное различие между ними состоит в том,: менять ли данные при изменении данных排他锁定, если он заблокирован, это все еще 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Затем я реорганизовал новую статью, основываясь на собственном понимании;
Категории