Какой MVCC больше всего любят задавать крупные производители?
Какой MVCC больше всего любят задавать крупные производители?

введение

Управление многоверсионным параллелизмом (MVCC) — это технология, используемая для повышения производительности одновременного выполнения баз данных, которая особенно эффективна при выполнении операций чтения и записи с высоким уровнем параллелизма. MVCC позволяет избежать конфликтов чтения и записи, поддерживая несколько версий данных, поэтому операции чтения не должны блокировать операции записи, а операции записи не влияют на операции чтения. Ниже мы подробно объясняем принцип реализации MVCC механизмом хранения InnoDB в MySQL.

MySQL
MySQL

Основные понятия MVCC

MVCC (Multi-Version Concurrency Control) можно рассматривать как улучшение блокировки на уровне строк, которое в основном обеспечивает одновременный доступ к данным за счет сохранения нескольких версий данных в разные моменты времени. MVCC часто используется для реализации оптимистических стратегий блокировки, контроля согласованности данных с помощью номеров версий и предотвращения узких мест в производительности, вызванных блокировками.

Интересно, задумывались ли вы когда-нибудь над таким вопросом: почему в повседневных операциях операции чтения и записи не могут блокировать друг друга?

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

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

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

Давайте посмотрим на пример на рисунке 1;

  1. Когда запись изменена на сеансе 1, но еще не отправлена,В это время запрос выполняется в Session2.,Что будет, если запись вернут?
  2. А когда будет отправлен сеанс Session1, как изменятся результаты при повторном запросе сеанса 2?
Рисунок 1
Рисунок 1

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

  • READ-UNCOMMITTED Уровень изоляции: существующий сеанс 1 До и после подачи, сессия 2Найденныйиз Вседа После модификацииизрезультат,Прямо сейчасcolumn= lisi
  • READ-COMMITTED Уровень изоляции: существующий сеанс 1 Перед отправкой, сессия 2Найденныйизвсе ещеданеобработанные данныеcolumn= zhangsan

,Но после того, как существование будет представлено,Запросрезультатстановитьсяcolumn= lisi

  • REPEATABLE-READ и SERIALIZABLE Уровень изоляции: существующий сеанс 1 До и после подачи, сессия 2Найденныйизвсегдада До модификацииизрезультатcolumn= zhangsan

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

действовать

MySQL 5.7

MySQL 8.0

Запросить текущий уровень изоляции сеанса

ВЫБЕРИТЕ @@tx_isolation; или ПОКАЗАТЬ ПЕРЕМЕННЫЕ, КАК 'transaction_isolation';

ВЫБЕРИТЕ @@transaction_isolation; или ПОКАЗАТЬ ПЕРЕМЕННЫЕ, КАК 'transaction_isolation';

Запросить глобальный уровень изоляции

ВЫБЕРИТЕ @@global.tx_isolation; или ПОКАЗАТЬ ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ, КАК 'transaction_isolation';

ВЫБЕРИТЕ @@global.transaction_isolation; или ПОКАЗАТЬ ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ, КАК 'transaction_isolation';

Изменить текущий уровень изоляции сеанса

SET SESSION TRANSACTION ISOLATION LEVEL уровень изоляции;

SET SESSION TRANSACTION ISOLATION LEVEL уровень изоляции;

Изменить глобальный уровень изоляции

SET GLOBAL TRANSACTION ISOLATION LEVEL уровень изоляции;

SET GLOBAL TRANSACTION ISOLATION LEVEL уровень изоляции;

Среди них уровень изоляции может быть одним из следующих:

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATABLE READ(MySQLпо умолчанию)
  • SERIALIZABLE

существуют Здесь мы пока не будем обсуждать характеристики базы данных изACID, а дасосредоточиться навопрос:данные о существовании были изменены,Как база данных гарантирует, что результаты запроса сохранят предыдущее значение?

Это достигается с помощью журналов отмены и технологии MVCC в базе данных, как показано на рисунке 1-1.

1-1
1-1

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

  1. DB_TRX_ID Каждая запись содержит DB_TRX_ID,то есть идентификатор транзакции,Записывает последнюю вставку строкииливозобновлятьиз делID。когда это необходимосудить о Когда запись да в деле видна, InnoDB Сравнение будет производиться на основе столбца, текущей транзакции и представления.
  2. DB_ROLL_PTR DB_ROLL_PTR да Указатель отката, указывающий на предыдущую версию записи строки. существуют При обновлении данных InnoDB Записи старых версий будут сохранены и связаны с помощью этих указателей для поддержки поиска предыдущих версий данных посредством отката. Это да понимает MVCC Ключ к многоверсионному хранилищу.
  3. DB_ROW_ID DB_ROW_ID да Автоматически увеличивающийся идентификатор строки, используемый для уникальной идентификации каждой строки данных при отсутствии явного первичного ключа. хотя DB_ROW_ID существовать MVCC Механизм не контролирует параллелизм напрямую.,Но он играет важную роль в управлении записями строк и их позиционировании.,Особенно когда дасуществовать не определяет первичный ключ.

Эти три скрытых столбца совместно поддерживают InnoDB из MVCC выполнить,Обеспечить существование в сценариях с высоким уровнем параллелизма.,Чтение и запись могут выполняться параллельно, не блокируя друг друга.

При вставке фрагмента данных Соответствующий указатель сегмента отката в существующей записи имеет значение NULL. Как показано на рисунке 1-2.

1-2
1-2

При обновлении записи исходная запись сохраняется в Undo В табличном пространстве можно прочитать измененные данные, которые не были отправлены во время запроса. Undo Добиться этого можно в старой версии табличного пространства. Несколько версий данных связаны через структуру связанного списка, образуя цепочку версий. MySQL Прохождение рекордаизуказатель отката(DB_ROLL_PTR)иделаID(DB_TRX_ID)чтобы определить версию данныхизвидимыйсекс。специфический Процесс принятия решенияследующее:

Процесс принятия решения

существуют в начале каждой транзакции,Система скопирует всю текущую информацию об активной транзакции в список.,называетсяRead View。При чтении записей,Будет основано на записях TRX_ID и Read View Самый крупный в Китае TRX_ID минимальная сумма TRX_ID Сравните, чтобы определить, видна ли запись для текущей транзакции.

  1. если Записыватьиз TRX_ID меньше, чем Read View Средний и самый маленький TRX_ID******:** Описание записи существует Read View серединаизвседела Отправьте заявку, прежде чем начать,таким образом, видимый для текущей транзакции,Данные могут быть возвращены напрямую.
  2. если Записыватьиз TRX_ID больше, чем Read View Самый крупный в Китае TRX_ID******:** Описание записи существуетдела Изменено после запуска。этотчаснеобходимо основываться науказатель отката Найти предыдущую версиюиз Записывать,и сделай это TRX_ID Присвойте значение текущей строке и повторите оценку.
  3. если Записыватьиз TRX_ID роды Read View В пределах:

Необходимо дальнейшее решение:

  • если TRX_ID существовать Read View серединажитьсуществовать:
    • Это означает, что запись существовала на момент начала транзакции.,Не представлено. В это время по указателю отката находится запись предыдущей версии.,вынуть его TRX_ID Сделайте следующий раунд суждения.
  • если TRX_ID Нетсуществовать Read View середина:
    • Описание записи существуетделазапускатьчас Поданный,поэтому виден для текущей транзакции,Данные могут быть возвращены напрямую.

Что такое ReadView

Read View да MySQL InnoDB Двигатель используется для реализации Многоверсионный параллельный контроль (MVCC) из Ключевые механизмы. Он существует, чтение выполнения транзакции Одновременно создается снимок, чтобы гарантировать, что транзакции могут видеть согласованное и стабильное представление данных. Читать View Записывает состояние системы, когда транзакция создает снимок, особенно все транзакции. транзакцияиз ID список. проходить Read View,База данных может гарантировать, что транзакция видит только те данные, которые были зафиксированы при создании представления.,На него не повлияют другие последующие дела.

Текущее чтение и чтение снимка

Текущее чтение

  • сейчас читаю Нужно получить последнюю версию записи из,И существование может быть заблокировано во время чтения.,Чтобы другие транзакции не могли одновременно изменять эти записи.
  • сцена:SELECT ... LOCK IN SHARE MODE, SELECT ... FOR UPDATE, UPDATE, INSERT, DELETE ждать.
  • Эти действия гарантируют, что транзакция считывает самые последние данные.,И избегайте одновременного изменения данных во время других транзакций.

Чтение снимка

  • чтение снимка обычно означает издабез блокировкииз SELECT действовать,оно проходит Read View выполнить,Убедитесь, что транзакции считывают полную версию данных при создании моментального снимка.,Вместо того, чтобы изменять его после да.
  • сцена:SELECT действовать, существовать, уровень изоляции считается зафиксированным (Read Committed) или повторяемое чтение (Repeatable Read) особенно распространено.
  • уровень изоляции сериализуется (Serializable) Когда, читая снимка выродится в сейчас читаю, из-за этого все времядействовать должно обеспечивать полную согласованность данных во избежание фантомного чтения.

Четыре поля просмотра чтения

Четыре поля просмотра чтение определяет выполнение транзакции существованиечтение снимка Какие данные ему видны, а какие Невидимый.

trx_ids:

  • trx_ids дагенерировать Read View все время активная транзакция(Прямо сейчас Не отправленодела)из ID список.
  • Эти транзакции вносят изменения в текущую транзакцию. Невидимый.,После создания представления чтения,Данные, измененные этими транзакциями в базе данных, не будут видны транзакции.

low_limit_id:

  • low_limit_id да Следующая транзакция будет назначена из ID。
  • из-за бизнеса ID увеличивается, поэтому low_limit_id отметить, чем ID Обновление транзакции (т.е. последующей транзакции) данных до текущих Read View Невидимый.

up_limit_id:

  • up_limit_id дагенерировать Read View Минимальная транзакция была совершена, когда ID。
  • этот ID Изменения данных, сгенерированные всеми ранее зафиксированными транзакциями, видны текущей транзакции, что также является одной из границ определения видимости версий данных.

creator_trx_id:

  • creator_trx_id дасоздавать Read View из дел ID。
  • Это поле используется для определения видимости отправленной версии данных в рамках текущей транзакции. Например,еслисуществовать выполнено несколько раз в транзакции чтение снимка,Creator_trx_id помогает определить, какие версии данных генерируются самой текущей транзакцией.,и видимый для него.

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

Интерпретация исходного кода

существовать MySQL 8.0 из Исходный кодсередина,Read View Основной код в основном включает в себя InnoDB двигатель хранения раздел администратора дел. они определяют Read View генерация, инициализация поля, оценка видимости и другие функции.

read_view_open_now функция

функция read_view_open_nowda используется для создания нового изображения. Read Вид. Он запишет текущие активные транзакции и инициализирует Read View из Каждое поле.

Язык кода:javascript
копировать
read_view_t* read_view_open_now(trx_t* trx) {
    read_view_t* view;

    view = static_cast<read_view_t*>(ut_malloc_nokey(sizeof(*view)));
    ut_a(view != NULL);

    /* Настроить создающую транзакцию ID */
    view->creator_trx_id = trx->id;

    /* Будьте в курсеактивная список транзакций и назначить view */
    view->m_trx_ids = trx_sys_get_active_trx_ids();

    /* активная транзакцияизколичество */
    view->trx_list_len = trx_sys->rw_trx_list_len;

    /* Установить низкий уровень воды */
    view->low_limit_no = trx_sys->rw_trx_list->start->id;

    /* Установить высокий уровень воды */
    view->up_limit_no = trx_sys->rw_trx_list->end->id;

    return(view);
}

trx_sys_get_active_trx_ids функция

функция trx_sys_get_active_trx_ids используется для получения всей активности в текущей системе. транзакцияиз ИДЕНТИФИКАТОР. Эта функция возвращает список, содержащий все незафиксированные транзакции. ID из списка транзакций из изменений в текущих Read View Невидимый.

Язык кода:javascript
копировать
trx_id_t* trx_sys_get_active_trx_ids() {
    trx_id_t* trx_ids;

    /* выделено для транзакций хранения ID из Объем памяти */
    trx_ids = static_cast<trx_id_t*>(ut_malloc_nokey(trx_sys->rw_trx_list_len * sizeof(trx_id_t)));

    /* Пересечь течениеактивная список транзакций, сохраняет каждую транзакцию из ID */
    rw_trx_list_lock();

    rw_trx_t* rw_trx = trx_sys->rw_trx_list->start;

    for (size_t i = 0; i < trx_sys->rw_trx_list_len; i++, rw_trx = rw_trx->next) {
        trx_ids[i] = rw_trx->id;
    }

    rw_trx_list_unlock();

    return trx_ids;
}

read_view_sees_trx_id функция

функция read_view_sees_trx_idиспользуется длясудить о деле ID изменено на текущий Read View видно. это основано на Четыре поля просмотра чтение для определения наглядности.

Язык кода:javascript
копировать
bool read_view_sees_trx_id(read_view_t* view,trx_id_t trx_id) {
    /* еслидела ID меньше, чем up_limit_id, указывающий на существование транзакции Read View Он был отправлен до сборки, поэтому его видно. */
    if (trx_id < view->up_limit_no) {
        return true;
    }

    /* еслидела ID больше, чемили равно low_limit_id, указывающий, что транзакция существует Read View Запускается после генерации, поэтому не видно */
    if (trx_id >= view->low_limit_no) {
        return false;
    }

    /* еслидела ID существовать active_trx_ids Перечислите, опишите даактивная одна из транзакций и поэтому невидима */
    for (size_t i = 0; i < view->trx_list_len; i++) {
        if (view->m_trx_ids[i] == trx_id) {
            return false;
        }
    }

    /* если Если ни одно из вышеперечисленных условий не выполнено, транзакция видна */
    return true;
}

read_view_close функция

функция read_view_close используется для закрытия и уничтожает одно Read Посмотреть, освободить память.

Язык кода:javascript
копировать
void read_view_close(read_view_t* view) {
    ut_free(view->m_trx_ids);
    ut_free(view);
}

Краткое описание логики кода

создавать Read View (read_view_open_now):

  • Создать новое имя для транзакции Read Просматривает и инициализирует все свои поля, включая активную список транзакций, верхний и нижний пределы ID ждать.

Получайте активные транзакции ID (trx_sys_get_active_trx_ids):

  • Пересеките системусерединавсе Не отправленоиз дел,возьми ихиз ID и добавьте эти ID хранилищесуществовать Read View середина.

Определите видимость транзакции (read_view_sees_trx_id):

  • судить о деле ID да Нет текущему Read View видно. Генерировать на основе Read View Время из состояния системы (например, транзакция ID верхний и нижний пределы、активная список транзакций и т.п.) судить.

закрытие Read View (read_view_close):

  • выпускать Read View Связано из памяти, конец Read View из жизненного цикла.

Эти фрагменты основного кода демонстрируют InnoDB Как пройти Read View Внедрите чтение снимков, чтобы обеспечить изоляцию и согласованность транзакций.

Реализация, связанная с MVCC

Подготовьте тестовые данные

существует Navicat. Выполните следующее в SQL и подготовьте простую тестовую таблицу:

Язык кода:javascript
копировать
CREATE TABLE test_mvcc (
    id INT PRIMARY KEY,
    value VARCHAR(50)
) ENGINE=InnoDB;

INSERT INTO test_mvcc (id, value) VALUES (1, 'Initial Value');

Работа в два сеанса

существовать Navicat Откройте два окна запросов и смоделируйте два сеанса транзакций.

сессия 1(запускатьделаивозобновлять Записывать):

Язык кода:javascript
копировать
START TRANSACTION;
UPDATE test_mvcc SET value = 'Updated Value by Session 1' WHERE id = 1;
-- На данный момент транзакция не отправлена, а данные только для сессии. 1 видимый

сессия 2(запускатьделаи Запрос Записывать):

Язык кода:javascript
копировать
START TRANSACTION;
SELECT * FROM test_mvcc WHERE id = 1;
-- В это время сессия 2 надо еще посмотреть 'Initial Value», потому что сессия 1 из дел Не отправлено

существованиясессия 1 Перед совершением транзакции данные передаются другим транзакциям Невидимый.

Зафиксируйте транзакцию и наблюдайте за изменениями

сессия 1 Отправить транзакцию:

Язык кода:javascript
копировать
COMMIT;

сессия 2 Запрос еще раз:

Язык кода:javascript
копировать
SELECT * FROM test_mvcc WHERE id = 1;
-- сейчассуществоватьсессия 2 Вы можете увидеть обновленное значение 'Updated Value by Session 1'

Анализ видимости

может пройтиэтот Экспериментальное наблюдениеделамеждуизизоляциясекси Записыватьизвидимыйсекс,Объедините следующее MySQL Встроенная команда для просмотра более подробной информации:

Язык кода:javascript
копировать
-- Проверять InnoDB из статус дел
SHOW ENGINE INNODB STATUS;

-- Проверятьтекущийделаиз ID Уровень изоляции
SELECT @@TRANSACTION_ISOLATION, @@tx_isolation;

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

Здесь необходимо объяснить одну вещь, Для разных из делуровень изоляции, видимыйсексизвыполнить也Нет一样。

  • Для уровня изоляции READ-COMMITTED: Каждый оператор запроса в транзакции будет повторно читатьView. Это приведет к неповторяющемуся явлению чтения.
  • Для уровня изоляции REPEATABLE-READ: Когда будет выполнен первый оператор транзакции, будет выполнен создательReadView. существовать Каждый запрос в течение этого периода времени после завершения транзакции не будет повторно создаватьReadView, Это обеспечивает возможность повторного чтения.

Ссылки: https://dev.mysql.com/blog-archive/mysql-8-0-mvcc-of-large-objects-in-innodb/

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose