17.3 InnoDB Многоверсионность
InnoDB — это многоверсионный движок хранения. Он сохраняет информацию об устаревших версиях изменённых строк для поддержки таких транзакционных функций, как одновременность и откат. Эта информация хранится в резервных табличных пространствах в структуре данных, называемой сегментом отката. См. Раздел 17.6.3.4, «Резервные табличные пространства». InnoDB использует информацию в сегменте отката для выполнения операций отката, необходимых в отмене транзакции. Также он использует информацию для построения более ранних версий строки для согласованного чтения. См. Раздел 17.7.2.3, «Согласованные чтение без блокировок».
Внутренне InnoDB добавляет три поля к каждой строке, хранящейся в базе данных:
Поле
DB_TRX_IDдлиной 6 байт указывает идентификатор транзакции для последней транзакции, которая вставила или обновила строку. Также удаление обрабатывается как обновление, где специальный бит в строке устанавливается для отметки её как удалённой.Поле
DB_ROLL_PTRдлиной 7 байт, называемое указателем отката. Указатель отката указывает на запись журнала отката, записанную в сегмент отката. Если строка была обновлена, запись журнала отката содержит информацию, необходимую для восстановления содержимого строки до её обновления.Поле
DB_ROW_IDдлиной 6 байт содержит идентификатор строки, который монотонно увеличивается при вставке новых строк. ЕслиInnoDBгенерирует кластеризованный индекс автоматически, индекс содержит значения идентификаторов строк. В противном случае, столбецDB_ROW_IDне отображается ни в одном индексе.
Журналы отката в сегменте отката делятся на журналы отката вставки и обновления. Журналы отката вставки нужны только при отмене транзакции и могут быть удалены как только транзакция подтверждена. Журналы отката обновления используются также при согласованном чтении, но они могут быть удалены только после того, как не останется транзакции, для которой InnoDB назначил снимок, который в согласованном чтении мог потребовать информацию из журнала отката обновления для построения более ранней версии строки базы данных. Дополнительную информацию о журналах отката см. в Разделе 17.6.6, «Журналы отката».
Рекомендуется регулярно подтверждать транзакции, включая транзакции, выполняющие только согласованные чтения. В противном случае, InnoDB не может удалить данные из журналов отката обновления, и сегмент отката может стать слишком большим, заполнив резервное табличное пространство, в котором он находится. Информацию о управлении резервными табличными пространствами см. в Разделе 17.6.3.4, «Резервные табличные пространства».
Физический размер записи журнала отката в сегменте отката обычно меньше соответствующей вставленной или обновлённой строки. Вы можете использовать эту информацию для расчёта необходимого места для вашего сегмента отката.
В схеме многоверсионности InnoDB строка не удаляется физически из базы данных сразу же, когда вы удаляете её с помощью SQL-запроса. InnoDB удаляет соответствующую строку и её записи индекса только при удалении записи журнала отката обновления, записанной для удаления. Эта операция удаления называется очисткой и она довольно быстрая, обычно занимает то же время, что и SQL-запрос, который произвёл удаление.
Если вы вставляете и удаляете строки в небольшие порции примерно с одинаковой скоростью в таблице, поток очистки может начать отставать, и таблица может стать всё больше и больше из-за всех “мёртвых” строк, что делает всё ограниченным диском и очень медленным. В таких случаях ограничьте новые операции с строками и выделите больше ресурсов для потока очистки, настроив системную переменную innodb_max_purge_lag. Дополнительную информацию см. в Разделе 17.8.9, «Настройка очистки».
Многоверсионность и Вторичные индексы
InnoDB многоверсионного управления одновременностью (MVCC) обрабатывает вторичные индексы по-другому, чем кластеризованные индексы. Записи в кластеризованном индексе обновляются на месте, и их скрытые системные столбцы указывают на записи журнала отката, из которых можно восстановить более ранние версии записей. В отличие от записей кластеризованного индекса, записи вторичного индекса не содержат скрытых системных столбцов и не обновляются на месте.
Когда столбец вторичного индекса обновляется, старые записи вторичного индекса помечаются для удаления, новые записи вставляются, а помечанные для удаления записи в конечном итоге очищаются. Когда запись вторичного индекса помечается для удаления или страница вторичного индекса обновляется более новой транзакцией, InnoDB ищет запись в базе данных в кластеризованном индексе. В кластеризованном индексе проверяется поле DB_TRX_ID записи, и правильная версия записи извлекается из журнала отката, если запись была изменена после начала транзакции чтения.
Если запись вторичного индекса помечается для удаления или страница вторичного индекса обновляется более новой транзакцией, этот метод не используется. Вместо возвращения значений из структуры индекса, InnoDB ищет запись в кластеризованном индексе.
Однако, если оптимизация сдвига условия индекса (ICP) включена и части условия WHERE могут быть оценены только с использованием полей из индекса, сервер MySQL всё ещё продвигает эту часть условия WHERE вниз к движку хранения, где она оценивается с использованием индекса. Если соответствующие записи не найдены, поиск в кластеризованном индексе пропускается. Если соответствующие записи найдены, даже среди записей, помеченных для удаления, InnoDB ищет запись в кластеризованном индексе.
© 2025 Oracle
Licensed under the GPLv2 License.