InnoDB
механизм хранения общего назначения, который
балансирует высокую надежность и высокую производительность. В MySQL 8.0
механизм хранения по умолчанию. Если Вы не сконфигурировали иной механизм
хранения значения по умолчанию, CREATE
TABLE
без предложения ENGINE=
создает
таблицу InnoDB
.
Главные преимущества InnoDB
:
Его операции DML следуют модели ACID с транзакционными возможностями commit, rollback и crash-recovery, чтобы защитить пользовательские данные. См. раздел 16.2.
InnoDB
-таблицы располагают Ваши данные по диску, чтобы
оптимизировать запросы, основанные на
первичных ключах. Каждая таблица
InnoDB
индекс по первичному ключу, известный как
кластеризируемый индекс,
который организует данные, чтобы минимизировать ввод/вывод для поисков
первичного ключа. См. раздел 16.8.8
.InnoDB
реализует ограничения
FOREIGN KEY
.
С внешними ключами вставки, обновления и удаления проверены, чтобы
гарантировать, что они не приводят к несогласованностям в различных таблицах.
См. раздел 16.8.6.
Table 16.1. Особенности механизма хранения InnoDB
Пределы хранения | 64TB | Транзакции | Да | Блокировка степени детализации | Строка |
MVCC | Да | Поддержка геоданных | Да | Индексирование геоданных | Да |
Индексы B-tree | Да | Индексы T-tree | Нет | Индексы Hash | Нет |
Полнотекстовый поиск | Да | Кластеризируемый индекс | Да | Кэширование данных | Да |
Кэширование индексов | Да | Сжатие данных | Да | Шифрование | Да |
Поддержка базы данных кластера | Нет | Репликация | Да | Внешние ключи | Да |
Резервное копирование/восстановление момента времени | Да | Кэш запросов | Да | Статистика обновления словаря данных | Да |
Чтобы сравнить особенности InnoDB
с другими механизмами
хранения, предоставленными MySQL, см.
главу 17.
Для информации об улучшениях InnoDB
и новых особенностях в MySQL 8.0 обратитесь к:
Перечень улучшений InnoDB
в
разделе 1.4.
Термины InnoDB
перечислены в
глоссарии.
InnoDB
, см.
MySQL Forums::InnoDB.InnoDB
is published under the same GNU GPL
License Version 2 (of June 1991) as MySQL. Подробности лицензирования MySQL
см. на
http://www.mysql.com/company/legal/licensing/.Если Вы используете таблицы
MyISAM
, Вы можете счесть InnoDB
выгодными по следующим причинам:
Если Ваш сервер отказывает из-за аппаратных средств или проблемы
программного обеспечения, независимо от того, что происходило в базе данных в
то время, Вы не должны сделать ничего специального после перезапуска базы
данных. InnoDB
автоматически завершает любые изменения, которые
были переданы перед временем катастрофического отказа, и отменяет любые
изменения, которые были в процессе, но не завершены. Только перезапустите
сервер и продолжите работу.
InnoDB
поддерживает свой собственный
буферный пул, так что хранит
таблица кэшей и индексирлванные данные в основной памяти, пока к данным
получают доступ. Часто используемые данные обработаны непосредственно в
памяти. Этот кэш относится ко многим типам информации и ускоряет обработку.
На специализированных серверах базы данных до 80% физической памяти часто
назначаются на буферный пул InnoDB
.WHERE
,
ORDER BY
,
GROUP BY
и
join.InnoDB
не только позволяет параллельное чтение и
запись к той же самой таблице, это кэширует измененные данные, чтобы
упростить дисковый ввод/вывод.InnoDB
может снова использовать.
BLOB
и длинных текстовых полей с
форматом строки DYNAMIC.
InnoDB
с таблицами других
механизмов хранения MySQL, даже в пределах того же самого запроса. Например,
Вы можете использовать join, чтобы
объединить данные от InnoDB
и
MEMORY
.InnoDB
был разработан для эффективности
центрального процессора и максимальной производительности, обрабатывая
большие объемы данных.InnoDB
могут обработать большие количества данных,
даже на операционных системах, где размер файла ограничен 2GB.Для InnoDB
-специфичных методов тюнинга, которые Вы можете
применить в своем коде программы, см.
раздел 9.5.
Этот раздел описывает лучшие методы использования
таблиц InnoDB
.
Определение первичного ключа для каждой таблицы, используя наиболее часто запрашиваемый столбец или столбцы, или значения auto-increment, если нет никакого очевидного первичного ключа.
START TRANSACTION
и COMMIT
.
В то время как Вы не хотите передавать транзакции слишком часто, Вы также не
хотите выпускать огромные пакеты
INSERT
,
UPDATE
или
DELETE
, которые работают в
течение многих часов.LOCK TABLES
. InnoDB
может обработать многократные сеансы чтения и
записи той же самой таблицы сразу, не жертвуя надежностью или высокой
производительностью. Чтобы получить исключительный доступ на запись
к ряду строк, используют
SELECT ... FOR UPDATE
, чтобы заблокировать только строки, которые Вы намереваетесь обновить.
innodb_file_per_table
, чтобы поместить данные и индексы для
отдельных таблиц в отдельные файлы, вместо единственного гигантского
system tablespace.
Эта установка позволяет использовать некоторые из других функций, такие как
табличное сжатие и быструю
обрезку.
Опция
innodb_file_per_table
включена по умолчанию в MySQL 5.6.6.
InnoDB
(ROW_FORMAT=COMPRESSED
в запросе
CREATE TABLE
).
Вы можете сжать таблицы InnoDB
, не жертвуя
способностью чтения-записи.--sql_mode=NO_ENGINE_SUBSTITUTION
, если есть проблема с механизмом, определенным в параметре
ENGINE=
запроса CREATE
TABLE
.Чтобы проверить, что InnoDB
механизм хранения по умолчанию,
используйте команду SHOW ENGINES
, чтобы рассмотреть различные механизмы хранения MySQL. Ищите
DEFAULT
в строке InnoDB
. Альтернативно, запросите
из INFORMATION_SCHEMA
таблицу
ENGINES
.
Если InnoDB
не механизм хранения по умолчанию, Вы можете
определить, работают ли Ваш сервер базы данных или приложения правильно с
InnoDB
перезапуская сервер с опцией
--default-storage-engine=InnoDB
, определенной в командной строке
или с
default-storage-engine=innodb
в разделе [mysqld]
конфигурационного файла my.cnf
.
Если Вы не принимали преднамеренное решение относительно механизма
хранения, и Вы только хотите посмотреть, как определенные таблицы работают,
когда они создаются под InnoDB
, скомандуйте
ALTER TABLE table_name ENGINE=InnoDB;
для каждой таблицы. Или, чтобы выполнить испытательные запросы,
не нарушая оригинальную таблицу, сделайте копию:
CREATE TABLE InnoDB_Table (...) ENGINE=InnoDB AS SELECT * FROM MyISAM_Table;
Проверьте полный жизненный цикл приложения от установки, посредством тяжелого использования и перезапуска сервера. Уничтожьте процесс сервера в то время, как база данных занята, чтобы моделировать перебой в питании и проверить, что данные восстановлены успешно, когда Вы перезапускаете сервер.
Проверьте любые конфигурации репликации, особенно если Вы используете различные версии MySQL и опции на ведущем устройстве и ведомых устройствах.
Модель ACID ряд принципов
проектирования баз данных, которые подчеркивают аспекты надежности, которые
важны для коммерческой информации и приложений критического назначения. MySQL
включает такие компоненты, как механизм хранения InnoDB
, которые
придерживаются близко к ACID, чтобы данные не были повреждены и результаты
не искажены исключительными условиями, такими как катастрофические отказы
программного обеспечения и сбои аппаратных средств. Когда Вы полагаетесь на
ACID, Вы не должны повторно изобрести колесо проверки последовательности и
механизмы восстановления катастрофического отказа. В случаях, где у Вас есть
дополнительные гарантии программного обеспечения, ультранадежные аппаратные
средства или приложение, которое может терпеть небольшое количество потерь
данных, Вы можете скорректировать настройки MySQL, чтобы обменять часть
надежности ACID для большей работы или пропускной способности.
Следующие разделы обсуждают, как MySQL, в особенности механизм хранения
InnoDB
, взаимодействует с категориями ACID:
A: атомность.
Атомность аспект ACID, главным образом,
вовлекает InnoDB
транзакции. Связанные особенности MySQL включают:
Последовательность аспект ACID, главным
образом, вовлекает внутреннюю обработку InnoDB
, чтобы защитить
данные от катастрофических отказов. Связанные особенности MySQL включают:
InnoDB
буфер doublewrite.
InnoDB
восстановление катастрофического отказа.Изоляция аспект ACID, главным образом,
вовлекает InnoDB
транзакции, в особенности
уровень изоляции, который относится к каждой транзакции.
Связанные особенности MySQL включают:
SET ISOLATION LEVEL
.InnoDB
блокировки. Во время исполнительной
настройки Вы смотрите эти детали через таблицы INFORMATION_SCHEMA
.Длительность аспект ACID вовлекает характеристики программного обеспечения MySQL, взаимодействующие с Вашей особой конфигурацией аппаратных средств. Из-за многих возможностей в зависимости от способностей Вашего центрального процессора, сети и устройств хранения данных, этот аспект наиболее сложен, чтобы обеспечить конкретные советы. Связанные особенности MySQL включают:
InnoDB
буфер doublewrite,
управляемый параметром
innodb_doublewrite
.
innodb_flush_log_at_trx_commit
.sync_binlog
.
innodb_file_per_table
.fsync()
.InnoDB
мультиверсионный
механизм хранения: это хранит информацию о старых версиях измененных
строк, чтобы поддерживать транзакционные функции, такие как параллелизм и
отмену.
Эта информация хранится в табличном пространстве в структуре данных,
названной сегмент отмены
(после аналогичной структуры данных в Oracle). InnoDB
использует информацию в сегменте отмены, чтобы выполнить операции отмены,
необходимые в работе. Это также использует информацию, чтобы создать более
ранние версии строки для
последовательного чтения.
Внутренне InnoDB
добавляют три поля к каждой строке,
сохраненной в базе данных. Поле 6-byte DB_TRX_ID
указывает на
операционный идентификатор для последней транзакции, которая вставила или
обновила строку. Кроме того, удаление обработано внутренне как обновление,
где специальный бит в строке установлен, чтобы отметить ее как удаленную.
Каждая строка также содержит 7 байтов DB_ROLL_PTR
указателя
пересчета. Он указывает на запись журнала отмены, записанную в сегмент
отмены. Если строка была обновлена, запись журнала отмены содержит
информацию, необходимую, чтобы восстановить контент строки прежде, чем это
было обновлено. 6 байтов DB_ROW_ID
содержит ID строки,
который увеличивается монотонно, по мере вставки новых строк. Если
InnoDB
производит кластеризируемый индекс автоматически,
индексирование содержит значения идентификаторов строки. Иначе столбец
DB_ROW_ID
не появляется ни в каком индексе.
Отмена входит в систему, сегмент отмены разделен на журналы отмены
вставки и обновления. Журналы отмены вставки необходимы только в операционной
отмене и могут быть стерты, как только транзакция передана. Журналы отмены
обновления используются также в последовательных чтениях, но от них можно
отказаться только после того, как нет никакой транзакции, к которой
InnoDB
назначил снимок, который в последовательном чтении мог
нуждаться в информации в журнале отмены обновления, чтобы создать более
раннюю версию строки базы данных.
Передавайте свои транзакции регулярно, включая те транзакции, которые
используют только последовательные чтения. Иначе InnoDB
не сможет отказаться от данных журналов отмены обновления, и сегмент отмены
может стать слишком большим, заполняя Ваше табличное пространство.
Физический размер записи журнала отмены в сегменте отмены как правило меньше чем соответствующая вставленная или обновленная строка. Вы можете использовать эту информацию, чтобы вычислить пространство, необходимое для Вашего сегмента отмены.
В мультиверсионной схеме InnoDB
строка физически немедленно не удалена из базы данных, когда Вы удаляете это
запросом SQL. InnoDB
физически удаляет соответствующую строку и
индексные записи только когда отказывается от записи журнала отмены
обновления, записанной для удаления. Эту работу удаления называют
чисткой и она довольно быстра, обычно
берет тот же самый порядок времени, как запрос SQL, который сделал удаление.
Если Вы вставляете и удаляете строки в небольших пакетах на приблизительно
том же самом уровне в таблице, поток чистки может начать отставать, и таблица
может стать больше и больше из-за
стертых строк, делая работу с диском очень
медленной. В таком случае приостановите новые операции строк и выделите
больше ресурсов потоку чистки, настраивая переменную
innodb_max_purge_lag
. См. раздел 16.13.
InnoDB
multiversion concurrency control (MVCC)
обрабатывает вторичный индекс по-другому, чем кластеризируемый. Записи в
кластеризируемом индексе обновлены оперативнее, и их скрытые системные записи
журнала отмены указывают на столбцы, от которых могут быть восстановлены
более ранние версии записи. В отличие от кластеризируемого индекса,
записи вторичного индекса не содержат скрытые системные столбцы.
Когда столбец вторичного индекса обновлен, старые записи вторичного
индекса, отмеченные как удаленные, удаляются, новые вставлены и отмеченные
как удаленные в конечном счете очищены. Когда запись вторичного индекса
отмечена как удаленная или индексная страница обновлена более новой
транзакцией, InnoDB
ищет запись базы данных в кластеризируемом
индексе. Там запись DB_TRX_ID
проверена и правильная версия
получена от журнала отмены, если запись была изменена после того, как
транзакция чтения была начата.
Если запись вторичного индекса помечена для удаления или индексная
страница обновлена более новой транзакцией, метод
индексного покрытия
не используется. Вместо этого, чтобы возвратить значения из индекса структуры
InnoDB
ищет запись в кластеризируемом индексе.
Однако, если оптимизация
index
condition pushdown (ICP) разрешена, и часть выражения WHERE
может быть оценена, используя только поля индекса, сервер MySQL передает
эту часть WHERE
механизму хранения, где это оценено, используя
индексирование. Если никакие записи соответствия не найдены, поиск по
кластеризируемому индексу не проводится. Если соответствие найдено, даже
среди отмеченных для удаления, InnoDB
ищет
запись в кластеризируемом индексе.
Этот раздел обеспечивает введение в главные компоненты архитектуры
механизма хранения InnoDB
.
Буферный пул область в основной памяти, где InnoDB
кэширует
таблицы и индексы, с которыми работает. Буферный пул позволяет часто
используемым данным быть обработанными непосредственно в памяти, что ускоряет
обработку. На специализированных серверах базы данных до 80% физической
памяти часто назначаются буфрному пулу InnoDB
.
Для эффективности большого объема операций чтения буферный пул разделен на страницы, которые могут потенциально содержать много строк. Для эффективности управления кэшем буферный пул осуществлен как связанный список страниц, данные, которые редко используются, удаляются из кэша, используя вариант алгоритма LRU.
Подробности в разделе 16.6.3.
Буфер изменения специальная структура данных, которая кэширует изменения в
страницах вторичного индекса,
когда затронутые страницы не находятся в
буферному пуле.
Буферизованные изменения, которые могут следовать из операций
INSERT
,
UPDATE
или
DELETE
(DML), слиты позже, когда
страницы загружены в буферный пул другими операциями чтения.
В отличие от кластеризируемого индекса, вторичный индекс обычно групповой, и вставки во вторичный индекс происходят в относительно случайном порядке. Точно так же удаления и обновления могут затронуть вторичные индексные страницы, которые рядом не расположены в индексном дереве. Слияние кэшируемых изменений идет в более позднее время, когда затронутые страницы считаны в буферный пул другими операциями, это позволяет избегать существенного ввода/вывода произвольного доступа, который был бы обязан читать вторичные индексные страницы с диска.
Периодически чистка, которая работает, когда система главным образом неактивна, или во время медленного завершения работы, пишет обновленные индексные страницы на диск. Работа чистки может записать дисковые блоки для серии индексируемых значений более эффективно, чем если бы каждое значение было немедленно написано на диск.
Буферное слияние изменения может занять несколько часов, когда есть много вторичных индексов, чтобы обновить, и много затронутых строк. В это время дисковый ввод/вывод увеличен, что может вызвать существенное замедление для запросов к диску. Слияние буферных изменений может также продолжить происходить после того, как транзакция передана. Фактически, слияние буферных изменений может продолжить происходить после завершения работы сервера и перезапуска (см. раздел 16.20.2 ).
В памяти буфер изменения занимает часть буферного пула InnoDB
.
На диске буфер изменения часть системного табличного пространства, так что
индексные изменения остаются буферизованными между перезапусками базы данных.
Типом данных, кэшируемых в буфере изменения, управляет параметр
конфигурации
innodb_change_buffering
. Плдробности в
разделе 16.6.4.
Вы можете также сконфигурировать максимальный размер буфера изменения. Для
получения дополнительной информации см.
раздел 16.6.4.1.
Следующие опции доступны для контроля буфера изменения:
InnoDB
Standard Monitor включает информацию о статусе
для буфера изменения. Чтобы смотреть данные монитора, скомандуйте
SHOW ENGINE INNODB STATUS
.
mysql> SHOW ENGINE INNODB STATUS\G
Буферная информация о статусе изменения расположена под заголовком
INSERT BUFFER AND ADAPTIVE HASH INDEX
и выглядит так:
------------------------------------- INSERT BUFFER AND ADAPTIVE HASH INDEX ------------------------------------- Ibuf: size 1, free list len 0, seg size 2, 0 merges merged operations: insert 0, delete mark 0, delete 0 discarded operations: insert 0, delete mark 0, delete 0 Hash table size 4425293, used cells 32, node heap has 1 buffer(s) 13577.57 hash searches/s, 202.47 non-hash searches/s
Подробности в разделе 16.16.3.
INFORMATION_SCHEMA.INNODB_METRICS
обеспечивает большинство точек
данных, найденных в InnoDB
Standard Monitor плюс другие точки
данных. Чтобы рассмотреть буферные метрики изменения и описание каждой,
дайте следующий запрос:
mysql> SELECT NAME, COMMENT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE '%ibuf%'\G
Подробности об использовании таблицы
INNODB_METRICS
см. в разделе
16.14.6.
INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
обеспечивает метаданные о каждой странице в буферном пуле,
включая индекс буфера изменений и бит-карту страниц буфера изменений.
Буферные страницы изменения идентифицированы
PAGE_TYPE
. IBUF_INDEX
тип страницы для
буферных индексных страниц и IBUF_BITMAP
бит-карты страниц буфера изменений.
Запрос таблицы
INNODB_BUFFER_PAGE
может потребовать существенной работы.
Чтобы избежать воздействовать на работу, воспроизведите проблему, которую Вы
хотите исследовать, и выполните Ваши запросы на испытательном экземпляре.
Например, Вы можете запросить таблицу
INNODB_BUFFER_PAGE
, чтобы определить приблизительное количество страниц
IBUF_INDEX
и IBUF_BITMAP
как процент полных буферных страниц пула.
SELECT (SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE WHERE PAGE_TYPE LIKE 'IBUF%') AS change_buffer_pages, (SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE) AS total_pages, (SELECT ((change_buffer_pages/total_pages)*100)) AS change_buffer_page_percentage; +---------------------+-------------+-------------------------------+ | change_buffer_pages | total_pages | change_buffer_page_percentage | +---------------------+-------------+-------------------------------+ | 25 | 8192 | 0.3052 | +---------------------+-------------+-------------------------------+
Для информации о других данных, обеспеченных таблицей
INNODB_BUFFER_PAGE
, см. раздел 22.30.1.
Для связанной информации об использовании см.
раздел
16.14.5.
mysql> SELECT * FROM performance_schema.setup_instruments WHERE NAME LIKE '%wait/synch/mutex/innodb/ibuf%'; +-------------------------------------------------------+---------+-------+ | NAME | ENABLED | TIMED | +-------------------------------------------------------+---------+-------+ | wait/synch/mutex/innodb/ibuf_bitmap_mutex | YES | YES | | wait/synch/mutex/innodb/ibuf_mutex | YES | YES | | wait/synch/mutex/innodb/ibuf_pessimistic_insert_mutex | YES | YES | +-------------------------------------------------------+---------+-------+
Для информации о контроле ожиданий InnoDB
mutex см.
раздел
16.15.2.
Адаптивный хеш-индекс
(AHI) позволяет InnoDB
выступить больше как база данных в памяти
на системах с соответствующими комбинациями рабочей нагрузки и вполне
достаточной памяти для буферного
пула, не жертвуя никакими особенностями или надежностью. Эта опция
активирована опцией
innodb_adaptive_hash_index
или выключена при старте сервера
параметром --skip-innodb_adaptive_hash_index
.
Основанный на наблюдаемом образце поисков, MySQL создает хеш, индексиря использование префикса ключа индекса. Префикс ключа может быть любой длины, и может случиться так, что только некоторые из значений в B-дереве появляются в хеш-индексе. Хеш-индекс создан по требованию для тех страниц индекса, к которым часто получают доступ.
Если таблица почти полностью расположена в основной памяти, хеш-индекс
может ускорить запросы, включая прямой поиск любого элемента, разворачивая
значение в своего рода указатель. InnoDB
имеет механизм, который отслеживает поиски в индексе. Если
InnoDB
находит, которые запросы могли получить пользу из
создания хеш-индекса, это делается автоматически.
С некоторыми рабочими нагрузками
ускорение от хеш-индекса очень перевешивает дополнительную работу, чтобы
контролировать индекные поиски и поддерживать структуру. Иногда блокировка
чтения-записи, которая контролирует доступ к адаптивному хешу
может стать источником проблем при тяжелых рабочих нагрузках, таких как
многократные параллельные соединения. Запросы с операторами
LIKE
и подстановочными знаками %
также имеют тенденцию не извлекать выгоду из AHI. Для рабочих нагрузок, где
адаптивный хеш не нужен, выключение его уменьшает ненужную работу. Поскольку
трудно предсказать заранее, является ли эта особенность подходящей для особой
системы, считайте рабочие точки отсчета с включенным и отключенным хэшем,
используя реалистическую рабочую нагрузку. Архитектурные изменения в MySQL
5.6 и выше делают больше рабочих нагрузок подходящими для того, чтобы
запретить адаптивный хеш, чем в более ранних выпусках, хотя это все еще
включено по умолчанию.
Адаптивный хеш индекс разделен. Каждый индекс связан с определенным
разделением, и каждое разделение защищено отдельным замком. Разделением
управляет опция
innodb_adaptive_hash_index_parts
.
По умолчанию это 8. Максимум 512.
Хеш-индекс всегда создается основанный на существующем индексе
B-tree для таблицы.
InnoDB
может создать хеш-индекс на префиксе любой длины ключа,
определенного для B-дерева, в зависимости от образца поисков, который
InnoDB
наблюдает для индекса B-дерева. Хеш-индекс
может быть частичным, покрывая только те страницы индексирования, к которым
часто получают доступ.
Вы можете контролировать использование адаптивного хеш-индекса
и утверждение для его использования в разделе SEMAPHORES
вывода команды SHOW ENGINE INNODB STATUS
. Если Вы видите, что много потоков ждут на RW-замке, создаваемом
в btr0sea.c
, тогда могло бы быть полезно отключить
адаптивную хеш-индексацию.
Подробности в разделе 9.3.8.
Буфер журнала Redo область памяти, которая хранит данные, которые записаны
в журнал redo. Размер буфера
журнала, определен опцией
innodb_log_buffer_size
. Буфер журнала периодически
сбрасывается к файлу системного журнала на диске. Большой буфер
позволяет большим транзакциям работать без потребности записать
журнал на диск прежде, чем транзакции передадут. Таким образом, если у Вас
есть транзакции, которые обновляют, вставляют или удаляют много строк,
увеличение буфера экономит дисковый ввод/вывод.
Опция
innodb_flush_log_at_trx_commit
управляет, как содержание
буфера журнала записано в файл системного журнала. Опция
innodb_flush_log_at_timeout
управляет тем, как часто
буфер сбрасывается на диск.
Системное табличное пространство InnoDB
содержит
словарь данных (метаданные для объектов InnoDB
),
область хранения для буфера doublewrite, буфер изменения
и журнал отмены. Системное табличное пространство также содержит таблицу и
индексные данные для любых создаваемых пользователем таблиц,
которые составлены в системном табличном пространстве. Системное табличное
пространство считают совместно используемым табличным пространством, так как
оно совместно использовано многими таблицами.
Системное табличное пространство представлено одним или более файлами с
данными. По умолчанию, один системный файл с данными, названный
ibdata1
, создается в каталоге MySQL data
.
Размером и числом системных файлов с данными управляет опция
innodb_data_file_path
.
Подробности в разделах 16.6.1 и 16.7.1.
Буфер doublewrite это область хранения, расположенная в системном
табличном пространстве, где InnoDB
пишет страницы, которые
сбрасываются из буферного пула InnoDB
прежде, чем страницы будут
записаны их надлежащим позициям в файле с данными. Только после сброса и
записи в буфер doublewrite, InnoDB
запишет страницы на их
надлежащие позиции. Если есть катастрофический отказ операционной системы,
подсистемы хранения или процесса
mysqld в середине записи страницы, InnoDB
может позже найти хорошую копию страницы в буфере doublewrite
во время восстановления катастрофического отказа.
Хотя данные всегда пишутся дважды, буфер doublewrite не требует вдвое
большего количества ввода/вывода или вдвое большего количества операций
ввода/вывода. Данные записаны в буфер doublewrite непосредственно как большой
последовательный кусок одним вызовом fsync()
.
Буфер doublewrite включен по умолчанию в большинстве случаев. Чтобы
отключить буфер doublewrite, надо установить опцию
innodb_doublewrite
в 0.
Если системные файлы табличного пространства (файлы ibdata
) расположены на устройствах Fusion-io, которые поддерживают
атомную запись буфер doublewrite автоматически отключен, и атомная запись
Fusion-io используются для всех файлов с данными. Поскольку буферная
установка doublewrite глобальна, буферизация doublewrite также отключена для
файлов с данными, находящихся на не Fusion-io аппаратных средствах.
Эта функция поддерживается только на аппаратных средствах Fusion-io
и включена только для Fusion-io NVMFS в Linux.
Чтобы в полной мере воспользоваться этой особенностью рекомендуется установка
innodb_flush_method
в O_DIRECT
.
Журнал отмены (или сегмент отмены) является областью хранения, которая хранит копии данных, измененных активными транзакциями. Если другая транзакция должна видеть оригинальные данные (как часть последовательной работы чтения), неизмененные данные получены от этой области хранения. По умолчанию эта область физически часть системного табличного пространства. Однако, журналы отмены могут также находиться в отдельных табличных пространствах отмены. Для получения дополнительной информации см. разделы 16.7.7 и 16.3.
InnoDB поддерживает 128 журналов отмены. Однако, 32 из 128 журналов отмены зарезервированы для временных табличных транзакций. Каждой транзакции, которая обновляет временную таблицу (исключая транзакции только для чтения) назначают два журнала отмены, один просто отмены, второй с поддержкой redo. Транзакции только для чтения получают один журнал отмены, поскольку транзакциям только для чтения разрешают изменить только временные таблицы.
Это оставляет 96 доступных журналов отмены, каждый из которых поддерживает до 1023 параллельных изменяющих данные транзакций, для полного предела приблизительно 96k параллельных изменяющих данные транзакций. 96K предела предполагает, что транзакции не изменяют временные таблицы. Если все изменяющие данные транзакции также изменяют временные таблицы, полный предел составляет приблизительно 32k параллельных транзакций изменения данных. Для получения дополнительной информации о журналах отмены, которые сохранены для временных табличных транзакций, см. раздел 16.4.11.1.
Опция
innodb_undo_logs
определяет число журналов
отмены, используемых InnoDB
.
Табличное пространство File-Per-Table однотабличное пространство, которое
создается в его собственном файле с данными, а не в системном табличном
пространстве. Таблицы составлены в табличных пространствах file-per-table,
когда включена опция
innodb_file_per_table
. Иначе таблицы InnoDB
составлены в системном табличном пространстве. Каждое табличное пространство
file-per-table представлено файлом данных .ibd
,
который создается в каталоге базы данных по умолчанию.
Табличные пространства per-table допускают форматы строк
DYNAMIC
и COMPRESSED
, которые поддерживают функции,
такие как хранение вне страницы для данных переменной длины и табличное
сжатие. Для информации об этих особенностях и о других преимуществах
табличных пространств file-per-table см.
раздел 16.7.4.
Совместно используемое InnoDB
табличное пространство
создано с помощью CREATE TABLESPACE
. Общие табличные пространства могут быть созданы за пределами
каталога данных MySQL, способны к хранению многих таблиц и поддерживают
таблицы всех форматов строк.
Таблицы добавлены к общему табличному пространству через
CREATE TABLE
или
tbl_name
... TABLESPACE [=]
tablespace_name
ALTER TABLE
.tbl_name
TABLESPACE [=]
tablespace_name
Табличное пространство отмены состоит из одного или более файлов,
содержащих журнал отмены.
Табличное пространство отмены создается только когда журнал отмены отделен от
системного табличного пространства, используя
опции
innodb_undo_tablespaces
и
innodb_undo_directory
.
Временное табличное пространство это табличное пространство для несжатых
временных таблиц и связанных объектов. Параметр конфигурации
innodb_temp_data_file_path
определяет относительный путь для
временного файла с данными табличного пространства. Если
innodb_temp_data_file_path
не задан, в каталоге данных создается
единственный авторасширяемый файл с данными в 12 МБ и именем
ibtmp1
. Временное табличное пространство обновлено при каждом
старте сервера и получает динамически произведенный ID пространства, который
помогает избежать конфликтов с существующими ID. Временное табличное
пространство не может находиться на сыром устройстве. Сервер не стартует,
если временное табличное пространство не может быть создано.
Временное табличное пространство удалено при нормальном завершении работы или прерванной инициализации. Временное табличное пространство не удалено, когда катастрофический отказ происходит. В этом случае администратор базы данных может удалить временное табличное пространство вручную или перезапустить сервер с той же самой конфигурацией, которая удаляет и обновляет временное табличное пространство.
Временные табличные журналы отмены используются для временных таблиц и
связанных объектов. Этот тип журнала
отмены не redo-журнал, поскольку временные таблицы не восстановлены во
время восстановления катастрофического отказа и не требуют такого журнала.
Временные табличные журналы отмены, однако, используются для отмены, в то
время как сервер работает. Этот специальный тип журнала позволяет обойтись
без redo-протоколов ввода/вывода для временных таблиц и связанных объектов.
Временные табличные журналы отмены находятся во временном табличном
пространстве. Значение по умолчанию: временный файл табличного пространства,
ibtmp1
, расположенный в каталоге данных по умолчанию и всегда
обновляется при запуске сервера. Определяемое пользователем местоположение
для временного файла табличного пространства может быть определено,
устанавливая опцию конфигурации
innodb_temp_data_file_path
.
32 сегмента отмены отведены для временных табличных журналов отмены для транзакций, которые изменяют временные таблицы и связанные объекты, что означает, что максимальное количество сегментов отмены, доступных для изменяющих данные транзакций, которые производят отчеты отмены, 96. С 96 доступными сегментами отмены предел параллельных изменяющих данные транзакциях составляет 96K. Для получения дополнительной информации см. разделы 16.3 и 16.8.7.
Журнал redo это основанная на диске структура данных, используемая во время восстановления катастрофического отказа, чтобы исправить данные, написанные неполными транзакциями. Во время нормального функционирования журнал кодирует просьбы изменить табличные данные, которые следуют из запросов SQL или вызовов низкого уровня API. Модификации, которые не закончили обновлять файлы с данными перед неожиданным завершением работы, переигрываются автоматически во время инициализации, прежде, чем соединения будут приняты. Для информации о роли журналов redo в восстановлении после катастрофического отказа см. раздел 16.17.1.
По умолчанию журнал физически представлен на диске как ряд файлов,
названных ib_logfile0
и ib_logfile1
. MySQL
пишет файлы системного журнала круговым способом. Данные в журнале
закодированы с точки зрения затронутых записей,
эти данные все вместе упоминаются как redo.
Проход данных через журнал представлен постоянно увеличивающимся значением
LSN.
Для соответствующей информации см.:
InnoDB
, как
ACID-совместимый механизм базы данных, сбрасывает
redo-журнал
транзакций прежде, чем это будет передано. InnoDB
использует
групповой commit, чтобы
сгруппировать много таких запросов вместе. Из-за этого
InnoDB
делает одну запись в файл журнала, чтобы выполнить
действие для многих транзакций, которые идут приблизительно в то же самое
время, значительно улучшая пропускную способность.
Для получения дополнительной информации об исполнении
COMMIT
и других действий с транзакциями см.
see раздел
9.5.2.
Чтобы осуществить крупномасштабное или очень надежное приложение базы
данных или настроить работу MySQL, важно понять блокировку и
операционную модель InnoDB
.
Этот раздел обсуждает несколько тем, связанных с блокировкой и операционной моделью, с которой Вы должны быть знакомы.
раздел 16.5.1
описывает типы блокировки, используемые InnoDB
.
autocommit
,
последовательные чтения без блокировки и блокирующие чтения.InnoDB
для различных запросов.InnoDB
применяет блокировку следующего ключа,
чтобы избежать призрачных строк.InnoDB
.
Этот раздел описывает типы блокировки, используемые InnoDB
.
InnoDB
реализует стандартные блокировки уровня строки,
где есть два типа блокировок,
совместно использованные
(S
) и
исключительные
(X
).
Совместно использованные
(S
) позволяют транзакции, которые держат
блокировку для чтения строки.
X
) позволяют транзакции, которые держат
блокировку для обновления или удаления строки.Если транзакция T1
держит совместно используемую
(S
) блокировку на строке r
,
тогда запросы от некоторой отличной транзакции T2
для блокировки на строке r
обработаны следующим образом:
Запрос T2
для S
можно
немедленно предоставить. В результате оба запроса
T1
и T2
держат S
на
r
.
T2
для X
нельзя немедленно предоставить.Если транзакция T1
держит исключительную
(X
) блокировку строки r
,
запрос от некоторой отличной транзакции T2
для блокировки любого типа на r
не может быть немедленно
предоставлен. Вместо этого транзакция T2
должна ждать, пока транзакция T1
выпустит
блокировку на строке r
.
InnoDB
допускает многократные блокировки степени
детализации, которые разрешают сосуществование блокировок на
уровне строки и соединяет все таблицы. Чтобы сделать блокировку на многих
уровнях степени детализации дополнительные типы блокировок, названных
блокировками намерения,
используются. Блокировки намерения это блокировки на уровне таблицы в
InnoDB
, которые указывают, какого типа блокировки (совместно
используемые или исключительные) транзакция потребует позже для строки в той
таблице. Есть два типа блокировок намерения, используемых в
InnoDB
(предположим, что транзакция T
требует
блокировку обозначенного типа на таблице t
):
Совместно использованное намерение (IS
): транзакция
T
намеревается установить блокировку
S
на отдельные строки в таблице t
.
IX
): транзакция
T
намеревается установить блокировку X
на какие-то строки.Например, SELECT ... LOCK IN SHARE MODE
поставит IS
, а
SELECT ... FOR UPDATE
поставит IX
.
Протокол блокировки намерения:
Прежде, чем транзакция может приобрести
S
на строку в таблице t
,
это должно сначала приобрести IS
или более сильную блокировку на t
.
X
на строку, это должно сначала приобрести IX
на
t
.Эти правила могут быть удобно получены в итоге посредством следующей матрицы совместимости типа блокировки.
X |
IX | S |
IS | |
---|---|---|---|---|
X | Конфликтуют | Конфликтуют | Конфликтуют | Конфликтуют |
IX | Конфликтуют | Совместимы | Конфликтуют | Совместимы |
S | Конфликтуют | Конфликтуют | Совместимы | Совместимы |
IS | Конфликтуют | Совместимы | Совместимы | Совместимы |
Блокировку предоставляют транзакции требования, если это совместимо с существующими блокировками, но не предоставляют, если это находится в противоречии с существующими блокировками. Тогда транзакция ждет, пока противоречивая существующая блокировка не будет выпущена. Если запрос блокировки находится в противоречии с существующей блокировкой и не может быть предоставлен, потому что он вызвал бы тупик, происходит ошибка.
Таким образом, блокировки намерения не блокируют ничего кроме полных
табличных запросов (например, LOCK TABLES ... WRITE
). Основная
цель IX
и IS
показать, что кто-то
блокирует строку или собирается заблокировать строку в таблице.
Блокировка записей это блокировка на индексной записи. Например,
SELECT c1 FOR UPDATE FROM t WHERE c1 = 10;
препятствует тому, чтобы любая другая транзакция вставила, обновила или
удалила строки, где значение t.c1
= 10
.
Такие блокировки всегда блокируют индексные записи, даже если таблица
определена без индекса. Для таких случаев InnoDB
создает кластеризируемый скрытый индекс и использует его. См.
раздел 16.8.8.
Блокировки промежутка это блокировка на промежутке между индексными
записями или блокировка на промежутке перед первой или после последней
индексной записью. Например, SELECT c1 FOR UPDATE FROM t WHERE c1
BETWEEN 10 and 20;
препятствует тому, чтобы другие транзакции вставили
значение 15
в столбец t.c1
независимо от того,
было ли уже какое-либо такое значение в столбце, потому что промежутки между
всеми существующими значениями в диапазоне заблокированы.
Промежуток может охватить одно значение, несколько значений или даже быть пустым.
Блокировки промежутка это часть компромисса между производительностью и параллелизмом и используются в некоторых операционных уровнях изоляции.
Блокировка промежутка не необходима для запросов, которые блокируют
строки, используя уникальный индекс, чтобы искать уникальную строку. Это не
включает случай, что условие поиска включает только некоторые столбцы
уникального многостолбцового индекса, в этом случае блокировка промежутка
действительно происходит. Например, если столбец id
имеет
уникальный индекс, следующий запрос использует только блокировку записи
индекса для строки с id
100, и не имеет значения, вставляют ли
другие сеансы строки в предыдущий промежуток:
SELECT * FROM child WHERE id = 100;
Если id
не индексирован или имеет неуникальный индекс, запрос
действительно блокирует предыдущий промежуток.
Также стоит отметить здесь, что противоречивые блокировки могут быть проведены на промежутке различными транзакциями. Например, транзакция A может держать совместно используемую блокировку промежутка (S-блокировка промежутка) на промежутке, в то время как транзакция B держит исключительную блокировку промежутка (X-блокировка промежутка) на том же самом промежутке. Причина, по которой позволены противоречивые блокировки промежутка, состоит в том, что если запись очищена из индекса, блокировки промежутка для записи, которые держат разные транзакции, должны быть слиты.
Блокировки промежутка в InnoDB
только мешают другим транзакциям вставить в промежуток. Они не препятствуют
тому, чтобы различные транзакции работали с ним как-то иначе. Таким образом,
X-блокировка промежутка имеет тот же самый эффект как S-блокировка.
Блокировка промежутка может быть отключена явно. Это происходит, если Вы
изменяете операционный уровень изоляции на
READ COMMITTED
.
При этих обстоятельствах блокировка промежутка отключена для поисков и
сканирований индексов и используется только для проверки ограничения внешнего
ключа и дублирования ключей.
Есть также другие эффекты использования уровня изоляции
READ COMMITTED
.
Блокировки записи для того, чтобы несоответствующие строки были
выпущены после того, как MySQL оценил WHERE
. Для
UPDATE
InnoDB
делает такое чтение, что это
возвращает последнюю переданную версию в MySQL так, чтобы MySQL мог
определить, соответствует ли строка WHERE
выражению в
UPDATE
.
Это комбинация блокировки записи на записи индекса и блокировки промежутка перед этой записью.
InnoDB
выполняет блокировку на уровне строки таким способом,
что когда это ищет или просматривает индекс таблицы, то устанавливает
совместно использованные или исключительные блокировки на индексных записях.
Таким образом, блокировки на уровне строки фактически блокировки индекса.
Блокировка следующего ключа также затрагивает
промежуток перед этой записью.
Если у одного сеанса есть совместно используемая или исключительная
блокировка на записи R
в индексе, другой сеанс не может вставить
новую индексную запись в промежутке сразу
перед R
в порядке индекса.
Предположите, что индекс содержит значения 10, 11, 13 и 20. Возможные блокировки для этого индекса покрывают следующие интервалы, где круглая скобка обозначает исключение конечной точки интервала, а квадратная скобка обозначает включение конечной точки:
(минус бесконечность, 10] (10, 11] (11, 13] (13, 20] (20, бесконечность)
Для последнего интервала это блокирует промежуток выше самого большого значения в индексе и виртуальную запись, имеющую значение выше, чем любое значение фактически в индексе. Такой записи на самом деле нет, таким образом, в действительности, это блокировка только промежутка после самого большого значения индекса.
По умолчанию InnoDB
работает на уровне изоляции
REPEATABLE READ
. В этом случае InnoDB
использует такую блокировку
для поисков и индексных просмотров, что предотвращает появление призрачных
строк (см. раздел 16.5.4).
Блокировки намерения вставки это тип блокировки промежутка, установленной
операцией INSERT
до вставки строки.
Эта блокировка сигнализирует намерение вставить таким способом, что
многие транзакции, вставляющие в то же самый промежуток, не должны ждать друг
друга, если они не вставляют в ту же самую позицию в пределах промежутка.
Предположите, что есть индексные записи со значениями 4 и 7. Отдельные
транзакции, которые пытаются вставить значения 5 и 6, соответственно, каждая
блокировка промежуток между 4 и 7 с блокировками намерения вставки до
получения исключительной блокировки на вставленной строке, но не блокируют
друг друга, потому что строки не находятся в противоречии.
Следующий пример демонстрирует транзакцию, берущую блокировку намерения вставки до получения исключительной блокировки на вставленной записи. Пример вовлекает двух клиентов A и B.
Клиент А составляет таблицу, содержащую две записи в индексе (90 и 102) и затем запускает транзакцию, которая помещает исключительную блокировку на записи индекса с ID больше 100. Исключительная блокировка включает блокировку промежутка перед записью 102:
mysql> CREATE TABLE child (id int(11) NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB; mysql> INSERT INTO child (id) values (90),(102); mysql> START TRANSACTION; mysql> SELECT * FROM child WHERE id > 100 FOR UPDATE; +-----+ | id | +-----+ | 102 | +-----+
Клиент B начинает транзакцию, чтобы вставить отчет в промежуток. Транзакция берет блокировку намерения вставки, в то время как она ждет, чтобы получить исключительную блокировку.
mysql> START TRANSACTION; mysql> INSERT INTO child (id) VALUES (101);
Чтобы рассмотреть данные о блокировке намерения вставки, выполните
SHOW ENGINE INNODB STATUS
.
Данные, подобные следующим, появляются под заголовком
TRANSACTIONS
:
mysql> SHOW ENGINE INNODB STATUS\G
...
SHOW ENGINE INNODB STATUS
---TRANSACTION 8731, ACTIVE 7 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 360, 1 row lock(s)
MySQL thread id 3, OS thread handle 0x7f996beac700, query id 30 localhost root update
INSERT INTO child (id) VALUES (101)
------- TRX HAS BEEN WAITING 7 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 31 page no 3 n bits 72 index `PRIMARY` of table `test`.`child`
trx id 8731 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 3 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
0: len 4; hex 80000066; ascf;;
1: len 6; hex 000000002215; asc " ;;
2: len 7; hex 9000000172011c; asc r ;;...
Блокировка AUTO-INC
это специальная блокировка на уровне
таблицы, взятая транзакциями, вставляющими в таблицы со столбцами
AUTO_INCREMENT
. В самом простом случае, если
одна транзакция вставляет значения в таблицу, любые другие транзакции должны
ждать, чтобы сделать их собственные вставки в эту таблицу так, чтобы строки,
вставленные первой транзакцией, получили последовательные
значения первичного ключа.
Параметр конфигурации
innodb_autoinc_lock_mode
управляет алгоритмом, используемым
для блокировки автоинкремента. Это позволяет Вам выбирать, как балансировать
между предсказуемыми последовательностями значений автоинкремента и
максимальным параллелизмом для операций вставки.
Подробности в разделе 16.8.5.
InnoDB
поддерживает индексацию столбцов с пространственными
данными (см. раздел 12.5.3.5
).
Чтобы обработать блокировку для вовлечения операций с индексами
SPATIAL
, блокировка следующего ключа не работает хорошо, чтобы
поддержать уровни изоляции
REPEATABLE READ
или
SERIALIZABLE
.
В многомерных данных нет никакого абсолютного понятия упорядочивания, таким
образом, не ясно, что является следующим ключом.
Чтобы обеспечить поддержку уровней изоляции для таблиц с индексами
SPATIAL
, InnoDB
применяет блокировки предиката.
Индекс SPATIAL
содержит минимальный ограничительный
прямоугольник (MBR) значения, таким образом, InnoDB
проводит в жизнь последовательное чтение на индексе, устанавливая предикат,
на значении MBR, используемом для запроса. Другие транзакции не могут
вставить или изменить строку, которая соответствовала бы условию запроса.
В транзакционной модели InnoDB
цель состоит в том, чтобы объединить лучшие свойства
мультиверсионной базы данных с
традиционной двухфазовой блокировкой. InnoDB
выполняет блокировку на уровне строки и выполняет запросы как
последовательные чтения
без блокировки по умолчанию в стиле Oracle. Информация о блокировке в
InnoDB
сохранена пространственно-эффективно так, чтобы
эскалация блокировки не была необходима. Как правило, нескольким
пользователям разрешают блокировать каждую строку таблицы
InnoDB
или любое случайное подмножество строк
без истощения памяти InnoDB
.
Операционная изоляция это одна из основ обработки базы данных. Изоляция это I в ACID, уровень изоляции это установка, которая точно настраивает баланс между работой и надежностью, последовательностью и воспроизводимостью результатов, когда многократные транзакции производят изменения и выполняют запросы в то же самое время.
InnoDB
реализует все четыре операционных уровня изоляции,
которые описаны стандартом SQL:1992:
READ UNCOMMITTED
, READ COMMITTED
, REPEATABLE
READ
и
SERIALIZABLE
. По умолчанию используется
REPEATABLE READ
.
Пользователь может изменить уровень изоляции для единственного сеанса или
для всех последующих соединений командой
SET TRANSACTION
.
Чтобы установить уровень изоляции по умолчанию сервера для всех соединений,
используйте параметр
--transaction-isolation
. Для получения дальнейшей информации
об уровнях изоляции и устанавливающем уровень синтаксисе см.
раздел 14.3.6.
InnoDB
реализует каждый из операционных уровней изоляции,
описанных здесь, используя различные стратегии
блокировки. Вы можете провести в
жизнь высокую степень последовательности с уровнем по умолчанию
REPEATABLE READ
, для операций на решающих данных, где совместимость с
ACID принципиальна.
Или Вы можете расслабить правила последовательности с
READ COMMITTED
или READ UNCOMMITTED
в ситуациях, где точная последовательность и повторимые
результаты менее важны, чем уменьшение количества издержек блокировки.
SERIALIZABLE
проводит в жизнь еще более строгие правила, чем
REPEATABLE READ
, и используется, главным образом, в специализированных ситуациях, таких
как транзакции XA и для того, чтобы
расследовать проблемы с параллелизмом и
тупиками.
Следующий список описывает, как MySQL поддерживает различные операционные уровни. Список идет от обычно используемого уровня до наименее используемого.
Это уровень изоляции значения по умолчанию для InnoDB
. Для
последовательных чтений
есть важное отличие от
READ COMMITTED
: все последовательные чтения в пределах той же
самой транзакции читают снимок, установленный первым чтением. Это соглашение
означает это, если Вы выпускаете несколько простых (без блокировки) запросов
SELECT
в пределах той же самой
транзакции, то эти SELECT
последовательны также друг относительно друга. См.
раздел 16.5.2.3.
Чтобы заблокировать чтения
(SELECT
с FOR UPDATE
или LOCK IN SHARE MODE
), UPDATE
и DELETE
,
блокировка зависит от того, использует ли запрос уникальный индекс с
уникальным условием поиска или условием поиска типа диапазона.
Если уникальный индекс с уникальным условием поиска, InnoDB
блокирует только найденные индексные записи, но не
промежуток перед этим. Для других
условий поиска InnoDB
блокирует индексный диапазон, используя
блокировки промежутка или
блокировки следующего ключа,
чтобы заблокировать вставки другими сеансами в
промежутки, покрытые диапазоном.
READ COMMITTED
Несколько подобный Oracle уровень изоляции относительно последовательных чтений (без блокировки): каждое последовательное чтение, даже в пределах той же самой транзакции, устанавливает и читает свой собственный новый снимок. См. раздел 16.5.2.3.
Для того, чтобы заблокировать
чтения (SELECT
с FOR
UPDATE
или LOCK IN SHARE MODE
),
UPDATE
и
DELETE
, InnoDB
блокирует только индексные записи, но не
промежутки перед ними, и таким образом разрешает свободную вставку новых
записей рядом с заблокированными.
В MySQL 8.0 при использовании READ COMMITTED
не применяется блокировка промежутка за исключением проверки ограничения
внешнего ключа и дубликата ключа. Кроме того, блокировки записи используются
для того, чтобы несоответствовующие строки были выпущены после того, как
MySQL оценил WHERE
.
Если Вы используете READ COMMITTED
, Вы
должны использовать основанное на
строке двоичное журналирование.
Запросы SELECT
выполнены способом без блокировки, но возможная более ранняя версия строки
могла бы использоваться. Таким образом, используя этот уровень изоляции,
такие чтения не последовательны. Это также называют
грязным чтением. Иначе этот
уровень изоляции работает как
READ COMMITTED
.
SERIALIZABLE
Похоже на REPEATABLE
READ
, но InnoDB
неявно конвертируется все простые
SELECT
в
SELECT ... LOCK IN SHARE MODE
,
autocommit
выключен.
Если же autocommit
включен, SELECT
выполняется в
собственной транзакции. Это только для чтения и может быть преобразовано в
последовательную форму, если выполнено как последовательное чтение (без
блокировки) и не должно заблокировать другие транзакции. Чтобы простой
SELECT
заблокировать, если другие
транзакции изменили выбранные строки, отключите
autocommit
.
В InnoDB
вся пользовательская деятельность происходит в
транзакции. Если режим
autocommit
включен, каждый запрос SQL формирует единственную
транзакцию самостоятельно. По умолчанию MySQL запускает сеанс для каждого
нового соединения с включенным
autocommit
, таким образом, MySQL делает передачу после каждого
запроса SQL, если запрос не возвращал ошибку. См.
раздел 16.20.4.
Сеанс, который имеет включенную опцию
autocommit
,
может выполнить транзакцию из многих запросов, запуская это с явной
командой START TRANSACTION
или
BEGIN
и завершая
COMMIT
или
ROLLBACK
. См.
раздел 14.3.1.
Если autocommit
выключен в пределах сеанса с помощью SET autocommit = 0
,
у сеанса всегда есть открытая транзакция.
COMMIT
или
ROLLBACK
заканчивает текущую транзакцию, и новая запускается.
Если сеанс, который имеет выключенный
autocommit
завершается, явно не передавая заключительную транзакцию, MySQL отменяет эту
транзакцию до прежнего состояния.
Некоторые запросы неявно заканчивают транзакцию, как будто Вы сделали
a COMMIT
. См.
раздел 14.3.3.
COMMIT
означает, что изменения,
сделанные в текущей транзакции, делаются постоянными и становятся видимыми
другим сеансам. ROLLBACK
отменяет все модификации, сделанные текущей транзакцией.
COMMIT
и
ROLLBACK
снимают все
блокировки, которые были установлены во время текущей транзакции.
По умолчанию соединение с сервером MySQL начинается с включенным режимом autocommit, который автоматически передает каждый запрос SQL, когда Вы выполняете это. Этот режим работы мог бы быть незнакомым, если у Вас есть опыт работы с другими системами базы данных, где общепринятой практикой является последовательность запросов DML и передача или отмена их все вместе.
Чтобы использовать транзакцию
из многих запросов, выключите режим командой SET autocommit = 0
и заканчивайте каждую транзакцию командой
COMMIT
или
ROLLBACK
.
Чтобы это сделать при включенном autocommit, начинайте каждую транзакцию с
START TRANSACTION
и заканчивайте
COMMIT
или
ROLLBACK
. Следующий пример
показывает две транзакции. Первая передана, вторая отменена.
shell> mysql test mysql> CREATE TABLE customer (a INT, b CHAR (20), INDEX (a)); Query OK, 0 rows affected (0.00 sec) mysql> -- Do a transaction with autocommit turned on. mysql> START TRANSACTION; Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO customer VALUES (10, 'Heikki'); Query OK, 1 row affected (0.00 sec) mysql> COMMIT; Query OK, 0 rows affected (0.00 sec) mysql> -- Do another transaction with autocommit turned off. mysql> SET autocommit=0; Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO customer VALUES (15, 'John'); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO customer VALUES (20, 'Paul'); Query OK, 1 row affected (0.00 sec) mysql> DELETE FROM customer WHERE b = 'Heikki'; Query OK, 1 row affected (0.00 sec) mysql> -- Now we undo those last 2 inserts and the delete. mysql> ROLLBACK; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM customer; +----+--------+ | a | b | +----+--------+ | 10 | Heikki | +----+--------+ 1 row in set (0.00 sec) mysql>
В таких API, как PHP, Perl DBI, JDBC, ODBC или обычный интерфейс C
Вы можете послать команду управления транзакцией серверу
как строку точно так же, как любые другие запросы SQL, такие как
SELECT
или
INSERT
. Некоторые API
также предлагает отдельные специальные функции или методы.
Последовательное чтение
означает, что InnoDB
использует мультиверсии, чтобы представить
запросу снимок базы данных в момент времени. Запрос видит изменения,
произведенные транзакциями, которые передали перед тем моментом времени, но
никаких изменений, произведенных позже или нейтральными транзакциями.
Исключение: запрос видит изменения, произведенные более ранними запросами в
пределах той же самой транзакции. Это исключение вызывает следующую аномалию:
если Вы обновляете некоторые строки в таблице,
SELECT
видит последнюю версию обновленных строк, но мог бы также видеть более старые
версии любых строк. Если другие сеансы одновременно обновляют ту же самую
таблицу, аномалия означает, что Вы могли бы видеть таблицу в статусе, который
никогда не существовал в базе данных.
Если операционный уровень
изоляции REPEATABLE
READ
(по умолчанию), все последовательные чтения в пределах той же
самой транзакции читают снимок, установленный первым таким чтением в этой
транзакции. Вы можете получить более новый снимок для своих запросов,
передавая текущую транзакцию и выдавая новые запросы.
На уровне READ
COMMITTED
каждое последовательное чтение в пределах транзакции
устанавливает и читает свой собственный новый снимок.
Последовательное чтение это режим по умолчанию, в котором
InnoDB
обрабатывает запросы
SELECT
на уровнях
READ COMMITTED
и REPEATABLE READ
. Последовательное чтение не устанавливает блокировок на
таблицы, к которым оно получает доступ, и поэтому другие сеансы свободны
изменить те таблицы в то же самое время, когда последовательное чтение
выполняется на таблице.
Предположите, что Вы работаете на уровне
REPEATABLE READ
. Когда Вы выпускаете последовательное чтение (то есть, одиночный
SELECT
), InnoDB
дает Вашей транзакции точку времени, согласно которой Ваш запрос видит базу
данных. Если другая транзакция удаляет строку и передает после того, как Ваша
точка была назначена, Вы не видите строку как удаленную. Вставки и обновления
обработаны так же.
Снимок базы данных относится к
SELECT
в пределах транзакции, не обязательно к запросам
DML. Если Вы вставляете или изменяете
некоторые строки и затем передаете транзакцию, запросы
DELETE
или
UPDATE
от другой параллельной
транзакции REPEATABLE READ
могут затронуть те переданные строки, даже при том, что сеанс не мог
запросить их. Если транзакция действительно обновляет или удаляет строки,
переданные иной транзакцией, те изменения действительно становятся видимыми к
текущей транзакции. Например, Вы могли бы столкнуться с такой ситуацией:
SELECT COUNT(c1) FROM t1 WHERE c1 = 'xyz'; -- Returns 0: no rows match. DELETE FROM t1 WHERE c1 = 'xyz'; -- Deletes several rows recently committed by other transaction. SELECT COUNT(c2) FROM t1 WHERE c2 = 'abc'; -- Returns 0: no rows match. UPDATE t1 SET c2 = 'cba' WHERE c2 = 'abc'; -- Affects 10 rows: another txn just committed 10 rows with 'abc' values. SELECT COUNT(c2) FROM t1 WHERE c2 = 'cba'; -- Returns 10: this txn can now see the rows it just updated.
Вы можете обновить точку времени, передавая Вашу транзакцию и затем делая
другой запрос SELECT
или
START TRANSACTION WITH CONSISTENT SNAPSHOT
.
В следующем примере сеанс A видит строку, вставленную B, только когда B передал вставку, а A передал также, чтобы точка времени обновилась.
Сеанс A Сеанс B SET autocommit=0; SET autocommit=0; time | SELECT * FROM t; | empty set | INSERT INTO t VALUES (1, 2); | v SELECT * FROM t; empty set COMMIT; SELECT * FROM t; empty set COMMIT; SELECT * FROM t; --------------------- | 1 | 2 | ---------------------
Если Вы хотите видеть свежее состояние
базы данных, используйте любой уровень изоляции
READ COMMITTED
или блокировку чтения:
SELECT * FROM t LOCK IN SHARE MODE;
На уровне READ
COMMITTED
каждое последовательное чтение в пределах транзакции
устанавливает и читает свой собственный новый снимок. С LOCK IN SHARE
MODE
блокировка чтения происходит вместо этого: SELECT
блокирует до транзакции, содержащей самые новые концы строк (см.
раздел 16.5.2.4).
Последовательное чтение не работает по определенным запросам DDL:
Последовательное чтение не работает через
DROP TABLE
, поскольку MySQL
не может использовать таблицу, которая была удалена, а InnoDB
разрушает эту таблицу.
ALTER TABLE
, так как
запрос делает временную копию оригинальной таблицы и удаляет оригинальную
таблицу, когда временная копия создана. Когда Вы используете последовательное
чтение в пределах транзакции, строки в новой таблице невидимы, потому что те
строки не существовали, когда снимок транзакции был взят.
В этом случае транзакция возвращает ошибку:
ER_TABLE_DEF_CHANGED
, Table definition has changed,
please retry transaction.Тип чтения изменяется для выбора в запросах
INSERT INTO ... SELECT
,
UPDATE ... (SELECT)
и
CREATE TABLE ... SELECT
,
которые не определяют FOR UPDATE
или
LOCK IN SHARE MODE
:
По умолчанию InnoDB
использует более сильные
блокировки и SELECT
действует как
READ COMMITTED
,
где каждое последовательное чтение, даже в пределах той же самой транзакции,
устанавливает и читает свой собственный новый снимок.
READ UNCOMMITTED
,
READ COMMITTED
или REPEATABLE READ
(то есть, что-либо кроме
SERIALIZABLE
).
В этом случае никакие блокировки не установлены на строках, считанных
из выбранной таблицы.Если Вы запрашиваете данные и затем вставляете или обновляете связанные
данные в пределах той же самой транзакции, запрос SELECT
не дает достаточную защиту. Другие транзакции могут обновить или удалить те
же самые строки, которые Вы только что запросили.
InnoDB
понимает два типа
блокировки чтений, которые
предлагают дополнительную безопасность:
SELECT ... LOCK IN SHARE MODE
задает совместно используемый режим блокировки на
любые строки, которые считаны. Другие сеансы могут считать строки, но не
могут изменить их, пока Ваша транзакция не передается. Если какая-либо из
этих строк была изменена другой транзакцией, которая еще не передалась, Ваш
запрос ждет ее завершения и затем использует последние значения.
SELECT ... FOR UPDATE
блокирует
строки и любые связанные записи в индексе, как будто была команда
UPDATE
для тех строк. Другие транзакции заблокированы на
обновление тех строк из SELECT ...
LOCK IN SHARE MODE
или от чтения данных в определенных
операционных уровнях изоляции. Последовательные чтения игнорируют любой набор
блокировок на записях, которые существуют в представлении чтения. Старые
версии записи не могут быть заблокированы: они восстановлены, применяя
журнал отмены
к копии записи в памяти.Эти пункты прежде всего полезны, имея дело со структурированными деревом или структурированными данными графика в единственной таблице или в разделении на несколько таблиц. Вы пересекаете края или ответвления дерева от одного места до другого, резервируя право возвратиться и изменить любой из этих указателей.
Все блокировки, установленные LOCK IN SHARE MODE
и
FOR UPDATE
выпущены, когда транзакция передана или отменена.
Блокировка строк для использования обновления SELECT FOR UPDATE
применяется, когда autocommit отключен любым способом
(START TRANSACTION
или установкой
autocommit
в 0). Если
autocommit включен, строки, соответствующие спецификации, не заблокированы.
Предположите, что Вы хотите вставить новую строку в таблицу
child
и удостоверьтесь, что дочерняя строка имеет родительскую
строку в таблице parent
. Ваш код программы может гарантировать
ссылочную целостность всюду по этой последовательности операций.
Во-первых, используйте последовательное чтение, чтобы запросить таблицу
PARENT
и проверьте, что родительская строка существует. Можете
Вы безопасно вставлять дочернюю строку в таблицу CHILD
?
Нет, потому что некоторый другой сеанс мог удалить родительскую строку в
момент между Вашими SELECT
и INSERT
.
Чтобы избежать этой потенциальной проблемы, используйте
SELECT
с
LOCK IN SHARE MODE
:
SELECT * FROM parent WHERE NAME = 'Jones' LOCK IN SHARE MODE;
После LOCK IN SHARE MODE
запрос возвращает
'Jones'
, который Вы можете безопасно добавить в дочернюю
запись в таблице CHILD
и передать транзакцию. Любая транзакция,
которая пытается приобрести исключительную блокировку в применимой строке в
таблице PARENT
ждет, пока Вы не закончите, то есть, пока данные
во всех таблицах не находятся в последовательном статусе.
Для другого примера, рассмотрите область счетчика целого числа в таблице
таблице CHILD_CODES
, используемую, чтобы назначить уникальный
идентификатор каждому дочернему элементу в таблице CHILD
.
Не используйте последовательное чтение или совместно используемое чтение,
чтобы считать текущее значение счетчика, потому что два пользователя базы
данных могли видеть то же самое значение счетчика, и происходит ошибка
дублирования ключа, если две транзакции пытаются добавить строки с тем же
самым идентификатором к CHILD
.
Здесь LOCK IN SHARE MODE
плохое решение, потому что, если два
пользователя читают счетчик в то же самое время, по крайней мере один из них
заканчивает в тупике, когда пытается обновить счетчик.
Чтобы осуществить чтение и постепенное увеличение счетчика, сначала
выполните блокировку чтения счетчика через FOR UPDATE
,
а затем увеличьте счетчик. Например:
SELECT counter_field FROM child_codes FOR UPDATE; UPDATE child_codes SET counter_field = counter_field + 1;
SELECT ... FOR UPDATE
читает
последние доступные данные, устанавливая исключительные блокировки на каждой
строке, которую читает. Таким образом, это устанавливает те же самые
блокировки, какие ищущий UPDATE
установил бы на строках.
Предыдущее описание просто пример того, как работает
SELECT ... FOR UPDATE
. В MySQL
определенная задача производства уникального идентификатора фактически может
быть выполнена, используя только единственный доступ к таблице:
UPDATE child_codes SET counter_field = LAST_INSERT_ID(counter_field + 1); SELECT LAST_INSERT_ID();
SELECT
просто получает
информацию об идентификаторе (определенном для текущего соединения).
Это не получает доступ ни к какой таблице.
Блокировка чтения,
UPDATE
или
DELETE
вообще устанавливают блокировки записи на каждой записи индекса, которая
просмотрена в обработке запроса SQL. Не имеет значения, есть ли условие
WHERE
в запросе, которое исключило бы строку.
InnoDB
не помнит точное выражение WHERE
, а только
знает, которые индексные диапазоны, были просмотрены. Блокировки обычно
следующего ключа, которые
также блокируют промежуток сразу перед записью.
Однако, блокировка промежутка
может быть отключена явно, что заставляет блокировку следующего ключа не
использоваться. Подробности в разделе
16.5.1. Операционный уровень изоляции также может затронуть, какие
блокировки установлены, см.
раздел 14.3.6.
Если вторичный индекс используется в поиске, и блокировки индексной
записи, которые будут установлены, исключительны, InnoDB
также получает соответствующие записи кластеризируемого индекса и ставит
на них блокировки.
Различия между совместно используемыми и исключительными блокировками описаны в разделе 16.5.1.
Если Вы не имеете индекса, подходящего для Вашего запроса, и MySQL должен просмотреть всю таблицу, чтобы обработать запрос, каждая строка таблицы становится заблокированной, что в свою очередь блокирует все вставки другими пользователями в таблицу. Важно создать хороший индекс так, чтобы Ваши запросы не просматривали слишком много строк.
Для SELECT ... FOR UPDATE
или
SELECT ... LOCK IN SHARE MODE
блокировки приобретены для просмотренные строки и, как ожидают, будут
выпущены для строк, которые не имеют право на включение в набор результатов
(например, если они не соответствуют критериям, поданным в
WHERE
). Однако, в некоторых случаях, строки нельзя было бы
немедленно разблокировать, потому что отношения между строкой результата и ее
первоисточником потеряны во время выполнения запроса. Например, в
UNION
просмотренные (и
заблокированные) строки могли бы быть вставлены во временную таблицу перед
оценкой, имеют ли они право на набор результатов. При этом потеряны отношения
строк во временной таблице к строкам в оригинальной таблице, и последние
строки не разблокируют до конца выполнения запроса.
InnoDB
устанавливает типы блокировок следующим образом.
SELECT ... FROM
последовательное чтение, читая снимок базы данных и не устанавливая
блокировок, если операционный уровень изоляции не установлен в
SERIALIZABLE
.
Для уровня SERIALIZABLE
поиск ставит совместно использованные блокировки следующего
ключа на индексные записи.
SELECT ... FROM ... LOCK IN SHARE MODE
ставит совместно использованные блокировки следующего ключа на
все индексные записи, используемые поиском.SELECT ... FROM ... FOR UPDATE
блокирует другие сеансы от выполнения
SELECT ... FROM ... LOCK IN SHARE MODE
или чтения в определенных операционных уровнях изоляции.
Последовательные чтения проигнорируют любой набор блокировок на записях,
которые существуют в представлении чтения.UPDATE ... WHERE ...
ставит
исключительную блокировку следующего ключа на каждой
записи столкновения поиска.UPDATE
меняет
запись в кластеризируемом индексе, неявные блокировки взяты на
затронутых записях вторичного индекса.
UPDATE
также ставит
совместно использованные блокировки на затронутые записи вторичного индекса,
когда выполняется проверка на дубликаты до вставки новых записей вторичного
индекса и когда происходит собственно вставка новых
записей вторичного индекса.DELETE FROM ... WHERE ...
ставит исключительную блокировку следующего ключа на каждую запись поиска.
INSERT
ставит исключительную
блокировку на вставленной строке. Эта блокировка на самом деле блокирует
запись индекса, а не следующий ключ (то есть, нет никакой блокировки
промежутка), и не препятствует тому, чтобы другие сеансы вставили в
промежуток перед вставленной строкой.
До вставки строки блокировка промежутка вызывает установку блокировки промежутка намерения вставки. Эта блокировка сигнализирует намерение вставить таким способом, что многократные транзакции, вставляющие в тот же самый промежуток, не должен ждать друг друга, если они не вставляют в той же самой позиции в пределах промежутка. Предположите, что есть индексные записи со значениями 4 и 7. Отдельные транзакции, которые пытаются вставить значения 5 и 6 блокируют промежуток между 4 и 7 с блокировками намерения вставки до получения исключительной блокировки на вставленной строке, но не заблокируют друг друга, потому что строки не находятся в противоречии.
Если происходит ошибка дублирования ключа, совместно используемая
блокировка на дубликате индексной записи установлена. Это использование
совместно используемой блокировки может привести к тупику, когда есть
многократные сеансы, пытающиеся вставить ту же самую строку, если у другого
сеанса уже есть исключительная блокировка. Это может произойти, если другой
сеанс удаляет строку. Предположите, что таблица InnoDB
t1
имеет следующую структуру:
CREATE TABLE t1 (i INT, PRIMARY KEY (i)) ENGINE = InnoDB;
Теперь предположите, что три сеанса выполняют следующие операции в порядке:
Сеанс 1:
START TRANSACTION; INSERT INTO t1 VALUES(1);
Сеанс 2:
START TRANSACTION; INSERT INTO t1 VALUES(1);
Сеанс 3:
START TRANSACTION; INSERT INTO t1 VALUES(1);
Сеанс 1:
ROLLBACK;
Сначала сеанс 1 приобретает исключительную блокировку на строку. Сеансы 2 и 3 получают ошибку дубликата ключа и они оба просят совместно используемую блокировку для строки. Когда сеанс 1 откатывается, он выпускает свою исключительную блокировку на строке, и запросы совместно используемой блокировки сеансами 2 и 3 удовлетворены. Вот здесь 2 и 3 в тупике: ни один не может приобрести исключительную блокировку на строке из-за совместно используемой блокировки, проводимой другим.
Подобная ситуация происходит, если таблица уже содержит строку со значением ключа 1, и три сеанса выполняют следующие операции в порядке:
Сеанс 1:
START TRANSACTION; DELETE FROM t1 WHERE i = 1;
Сеанс 2:
START TRANSACTION; INSERT INTO t1 VALUES(1);
Сеанс 3:
START TRANSACTION; INSERT INTO t1 VALUES(1);
Сеанс 1:
COMMIT;
Сеанс 1 приобретает исключительную блокировку на строке. Сеансы 2 и 3 получают ошибку дубликата ключа и оба требуют совместно используемую блокировку для строки. Когда сеанс 1 передает транзакцию, он выпускает свою исключительную блокировку на строке, и совместно используемые запросы блокировки 2 и 3 удволетворены. В итоге 2 и 3 в тупике: ни один не может приобрести исключительную блокировку на строку из-за совместно используемой блокировки, проводимой другим.
INSERT ... ON DUPLICATE KEY
UPDATE
отличается от простого
INSERT
использованием исключительной блокировки следующего ключа вместо
совместно используемой блокировки на строке, которая будет обновлена, когда
происходит ошибка дубликата ключа.REPLACE
сделан как
INSERT
,
если нет никакого столкновения на уникальном ключе. Иначе исключительная
блокировка следующего ключа помещена на строку, которая будет заменена.INSERT INTO T SELECT ... FROM S WHERE ...
ставит
исключительную блокировку индексной записи (без блокировки промежутка) на
каждой строке, вставленной в T
. Если операционный уровень
изоляции
READ COMMITTED
, InnoDB
делает поиск на
S
как последовательное чтение (никакие блокировки не
применяются). Иначе InnoDB
ставит совместно используемую
блокировку следующего ключа на строках из S
. InnoDB
должен установить блокировки в последнем случае: в восстановлении
после резервного копирования каждый запрос SQL должен быть выполнен точно
таким же образом, как это было сделано первоначально.
CREATE TABLE ... SELECT ...
выступает как SELECT
с
с совместно используемыми блокировками следующего ключа или как
последовательное чтение при
INSERT ... SELECT
.
Когда SELECT
учавствует в
REPLACE INTO t SELECT ... FROM s WHERE ...
или UPDATE t ... WHERE col IN (SELECT ... FROM s ...)
,
InnoDB
ставит совместно используемую блокировку следующего
ключа на строках из таблицы s
.
AUTO_INCREMENT
в
таблице, InnoDB
ставит исключительную блокировку на конце
индекса, связанного со столбцом AUTO_INCREMENT
.
При доступе к счетчику автоинкремента InnoDB
использует режим
блокировки AUTO-INC
, где блокировка длится только до конца
текущего запроса SQL, но не до конца всей транзакции.
Другие сеансы не могут вставить в таблицу в то время, как
проводится табличная блокировка AUTO-INC
, см.
раздел 16.5.2.
InnoDB
приносит значение ранее инициализированного столбца
AUTO_INCREMENT
, не устанавливая блокировок.
FOREIGN KEY
определено на таблице, любые
вставки, обновления или удаления, которые требуют, чтобы условие ограничения
было проверено, ставят совместно используемую блокировку на уровне записи,
которые проверяются на ограничение. InnoDB
ставит эти блокировки
в случае, где ограничение терпит неудачу.LOCK TABLES
ставит
табличные блокировки, но это более высокий уровень MySQL, выше слоя
InnoDB
, который устанавливает эти блокировки.
InnoDB
знает о табличных блокировках, если
innodb_table_locks = 1
(по умолчанию) и
autocommit = 0
и уровень MySQL выше InnoDB
знает о блокировках
на уровне строки.
Иначе автоматическое обнаружение тупика InnoDB
не может обнаружить тупики, где такие табличные блокировки вовлечены.
Кроме того, потому что в этом случае более высокий уровень MySQL не знает о
блокировках на уровне строки, можно получить табличную блокировку на таблице,
где у другого сеанса в настоящее время есть блокировки на уровне строки.
Однако, это не подвергает опасности операционную целостность, как обсуждено в
разделе 16.5.5.2. См.
также раздел 16.8.7.
Так называемая призрачная проблема
происходит в пределах транзакции, когда тот же самый запрос производит
различные наборы строк в разное время. Например, если
SELECT
выполнен дважды, но возвращает строку во второй раз, которая не была
возвращена в первый раз, строка призрачная.
Предположите, что есть индекс на столбце id
таблицы
child
и что Вы хотите считать и заблокировать все строки из
таблицы, имеющей значение идентификатора, больше 100, с намерением обновить
некоторый столбец в выбранных строках позже:
SELECT * FROM child WHERE id > 100 FOR UPDATE;
Запрос просматривает индекс с первой записи, где id
больше
100. Пусть в таблице строки с id
90 и 102.
Если блокировки на записях индекса в просмотренном диапазоне не запрещают
вставки в промежутки (в этом случае, промежуток между 90 и 102), другой сеанс
может вставить новую строку в таблицу с id
101.
Если Вы должны были выполнить тот же самый
SELECT
в пределах той же самой транзакции Вы видели бы новую строку с
id
101 (призрак)
в наборе результатов, возвращенном запросом. Если мы расцениваем ряд строк
как элемент данных, новый призрачный дочерний элемент нарушил бы принцип
изоляции транзакций, что транзакция должна быть в состоянии работать так,
чтобы данные, которые она прочитала, не изменились во время транзакции.
Чтобы избегать таких ситуаций InnoDB
использует алгоритм, названный блокировка следующего
ключа, который комбинирует блокировку индекса строки с блокировкой
промежутка. InnoDB
выполняет блокировку на уровне строки таким
способом, что когда это ищет или просматривает индекс таблицы, это
устанавливает совместно использованные или исключительные блокировки на
индексных записях, с которыми сталкивается. Таким образом, блокировки на
уровне строки фактически блокировки индексных записей. Кроме того,
блокировка следующего ключа на записи индекса также затрагивает
промежуток перед этой записью.
Таким образом, блокировка следующего ключа это блокировка индексной записи и
промежутка, предшествующего ей. Если у одного сеанса есть совместно
используемая или исключительная блокировка на записи R
в
индексе, другой сеанс не может вставить новую запись в промежутке немедленно
перед R
в порядке индекса.
Когда InnoDB
просматривает индекс, это может также
заблокировать промежуток после последней записи в индексе. Это происходит в
предыдущем примере: чтобы предотвратить любую вставку в таблицу, где
id
больше 100, блокировки, установленные InnoDB
,
включают блокировку на промежутке после id
102.
Вы можете использовать блокировку следующего ключа, чтобы осуществить проверку уникальности в Вашем приложении: если Вы читаете свои данные в режиме совместного доступа и не видите дубликат строки, которую собираетесь вставить, то можете безопасно вставить свою строку и знать, что блокировка следующего ключа, установленная на преемнике Вашей строки во время чтения, предотвращает вставку дубликата для Вашей строки. Таким образом, блокировка следующего ключа позволяет Вам блокировать небытие чего-то в Вашей таблице.
Блокировка промежутка может быть отключена как обсуждено в разделе 16.5.1. Это может вызвать призрачные проблемы, потому что другие сеансы могут вставить новые строки в промежутки, когда блокировка промежутка отключена.
Тупик это ситуация, где различные транзакции не способны продолжить работу потому, что каждый держит блокировку, нужную другой. Поскольку обе транзакции ждут ресурса, ни одна никогда не будет выпускать блокировки, которые держит.
Тупик может произойти, когда транзакции блокируют строки в многих таблицах
(через такие запросы, как UPDATE
или SELECT ... FOR UPDATE
),
но в противоположном порядке. Тупик может также произойти, когда такие
запросы блокируют диапазоны, индексных записей и промежутки с каждой
транзакцией, приобретающей некоторые блокировки, но не другие из-за проблемы
синхронизацией. Для примера тупика см.
раздел 16.5.5.1.
Чтобы уменьшить возможность тупиков, используйте транзакции, а не
LOCK TABLES
,
сохраните транзакции, которые вставляют или обновляют данные, достаточно
маленькими, чтобы они не оставались открытыми в течение долгих промежутков
времени, когда различные транзакции обновляют многие таблицы или большие
спектры строк, используйте тот же самый порядок операций (таких, как
SELECT ... FOR UPDATE
)
в каждой транзакции, создайте индексы на столбцах, используемых в
SELECT ... FOR UPDATE
и
UPDATE ... WHERE
.
Возможность тупиков не затронута уровнем изоляции, потому что уровень
изоляции изменяет поведение операций чтения, в то время как тупики происходят
из-за записи. Для получения дополнительной информации об уходе от условий
тупика см. раздел 16.5.5.3
.
Когда обнаружение тупика включено (значение по умолчанию), и тупик
действительно происходит, InnoDB
обнаруживает условие и
откатывает одну из транзакций до прежнего уровня. Если обнаружение тупика
отключено, используя опцию
innodb_deadlock_detect
, InnoDB
полагается на
настройку
innodb_lock_wait_timeout
, чтобы откатить транзакции до прежнего
уровня в случае тупика. Таким образом, даже если Ваша логика приложения
правильна, Вы должны все еще обработать случай, где транзакция должна быть
повторена. Чтобы увидеть последний тупик в пользовательской транзакции
InnoDB
, используйте
SHOW ENGINE INNODB STATUS
.
Если частые тупики выделяют проблему с операционной структурой или обработкой
ошибки приложения, работайте с опцией
innodb_print_all_deadlocks
, чтобы напечатать информацию обо всех
тупиках в журнал ошибок mysqld
. Для получения дополнительной информации о том, как
тупики автоматически обнаружены и обработаны см.
раздел 16.5.5.2.
Следующий пример иллюстрирует, как ошибка может произойти, когда запрос блокировки вызвал бы тупик. Пример вовлекает двух клиентов A и B.
Клиент А составляет таблицу, содержащую одну строку, а затем начинает
транзакцию. В пределах транзакции A получает блокировку
S
на строке, выбирая это в режиме общего доступа:
mysql> CREATE TABLE t (i INT) ENGINE = InnoDB; Query OK, 0 rows affected (1.07 sec) mysql> INSERT INTO t (i) VALUES(1); Query OK, 1 row affected (0.09 sec) mysql> START TRANSACTION; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM t WHERE i = 1 LOCK IN SHARE MODE; +---+ | i | +---+ | 1 | +---+
Затем клиент Б начинает транзакцию и пытается удалить строку из таблицы:
mysql> START TRANSACTION; Query OK, 0 rows affected (0.00 sec) mysql> DELETE FROM t WHERE i = 1;
Удаление требует блокировки X
.
Блокировку нельзя предоставить, потому что это является несовместимым с
S
, которую держит клиент А, таким образом, запрос идет
в очередь запросов блокировки для строки, что блокирует клиента B.
Наконец, клиент также пытается удалить строку из таблицы:
mysql> DELETE FROM t WHERE i = 1; ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
Тупик происходит здесь потому, что клиент A требует блокировку
X
, чтобы удалить строку. Однако, тот запрос блокировки
нельзя предоставить, потому что у клиента B уже есть запрос на
X
, и он ждет, пока клиент A выпустит блокировку
S
. Так они будут ждать друг друга вечно.
В результате InnoDB
производит ошибку для одного из клиентов и
выпускает все его блокировки. Клиент возвращает эту ошибку:
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
Здесь можно предоставить запрос блокировки для другого клиента, и это удаляет строку из таблицы.
Когда обнаружение тупика
включено (по умолчанию), InnoDB
автоматически обнаруживает
транзакционные тупики и откатывает
до прежнего уровня транзакцию или транзакции, чтобы найти выход из тупика.
InnoDB
старается выбрать маленькие транзакции, чтобы откатить,
где размер транзакции определен числом затронутых ей строк.
InnoDB
знает о табличных блокировках, если
innodb_table_locks = 1
(по умолчанию) и
autocommit = 0
,
и уровень MySQL выше этого знает о блокировках на уровне строки. Иначе
InnoDB
не может обнаружить тупики, где табличная блокировка,
установленная MySQL LOCK TABLES
или блокировка, установленная механизмом хранения кроме
InnoDB
, вовлечена. Решите эти ситуации, устанавливая значение
innodb_lock_wait_timeout
.
Когда InnoDB
выполняет полную отмену транзакции, все
блокировки, установленные транзакцией, выпущены. Однако, если только
единственный запрос SQL откатывается до прежнего уровня в результате ошибки,
некоторые из блокировок, установленных запросом, могут быть сохранены. Это
происходит потому, что InnoDB
хранит блокировки строк
таким образом, что не может знать, какая блокировка была
установлена которым запросом.
Если SELECT
вызывает сохраненную
функцию в транзакции, и запрос в пределах функции терпит неудачу, то запрос
откатывается. Кроме того, если ROLLBACK
выполнен после этого, откатывается вся транзакция.
Если раздел LATEST DETECTED DEADLOCK
в
InnoDB
Monitor включает сообщение TOO DEEP OR
LONG SEARCH IN THE LOCK TABLE WAITS-FOR GRAPH, WE WILL ROLL BACK FOLLOWING
TRANSACTION, это указывает, что число транзакций в
ожидании достигло предела 200. Это обработано как тупик и транзакция,
пытающаяся встать в очередь откатывается до прежнего уровня. Та же самая
ошибка может также произойти, если поток блокировки должен смотреть больше,
чем на 1000000 блокировок, принадлежавших транзакциям в списке ожидания.
Для методов, чтобы организовать операции базы данных, чтобы избежать тупиков, см. раздел 16.5.5.
На высоконагруженных системах обнаружение тупика может вызвать замедление,
когда многочисленные потоки ждут той же самой блокировки. Время от времени
может быть более эффективно отключить обнаружение тупика и положиться на
опцию
innodb_lock_wait_timeout
для операционной отмены, когда тупик
происходит. Обнаружение тупика может быть отключено, используя опцию
innodb_deadlock_detect
.
Этот раздел основывается на концептуальной информации о тупиках в разделе 16.5.5.2. Это объясняет, как организовать операции базы данных, чтобы минимизировать тупики и последующую обработку ошибок, требуемую в приложениях.
Тупики это классическая проблема в транзакционных базах данных, но они не опасны, если не являются настолько частыми, что Вы не можете выполнить определенные транзакции вообще. Обычно Вы должны написать свои приложения так, чтобы они были всегда подготовлены перезапустить транзакцию, если она отменена из-за тупика.
InnoDB
использует автоматическую блокировку на уровне строки.
Вы можете получить тупики даже в случае транзакций, которые только вставляют
или удаляют единственную строку. Это так, потому что эти операции не
действительно атомарные, они автоматически
устанавливают блокировки (возможно, несколько) индексных записей
строки, вставленной или удаленной.
Вы можете справиться с тупиками и уменьшить вероятность их возникновения следующими методами:
В любое время скомандуйте SHOW
ENGINE INNODB STATUS
, чтобы определить причину нового тупика. Это
может помочь Вам настроить свое приложение, чтобы избежать тупиков.
innodb_print_all_deadlocks
. Информация о каждом тупике, не
только последнем, зарегистрирована в
журнале ошибок MySQL. Отключите эту опцию, когда Вы закончите отладку.
SELECT ... FOR UPDATE
или SELECT ... LOCK IN SHARE MODE
),
попытайтесь использовать более низкий уровень изоляции, такой как
READ COMMITTED
.
INSERT
,
UPDATE
и DELETE
в различных местах.EXPLAIN SELECT
, чтобы
определить, которые индекс сервер MySQL использует как самый подходящий
для Ваших запросов.SELECT
,
чтобы возвратить данные из старого снимка, не добавляйте
FOR UPDATE
или LOCK IN SHARE MODE
. Используя
уровня изоляции READ
COMMITTED
хорошо здесь, потому что каждое последовательное чтение
в пределах той же самой транзакции читает из ее собственного нового снимка.
LOCK TABLES
с
InnoDB
: начать с SET autocommit = 0
(но не
START TRANSACTION
) сопровождаемый
LOCK TABLES
и не вызывать
UNLOCK TABLES
пока Вы не передаете транзакцию явно. Например, если Вы должны записать в
таблицу t1
и читать из таблицы t2
,
Вы можете сделать это:
SET autocommit=0;
LOCK TABLES t1 WRITE, t2 READ, ...;
... do something with tables t1 and t2 here ...
COMMIT;
UNLOCK TABLES;
Блокировки на уровне таблицы предотвращают параллельные обновления таблицы, избегая тупиков за счет менее быстрого отклика для занятой системы.
InnoDB
также работает в этом случае, потому что
блокировка преобразования в последовательную форму это
блокировка на уровне строки. С MySQL блокировки на уровне таблицы метод
тайм-аута должен использоваться, чтобы решить тупики.Этот раздел предоставляет информацию о конфигурации и процедуры для
инициализации и запуска InnoDB
, а также
различные компоненты и особенности механизма хранения InnoDB
.
Для информации об оптимизации операций базы данных для таблиц
InnoDB
см. раздел 9.5
.
Первые решения о настройке InnoDB
вовлекают конфигурацию файлов с данными, файлов системного журнала, размера
страницы и буферов памяти. Рекомендуется, чтобы Вы определили файл с данными,
файл системного журнала и конфигурацию размера страницы прежде, чем создать
экземпляр InnoDB
. Изменение файла с данными или конфигурации
файла системного журнала после запуска InnoDB
может вовлечь нетривиальную процедуру, и размер страницы может быть определен
только когда InnoDB
начально инициализирован.
В дополнение к этим темам этот раздел предоставляет информацию об опциях в конфигурационном файле, рассматривая информацию об инициализации и важные соображения о хранении.
Поскольку MySQL использует файл с данными, файл системного журнала и
настройки конфигурации размера страницы, чтобы инициализировать
InnoDB
, рекомендуется, чтобы Вы определили эти настройки в
конфигурационном файле, который MySQL читает при запуске, до инициализации
InnoDB
впервые. InnoDB
инициализирован, когда
сервер MySQL запущен, и первая инициализация InnoDB
обычно происходит в первый раз, когда Вы запускаете сервер MySQL.
Вы можете поместить опции InnoDB
в группу
[mysqld]
любого файла опции, который читает Ваш сервер, когда
запускается. Местоположения файлов опции MySQL описаны в
разделе 5.2.6.
Чтобы удостовериться, что
mysqld читает опции только из определенного файла (и
mysqld-auto.cnf
), используйте
--defaults-file
как первую опцию в командной строке, запуская сервер:
mysqld --defaults-file=path_to_configuration_file
Чтобы видеть сведения об инициализации InnoDB
во время
запуска, запустите mysqld
из командной строки. Когда
mysqld
запущен из командной строки, информация об инициализации выведена на консоль.
Например, в Windows, если
mysqld расположен в
C:\Program Files\MySQL\MySQL Server 8.0\bin
,
запустите MySQL так:
C:\> "C:\Program Files\MySQL\MySQL Server 8.0\bin\mysqld" --console
В Unix-системах mysqld
расположен в подкаталоге
bin
установки MySQL:
sell> bin/mysqld --user=mysql &
Если Вы не посылаете вывод сервера на консоль, проверьте журнал ошибок
после запуска, чтобы видеть информацию об инициализации InnoDB
,
напечатанную во время процесса запуска.
Для информации о запуске MySQL, используя другие методы, см. раздел 2.9.5.
Рассмотрите следующие связанные с хранением соображения перед продолжением Вашей конфигурации.
В некоторых случаях работа базы данных улучшается, если все данные
не помещены на тот же самый физический диск. Помещение файлов системного
журнала на различном диске от данных очень часто выгодно для работы.
Например, Вы можете поместить системные файлы с данными табличного
пространства и файлы системного журнала на различных дисках. Вы можете также
использовать сырые дисковые разделы (сырые устройства) для файлов с данными
InnoDB
, что может ускорить ввод/вывод. См.
раздел 16.7.3.
На дисководах ATA/SATA команда hdparm -W0 /dev/hda
может работать, чтобы отключить кэширование записи.
Остерегайтесь того, что некоторые диски или дисковые
контроллеры могут быть неспособны отключить кэширование записи.
InnoDB
, которые
защищают пользовательские данные, InnoDB
использует метод потока файла, вовлекающий структуру, названную
буфер doublewrite,
который включен по умолчанию
(innodb_doublewrite=ON
). Буфер doublewrite добавляет безопасность восстановления после
катастрофического отказа и улучшает работу относительно большинства вариантов
Unix, уменьшая потребность в fsync()
. Рекомендуется держать
опцию innodb_doublewrite
включенной, если Вы обеспокоены целостностью данных или
возможными отказами. Для дополнительной информации о буфере
doublewrite см. раздел 16.11.1.InnoDB
использовать файлы с данными или файлы системного журнала
на томах NFS. Потенциальные проблемы изменяются в зависимости от OS и версии
NFS, и включают такие проблемы, как нехватка защиты от конфликтов записи
и ограничения на максимальные размеры файла.Системные файлы с данными табличного пространства сконфигурированы,
используя опции
innodb_data_file_path
и
innodb_data_home_dir
.
innodb_data_file_path
используется, чтобы сконфигурировать
системные файлы с данными табличного пространства. Значение
innodb_data_file_path
должно быть списком из одной или более спецификаций файла с
данными. Если Вы называете больше чем один файл с данными, отделяете
их точкой с запятой (;
):
innodb_data_file_path=datafile_spec1
[;datafile_spec2
]...
Например, следующая установка явно создает минимальное системное табличное пространство:
[mysqld] innodb_data_file_path=ibdata1:12M:autoextend
Эта установка конфигурирует единственный файл с данными 12 МБ
ibdata1
. Никакое местоположение для файла не задано, так что по
умолчанию, InnoDB
создает это в каталоге данных MySQL.
Размеры определены, используя буквы суффикса K
,
M
или G
, чтобы указать на KB, MB или GB.
Табличное пространство, содержащее файл с данными 50 МБ фиксированного
размера с именем ibdata1
и 50MB автомасштабируемый файл с именем
ibdata2
в каталоге данных может быть сконфигурирован как это:
[mysqld] innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend
Полный синтаксис для спецификации файла с данными включает имя файла, его размер и несколько дополнительных признаков:
file_name
:file_size
[:autoextend[:max:max_file_size
]]
autoextend
и max
могут использоваться только для последнего файла с данными в строке
innodb_data_file_path
.
Если Вы определяете autoextend
для последнего файла с
данными, InnoDB
расширяет файл с данными, если он исчерпывает
свободное пространство в табличном пространстве. Инкремент составляет 64 МБ
за один раз по умолчанию. Чтобы изменить инкремент, измените значение
innodb_autoextend_increment
.
Если диск становится полным, Вы могли бы добавить другой файл с данными на другом диске. Для инструкций реконфигурирования табличного пространства см. раздел 16.7.1.
InnoDB
не знает о максимальном размере файла в файловой
системе, так что следует быть осторожным на файловых системах, где
максимальный размер файла маленькое значение, такое как 2GB.
Чтобы определить максимальный размер для файла с данными, используйте
параметр max
после autoextend
. Используйте
max
только в случаях, где ограничение дискового использования
имеет жизненную важность, потому что превышение максимального размера
вызывает фатальную ошибку, возможно, включая катастрофический отказ.
Следующяя конфигурация позволяет ibdata1
расти до 500MB:
[mysqld] innodb_data_file_path=ibdata1:12M:autoextend:max:500M
InnoDB
создает файлы табличного пространства в каталоге
данных MySQL по умолчанию (datadir
). Чтобы определить местоположение явно, используйте опцию
innodb_data_home_dir
. Например, чтобы создать два файла
ibdata1
и ibdata2
в /myibdata
:
[mysqld] innodb_data_home_dir = /myibdata innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend
InnoDB
не создает каталоги, так что удостоверьтесь, что
каталог /myibdata
существует прежде, чем Вы запустите сервер.
Используйте Unix или DOS mkdir
, чтобы создать
любые необходимые каталоги.
Удостоверьтесь, что у сервера MySQL есть надлежащие права доступа, чтобы создать файлы в каталоге данных. Более широко, у сервера должны быть права доступа в любом каталоге, где это должно создать файлы с данными.
InnoDB
формирует путь к каталогу для каждого файла с данными,
дословно добавляя значение
innodb_data_home_dir
к имени файла с данными, добавляя разделитель пути (наклонная
черта или наклонная черта влево) между значениями в случае необходимости.
Если опция
innodb_data_home_dir
не определена в my.cnf
вообще, значение по умолчанию ./
, что означает каталог данных
MySQL. Сервер MySQL изменяет свой текущий рабочий каталог на свой каталог
данных, когда он начинает выполняться.
Если Вы определяете
innodb_data_home_dir
как пустую строку, Вы можете определить
абсолютные пути для файлов с данными, перечисленных в
innodb_data_file_path
. Следующий пример эквивалентен предыдущему:
[mysqld] innodb_data_home_dir = innodb_data_file_path=/ibdata/ibdata1:50M;/ibdata/ibdata2:50M:autoextend
По умолчанию InnoDB
создает два файла системного журнала по
48 МБ в каталоге данных MySQL
(datadir
) с именами
ib_logfile0
и ib_logfile1
.
Следующие опции могут использоваться, чтобы изменить конфигурацию по умолчанию:
innodb_log_group_home_dir
определяет путь к каталогу с файлами системного журнала (redo logs).
Если эта опция не сконфигурирована, файлы создаются в каталоге данных MySQL
(datadir
).
Вы могли бы использовать эту опцию, чтобы поместить файлы системного журнала в ином физическом местоположении хранения, чем файлы с данными, чтобы избежать потенциальных конфликтов ресурса ввода/вывода. Например:
[mysqld] innodb_log_group_home_dir = /dr3/iblogs
innodb_log_files_in_group
определяет число файлов системного
журнала в группе журналов. Значение по умолчанию и рекомендуемое значение 2.
innodb_log_file_size
определяет размер в байтах каждого файла
системного журнала в группе журналлв. Объединенный размер файлов системного
журнала (
innodb_log_file_size
*
innodb_log_files_in_group
) не может превысить максимальное
значение, которое является немного меньше чем 512GB.
Пара файлов системного журнала по 255 GB, например, приближается к пределу,
но не превышает его. Размер файла системного журнала по умолчанию составляет
48 МБ. Заметные значения колеблются от 4 МБ до
1/N
размера буферного пула, где N
число файлов системного журнала в группе. Чем больше значение, тем меньше
деятельности потока контрольной точки необходимо в буферном пуле, сохраняя
дисковый ввод/вывод. Для дополнительной информации см.
раздел 9.5.4.
По умолчанию журналы отмены это часть системного табличного пространства. Однако, Вы можете хотеть хранить их в одном или более отдельных табличных пространств отмены, как правило, на ином устройстве хранения данных.
Опция
innodb_undo_directory
определяет путь, где InnoDB
создает отдельные табличные пространства для журналов отмены. Эта опция как
правило используется в соединении с
innodb_undo_logs
и
innodb_undo_tablespaces
, которые определяют дисковое расположение
журналов отмены вне системного табличного пространства.
Подробности в разделе 16.7.7 .
По умолчанию InnoDB
создает единственный автомасштабируемый
временный файл с данными табличного пространства ibtmp1
в
каталоге данных MySQL (datadir
) это немного больше, чем 12 МБ. Конфигурация по умолчанию
может быть изменена при запуске, используя
innodb_temp_data_file_path
.
innodb_temp_data_file_path
определяет путь, имя файла и размер файла для
временных файлов с данными табличного пространства.
Полный путь к каталогу для файла сформирован, связывая
innodb_data_home_dir
с путем, определенным
innodb_temp_data_file_path
. Размер файла определен в
KB, MB или GB (1024MB), добавляя K, M или G к значению размера.
Сумма размеров файлов должна быть немного больше, чем 12 МБ.
innodb_page_size
определяет размер страницы для всех табличных пространств
InnoDB
. Это значение установлено, когда экземпляр
создается и остается постоянным позже. Допустимые значения составляют
64k, 32k, 16k (по умолчанию), 8k и 4k. Альтернативно, Вы можете определить
размер страницы в байтах (65536, 32768, 16384, 8192, 4096).
Размер страницы по умолчанию 16k является подходящим для широкого диапазона рабочих нагрузок, особенно для запросов, вовлекающих сканирование таблицы и операции DML, вовлекающие оптовые обновления. Меньшие размеры страницы могли бы быть более эффективными для рабочих нагрузок OLTP, вовлекающих, многие маленькие записи, где может быть проблемой, когда единственная страница содержит много строк. Меньшие страницы могли бы также быть эффективными с устройствами хранения данных SSD, которые, как правило, используют маленькие размеры блока. Задание размера страницы близким к размеру блока устройства хранения данных минимизирует количество неизменных данных, которые переписаны на диск.
MySQL выделяет память различным кэшам и буферам, чтобы улучшить исполнение
операций базы данных. Выделяя память для InnoDB
,
всегда считайте память требуемую операционной системой, память, выделенную
другим приложениям, и память для других буферов MySQL и кэшей.
Например, если Вы используете таблицы MyISAM
,
считайте объем памяти, выделенный для ключевого буфера
(key_buffer_size
). Для краткого обзора буферов MySQL и кэшей см.
раздел 9.12.3.1.
Буферы для InnoDB
сконфигурированы, используя следующие параметры:
innodb_buffer_pool_size
определяет размер буферного пула, который
является областью памяти, которая содержит кэшируемые данные для таблиц
InnoDB
, индексов и других вспомогательных буферов. Размер
буферного пула важен для системной работы, и рекомендуют выделить под
innodb_buffer_pool_size
от 50 до 75 процентов системной памяти.
Буферный размер пула по умолчанию составляет 128MB. Подробности в
разделе 9.12.3.1.
Для информации о том, как сконфигурировать размер пула буферного см.
раздел 16.6.3.2.
Размер пула может быть сконфигурирован при запуске или динамически.
На системах с большим объемом памяти Вы можете улучшить параллелизм, деля
буферный пул на несколько экземпляров. Числом экземпляров пула управляет
innodb_buffer_pool_instances
.
По умолчанию InnoDB
создает один буферный экземпляр.
Число экземпляров пула может быть сконфигурировано при запуске. Для получения
дополнительной информации см.
раздел 16.6.3.3.
innodb_log_buffer_size
определяет размер в байтах буфера,
который InnoDB
применяет для записи файлов системного журнала на
диск. Размер по умолчанию составляет 16 МБ. Большой буфер журнала позволяет
большим транзакциям работать без потребности записать журнал на диск прежде,
чем транзакции передадут. Если у Вас есть транзакции, которые обновляют,
вставляют или удаляют много строк, Вы могли бы полагать, что увеличение
размера буфера журнала уменьшит дисковый ввод/вывод.
innodb_log_buffer_size
может быть сконфигурирован при запуске.
Для соответствующей информации см.
раздел 9.5.4.
В 32-bit GNU/Linux x86 не стоит устанавливать использование памяти слишком
большим. glibc
может разрешить куче процесса расти по стекам
потока, который разрушает Ваш сервер. Это рискованно, если память, выделенная
процессу mysqld
для глобальных и поточных буферов и кэшей, близка к или превышает 2GB.
Формула, подобная следующей, которая вычисляет глобальное и поточное распределение памяти для MySQL, может использоваться, чтобы оценить использование памяти MySQL. Вы, возможно, должны изменить формулу, чтобы составлять буферы и кэши в Вашей версии MySQL и конфигурации. Для краткого обзора буферов MySQL и кэшей см. раздел 9.12.3.1.
innodb_buffer_pool_size + key_buffer_size + max_connections*(sort_buffer_size+read_buffer_size+binlog_cache_size) + max_connections*2MB
Каждый поток использует стек (часто 2 МБ, но только 256 КБ в двоичных
модулях MySQL от Oracle Corporation) и в худшем случае также использует
еще sort_buffer_size + read_buffer_size
памяти.
В Linux, если ядро настроено для поддержки большой страницы,
InnoDB
может использовать большие страницы, чтобы выделить
память для буферного пула. См.
раздел 9.12.3.2.
Вы можете теперь запросить таблицы, где каталог данных MySQL находится на
носителе только для чтения, включая опцию
--innodb-read-only
при запуске сервера.
Чтобы подготовить систему к работе только для чтения, удостоверьтесь, что
вся необходимая информация сброшена в
файлы с данными прежде, чем сохранить ее на носителе только для чтения.
Выполните сервер с отключенной буферизацией изменения
(
innodb_change_buffering=0
) и сделайте
медленную парковку.
Чтобы включить режим только для чтения для всего MySQL, определите следующие параметры конфигурации при запуске сервера:
/var
недоступен на запись:
--pid-file=path_on_writeable_media
и --event-scheduler=disabled
.С MySQL 8.0 включение
innodb_read_only
блокирует табличные операции создания и удаления
для всех механизмов хранения. Эти операции изменяют таблицы словаря данных в
системной базе данных mysql
, но те таблицы использует
механизм хранения InnoDB
и не может изменить, когда включена
innodb_read_only
. То же самое ограничение относится к любой работе, которая изменяет
таблицы словаря данных, такой как
ANALYZE TABLE
и ALTER TABLE
.tbl_name
ENGINE=engine_name
Кроме того, другие таблицы в базе данных mysql
используют механизм хранения InnoDB
в MySQL 8.0. Например,
CREATE USER
,
GRANT
,
REVOKE
и
INSTALL PLUGIN
не
работают в режиме только для чтения.
Этот режим работы является подходящим в таких ситуациях:
Распределение приложения MySQL или ряда данных MySQL на носителе данных только для чтения, таком как DVD или CD.
Эта особенность, главным образом, предназначена для гибкости в распределении и развертывании, а не сырой работе, основанной на аспекте только для чтения. См. раздел 9.5.3 для способов настроить исполнение запросов только для чтения, которые не требуют создания всего сервера только для чтения.
Когда сервер выполнен в режиме только для чтения через
--innodb-read-only
, многие особенности и компоненты InnoDB
уменьшены
или выключены полностью:
Буферизация
изменений не сделана, в особенности никакие слияния от буфера изменения.
Чтобы удостовериться, что буфер изменения пуст, когда Вы готовите систему к
работе только для чтения, выключите его
(
innodb_change_buffering=0
) и сделайте
медленную парковку.
innodb_log_file_size
к самому маленькому возможному размеру (1 MB).SHOW ENGINE
INNODB STATUS
ничего не покажет.
innodb_undo_tablespaces
и
innodb_undo_directory
.Этот раздел обеспечивает конфигурацию буферного
пула InnoDB
.
InnoDB
поддерживает область
хранения, названную буферным пулом
для того, чтобы кэшировать данные и индексы в памяти. Знание, как
буфер работает и использование в своих интересах его, чтобы сохранить данные,
к которым часто получают доступ, в памяти, важный аспект настройки MySQL.
Вы можете сконфигурировать различные аспекты буферного пула
InnoDB
, чтобы улучшить работу.
Идеально Вы устанавливаете размер буферного пула к столь большому
значению как возможно, оставляя достаточную память для других процессов на
сервере, чтобы работать без чрезмерных проблем. Чем больше буферный пул, тем
больше InnoDB
работает как база данных в памяти, читая данные с
диска однажды и затем получая доступ к данным в памяти во время последующих
чтений. См. раздел 16.6.3.2
.
InnoDB
выполняет
предвыборки и предварительно принести страницы в буферный пул асинхронно, в
ожидании, что страницы скоро будут необходимы. Для деталей см.
раздел 16.6.3.5.InnoDB
динамически корректирует уровень сброса,
исходя из рабочей нагрузки. Для деталей см.
раздел 16.6.3.6
.InnoDB
, чтобы улучшить
работу. Для деталей см.
раздел 16.6.3.7.InnoDB
сохраняет текущее
состояние буферного пула, чтобы избежать длинного периода разминки после
перезапуска сервера. Вы можете также сохранить текущее состояние
пула, в то время как сервер работает. Для деталей см.
раздел 16.6.3.8.
InnoDB
управляет буферным пулом как списком, используя
вариант последнего использованного алгоритма (LRU). Когда нужно место, чтобы
добавить новую страницу к пулу, InnoDB
вычеркивает последнюю
использованную страницу и добавляет новую страницу к середине списка. Эта
вставка в середину обрабатывает список
как два подсписка:
В начальном подсписке новые (или молодые) страницы, к которым недавно получили доступ.
Этот алгоритм сохраняет страницы, которые в большой степени используются запросами в новом подсписке. Старый подсписок содержит менее используемые страницы, эти страницы кандидаты на вычеркивание.
Алгоритм LRU работает следующим образом по умолчанию:
3/8 буферного пула посвящены старому подсписку.
InnoDB
читает страницу в буферный пул, это
первоначально вставляет это в середину (голова старого подсписка).
Страница может быть считана потому, что она требуется для определенной
пользователем работы, такой как запрос SQL, или как часть работы
предвыборки,
выполненной автоматически InnoDB
.По умолчанию, страницы, считанные запросами немедленно, перемещаются в
новый подсписок, означая, что они будут оставаться в буферном пуле в течение
долгого времени. Сканирование таблицы (такое, как выполнено для
mysqldump
или SELECT
без WHERE
)
может принести большой объем данных в буферный пул и выдавить эквивалентное
количество более старых данных, даже если новые данные никогда не
используются снова. Точно так же страницы, которые загружены фоновым потоком
предвыборки, к которым затем получен доступ только однажды, перемещены в
начало нового списка. Эти ситуации могут продвинуть часто используемые
страницы к старому подсписку, где они становятся кандидатами на вычеркивание.
Для информации об оптимизации этого поведения см. разделы
16.6.3.4 и
16.6.3.5.
InnoDB
Standard Monitor выводит содержимое нескольких полей
в разделе BUFFER POOL AND MEMORY
, которые принадлежат работе
алгоритма LRU буферного пула. Для деталей см.
раздел 16.6.3.9.
Несколько параметров конфигурации затрагивают различные аспекты
буферного пула InnoDB
.
Определяет размер буферного пула. Если буферный пул является небольшим, и
у Вас есть достаточная память, пул большего размера может улучшить работу,
уменьшая количество дискового ввода/вывода, необходимого для доступа запросов
к таблицам InnoDB
. Опция
innodb_buffer_pool_size
является динамической, что позволяет Вам
сконфигурировать размер, не перезапуская сервер. См.
раздел 16.6.3.2.
innodb_buffer_pool_chunk_size
Определяет размер куска для изменения размера пула. См. раздел 16.6.3.2.
innodb_buffer_pool_instances
Делит буферный пул на пользовательское конкретное количество отдельных
областей, каждая с его собственным списком LRU и связанными структурами
данных, чтобы уменьшить издержки во время параллельного чтения памяти.
Эта опция вступает в силу только, когда Вы устанавливаете
innodb_buffer_pool_size
к значению 1GB или больше. Полный размер,
который Вы определяете, разделен среди всех буферных пулов. Для лучшей
эффективности, определите комбинацию
innodb_buffer_pool_instances
и
innodb_buffer_pool_size
так, чтобы каждый экземпляр буферного пула
составил по крайней мере 1 гигабайт. См.
раздел 16.6.3.3.
innodb_old_blocks_pct
Определяет приблизительный процент буферного пула, который
InnoDB
использует для старого подсписка блока. Диапазон значений
от 5 до 95. Значение по умолчанию 37 (то есть, 3/8 пула). См.
раздел 16.6.3.4
.
innodb_old_blocks_time
Определяет, сколько времени в миллисекундах (ms) страница, вставленная в старый подсписок, должна остаться там после первого доступа к ней прежде, чем сможет быть перемещена в новый подсписок. Если значение 0, страница, вставленная в старый подсписок, немедленно перемещается в новый подсписок в первый раз, когда к ней получают доступ, независимо от того, как быстро после вставки доступ происходит. Если значение больше 0, страницы остаются в старом подсписке, пока доступ не происходит, по крайней мере, столько миллисекунд после первого доступа. Например, значение 1000 предписывает страницам остаться в старом подсписке в течение 1 секунды после первого доступа прежде, чем они смогут переместиться в новый подсписок.
Установка
innodb_old_blocks_time
больше 0
препятствует тому, чтобы одноразовое сканирование таблицы затопило новый
подсписок страницами, используемыми только для просмотра.
К строкам страницы для просмотра получают доступ много раз в быстрой
последовательности, но страница не использована после этого. Если
innodb_old_blocks_time
установлен в значение больше, чем время
обработки страницы, эта страница остается в старом
и сдвигается к хвосту списка, который будет выселен быстро. Этим путем
страницы, используемые только для одноразового просмотра, не действуют в
ущерб в большой степени используемым страницам в новом подсписке.
innodb_old_blocks_time
может быть установлен во время выполнения,
таким образом, Вы можете изменить его временно, выполняя такие операции, как
сканирование таблицы и дампы:
SET GLOBAL innodb_old_blocks_time = 1000;
... perform queries that scan tables ...
SET GLOBAL innodb_old_blocks_time = 0;
Эта стратегия не применяется, если Ваше намерение
нагреть буферный пул, заполняя его контентом
таблицы. Например, оценочные испытания часто выполняют сканирование
таблицу или индекса при запуске сервера, потому что те данные обычно были бы
в буферном пуле после периода нормальной эксплуатации. В этом случае
установите
innodb_old_blocks_time
в 0, по крайней мере пока
идет фаза разминки.
См. раздел 16.6.3.4.
innodb_read_ahead_threshold
Управляет чувствительностью линейной предвыборки, чтобы предварительно принести страницы в буферный пул .
См. раздел 16.6.3.5 .
innodb_random_read_ahead
Включает случайный метод
предвыборки страниц в буферный пул. Случайное чтение это
метод, который предсказывает, какие страницы могли бы скоро быть необходимы,
основываясь на страницах, которые уже в буферном пуле, независимо от порядка,
в котором были считаны те страницы.
innodb_random_read_ahead
отключен по умолчанию. См.
раздел 16.6.3.5.
innodb_adaptive_flushing
Определяет, скорректировать ли динамически уровень сброса flushing грязных страниц в буферном пуле, основываясь на рабочей нагрузке. Корректировка уровня потока динамически предназначена, чтобы избежать взрывов деятельности ввода/вывода. Эта установка включена по умолчанию. См. раздел 16.6.3.6 .
innodb_adaptive_flushing_lwm
Нижний процент redo log, при котором адаптивный сброс включен. См. раздел 16.6.3.7.
innodb_flush_neighbors
Определяет, сбрасывают ли страницы из буферного пула другие грязные страницы в том же самом экстенте. См. раздел 16.6.3.7.
innodb_flushing_avg_loops
Число итераций, для которых InnoDB сохраняет ранее сделанный снимок состояния сброса, управляя, как быстро адаптивный сброс отвечает на изменяющиеся рабочие нагрузки. См. раздел 16.6.3.7.
innodb_lru_scan_depth
Параметр, который влияет на алгоритмы и эвристику для работы
сброса для буферного пула. Прежде
всего интересен для исполнительных экспертов, настраивающих рабочие нагрузки
I/O. Это определяет как далеко вниз поток page_cleaner
сканирует
буферный пул LRU в поисках грязных
страниц для сброса. См.
раздел 16.6.3.7.
innodb_max_dirty_pages_pct
InnoDB
старается сбросить
данные из буферного пула так, чтобы процент
грязных страниц
не превысил это значение. Определите целое число в диапазоне от 0 до 99.
Значение по умолчанию 75. См.
раздел 16.6.3.6
.
innodb_max_dirty_pages_pct_lwm
Нижний уровень (в процентах) грязных страниц, где предварительному сбросу позволяют управлять отношением грязных страниц. Значение по умолчанию 0 отключает предварительно это поведение полностью.
См. раздел 16.6.3.7 .
innodb_buffer_pool_filename
Определяет название файла, который хранит список ID табличного
пространства и страницы, произведенный
innodb_buffer_pool_dump_at_shutdown
или
innodb_buffer_pool_dump_now
. См.
раздел 16.6.3.8.
innodb_buffer_pool_dump_at_shutdown
Определяет, сделать ли запись страниц, кэшируемых в буферном пуле, когда сервер MySQL закрыт, чтобы сократить процесс следующего перезапуска. См. раздел 16.6.3.8.
innodb_buffer_pool_load_at_startup
Определяет, что на запуске сервера MySQL буферный пул автоматически
подогревается, загружая те же самые
страницы, которые это содержало в более раннее время.
Как правило, используется в комбинации с
innodb_buffer_pool_dump_at_shutdown
. См.
раздел 16.6.3.8.
innodb_buffer_pool_dump_now
Немедленно делает запись страниц, кэшируемых в буферном пуле. См. раздел 16.6.3.8.
innodb_buffer_pool_load_now
Немедленно нагревает
буферный пул, загружая ряд страниц данных, не ожидая перезапуска сервера.
Может быть полезно, чтобы возвратить кэш-память к известному статусу
во время сопоставительного анализа или к готовому серверу MySQL, чтобы
возобновить его нормальную рабочую нагрузку после выполнения запросов для
отчетов или обслуживания. Как правило используется с
innodb_buffer_pool_dump_now
. См.
раздел 16.6.3.8.
innodb_buffer_pool_dump_pct
Определяет процент последний раз используемых страниц для каждого буферного пула для сброса. Диапазон от 1 до 100. См. раздел 16.6.3.8.
innodb_buffer_pool_load_abort
Прерывает процесс восстановления
буферного содержимого, вызванный
innodb_buffer_pool_load_at_startup
или
innodb_buffer_pool_load_now
. См.
раздел 16.6.3.8.
Вы можете сконфигурировать размер буферного пула офлайн (при запуске) или онлайн в то время, как сервер работает. Поведение, описанное в этом разделе, относится к обоим методам.
Увеличивая или уменьшая
innodb_buffer_pool_size
работа выполняется кусками. Размер куска
определен параметром конфигурации
innodb_buffer_pool_chunk_size
, у которого есть
значение по умолчанию 128M
.
Размер пула должен всегда быть равным или кратным числу
innodb_buffer_pool_chunk_size
*
innodb_buffer_pool_instances
. Если Вы конфигурируете
innodb_buffer_pool_size
к значению, которое не равно или кратно
числу
innodb_buffer_pool_chunk_size
*
innodb_buffer_pool_instances
, размер пула автоматически
скорректирован к значению, которое равно или кратно этому числу, но
не меньше чем указанный буферный размер пула.
В следующем примере
innodb_buffer_pool_size
установлен в 8G
, и
innodb_buffer_pool_instances
установлен в 16
.
innodb_buffer_pool_chunk_size
128M
,
что является значением по умолчанию.
8G
допустимое значение
innodb_buffer_pool_size
, потому что 8G
кратно
innodb_buffer_pool_instances=16
*
innodb_buffer_pool_chunk_size=128M
, которое 2G
.
shell> mysqld --innodb_buffer_pool_size=8G --innodb_buffer_pool_instances=16 mysql> SELECT @@innodb_buffer_pool_size/1024/1024/1024; +------------------------------------------+ | @@innodb_buffer_pool_size/1024/1024/1024 | +------------------------------------------+ | 8.000000000000 | +------------------------------------------+
В этом примере
innodb_buffer_pool_size
установлен в 9G
и
innodb_buffer_pool_instances
установлен в 16
.
innodb_buffer_pool_chunk_size
128M
, что является
значением по умолчанию. В этом случае 9G
не кратно
innodb_buffer_pool_instances=16
*
innodb_buffer_pool_chunk_size=128M
, так что
innodb_buffer_pool_size
скорректирован к 10G
,
что является следующим числом, кратным
innodb_buffer_pool_chunk_size
*
innodb_buffer_pool_instances
, но не меньше чем
указанный размер пула.
shell> mysqld --innodb_buffer_pool_size=9G --innodb_buffer_pool_instances=16 mysql> SELECT @@innodb_buffer_pool_size/1024/1024/1024; +------------------------------------------+ | @@innodb_buffer_pool_size/1024/1024/1024 | +------------------------------------------+ | 10.000000000000 | +------------------------------------------+
innodb_buffer_pool_chunk_size
может быть увеличен или уменьшен с
шагом в 1MB (1048576 байт), но может быть изменен только при запуске в
командной строки или в конфигурационном файле MySQL.
Командная строка:
shell> mysqld --innodb_buffer_pool_chunk_size=134217728
Конфигурационный файл:
[mysqld] innodb_buffer_pool_chunk_size=134217728
Следующие условия применяются, изменяя
innodb_buffer_pool_chunk_size
:
Если новое значение
If the new
innodb_buffer_pool_chunk_size
*
innodb_buffer_pool_instances
больше, чем текущий буферный размер
пула, когда буферный пул инициализирован,
innodb_buffer_pool_chunk_size
является усеченным к
innodb_buffer_pool_size
/
innodb_buffer_pool_instances
.
Например, если буферный пул инициализирован с размером
2GB
(2147483648 байт), 4
экземплярами
пула и размером куска 1GB
(1073741824 байт),
размер куска является усеченным к значению, равному
innodb_buffer_pool_size
/
innodb_buffer_pool_instances
, как показано ниже:
shell> mysqld --innodb_buffer_pool_size=2147483648 --innodb_buffer_pool_instances=4 --innodb_buffer_pool_chunk_size=1073741824; mysql> SELECT @@innodb_buffer_pool_size; +---------------------------+ | @@innodb_buffer_pool_size | +---------------------------+ | 2147483648 | +---------------------------+ mysql> SELECT @@innodb_buffer_pool_instances; +--------------------------------+ | @@innodb_buffer_pool_instances | +--------------------------------+ | 4 | +--------------------------------+ # Chunk size was set to 1GB (1073741824 bytes) on startup but was # truncated to innodb_buffer_pool_size / innodb_buffer_pool_instances mysql> SELECT @@innodb_buffer_pool_chunk_size; +---------------------------------+ | @@innodb_buffer_pool_chunk_size | +---------------------------------+ | 536870912 | +---------------------------------+
innodb_buffer_pool_chunk_size
*
innodb_buffer_pool_instances
. Если Вы изменяете
innodb_buffer_pool_chunk_size
,
innodb_buffer_pool_size
автоматически скорректирован к значению,
которое равно или кратно
innodb_buffer_pool_chunk_size
*
innodb_buffer_pool_instances
не меньше, чем текущий буферный размер пула. Корректировка происходит, когда
буферный пул инициализирован. Это поведение
продемонстрировано в следующем примере:
# The buffer pool has a default size of 128MB (134217728 bytes) mysql> SELECT @@innodb_buffer_pool_size; +---------------------------+ | @@innodb_buffer_pool_size | +---------------------------+ | 134217728 | +---------------------------+ # The chunk size is also 128MB (134217728 bytes) mysql> SELECT @@innodb_buffer_pool_chunk_size; +---------------------------------+ | @@innodb_buffer_pool_chunk_size | +---------------------------------+ | 134217728 | +---------------------------------+ # There is a single buffer pool instance mysql> SELECT @@innodb_buffer_pool_instances; +--------------------------------+ | @@innodb_buffer_pool_instances | +--------------------------------+ | 1 | +--------------------------------+ # Chunk size is decreased by 1MB (1048576 bytes) at startup # (134217728 - 1048576 = 133169152): shell> mysqld --innodb_buffer_pool_chunk_size=133169152 mysql> SELECT @@innodb_buffer_pool_chunk_size; +---------------------------------+ | @@innodb_buffer_pool_chunk_size | +---------------------------------+ | 133169152 | +---------------------------------+ # Buffer pool size increases from 134217728 to 266338304 # Buffer pool size is automatically adjusted to a value that is equal to # or a multiple of innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances # that is not less than current buffer pool size mysql> SELECT @@innodb_buffer_pool_size; +---------------------------+ | @@innodb_buffer_pool_size | +---------------------------+ | 266338304 | +---------------------------+
Этот пример демонстрирует то же самое поведение, но с несколькими экземплярами буферного пула:
# The buffer pool has a default size of 2GB (2147483648 bytes) mysql> SELECT @@innodb_buffer_pool_size; +---------------------------+ | @@innodb_buffer_pool_size | +---------------------------+ | 2147483648 | +---------------------------+ # The chunk size is .5 GB (536870912 bytes) mysql> SELECT @@innodb_buffer_pool_chunk_size; +---------------------------------+ | @@innodb_buffer_pool_chunk_size | +---------------------------------+ | 536870912 | +---------------------------------+ # There are 4 buffer pool instances mysql> SELECT @@innodb_buffer_pool_instances; +--------------------------------+ | @@innodb_buffer_pool_instances | +--------------------------------+ | 4 | +--------------------------------+ # Chunk size is decreased by 1MB (1048576 bytes) at startup # (536870912 - 1048576 = 535822336): shell> mysqld --innodb_buffer_pool_chunk_size=535822336 mysql> SELECT @@innodb_buffer_pool_chunk_size; +---------------------------------+ | @@innodb_buffer_pool_chunk_size | +---------------------------------+ | 535822336 | +---------------------------------+ # Buffer pool size increases from 2147483648 to 4286578688 # Buffer pool size is automatically adjusted to a value that is equal to # or a multiple of innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances # that is not less than current buffer pool size of 2147483648 mysql> SELECT @@innodb_buffer_pool_size; +---------------------------+ | @@innodb_buffer_pool_size | +---------------------------+ | 4286578688 | +---------------------------+
Забота должна быть проявлена, изменяя
innodb_buffer_pool_chunk_size
, поскольку это значение может
увеличить размер буферного пула, как показано в примерах выше. Прежде чем Вы
измените
innodb_buffer_pool_chunk_size
, вычислите эффект, который это будет
иметь на
innodb_buffer_pool_size
, чтобы гарантировать, что получающийся
размер пула является приемлемым.
Чтобы избежать потенциальных исполнительных проблем, число кусков
(
innodb_buffer_pool_size
/
innodb_buffer_pool_chunk_size
) не должно превышать 1000.
Опция
innodb_buffer_pool_size
может быть установлена динамически,
используя командой SET
, разрешая Вам
изменить размеры буферного пула, не перезапуская сервер. Например:
mysql> SET GLOBAL innodb_buffer_pool_size=402653184;
Активные транзакции и операции через InnoDB
API
должны быть завершены прежде, чем изменить размеры буферного пула. Начиная
изменение размера, работа не запускается, пока все активные транзакции не
завершены. Как только работа по изменению размеров началась, новые
транзакции и операции, которые требуют доступа к буферному пулу, ждут, пока
работа не закончится. Исключение: параллельный доступ к буферному пулу
разрешен в то время, когда буферный пул дефрагментируется.
Недостаток разрешения параллельного доступа состоит в том, что это может
привести к временной нехватке доступных страниц, в то время
как страницы удаляются.
Вложенные транзакции могут отвалиться, если начаты после того, как началась работа по изменению размера буфера.
Innodb_buffer_pool_resize_status
сообщает о ходе изменения
размеров буферного пула:
mysql> SHOW STATUS WHERE Variable_name='InnoDB_buffer_pool_resize_status'; +----------------------------------+----------------------------------+ | Variable_name | Value | +----------------------------------+----------------------------------+ | Innodb_buffer_pool_resize_status | Resizing also other hash tables. | +----------------------------------+----------------------------------+
Это также зарегистрировано в файле журнала ошибок сервера. Этот пример показывает записи, которые зарегистрированы, увеличивая размер буферного пула:
[Note] InnoDB: Resizing buffer pool from 134217728 to 4294967296. (unit=134217728) [Note] InnoDB: disabled adaptive hash index. [Note] InnoDB: buffer pool 0 : 31 chunks (253952 blocks) was added. [Note] InnoDB: buffer pool 0 : hash tables were resized. [Note] InnoDB: Resized hash tables at lock_sys, dictionary. [Note] InnoDB: completed to resize buffer pool from 134217728 to 4294967296. [Note] InnoDB: re-enabled adaptive hash index.
Этот пример показывает записи, которые зарегистрированы, уменьшая размер буферного пула:
[Note] InnoDB: Resizing buffer pool from 4294967296 to 134217728. (unit=134217728) [Note] InnoDB: disabled adaptive hash index. [Note] InnoDB: buffer pool 0 : start to withdraw the last 253952 blocks. [Note] InnoDB: buffer pool 0 : withdrew 253952 blocks from free list. tried to relocate 0 pages. (253952/253952) [Note] InnoDB: buffer pool 0 : withdrawn target 253952 blocks. [Note] InnoDB: buffer pool 0 : 31 chunks (253952 blocks) was freed. [Note] InnoDB: buffer pool 0 : hash tables were resized. [Note] InnoDB: Resized hash tables at lock_sys, dictionary. [Note] InnoDB: completed to resize buffer pool from 4294967296 to 134217728. [Note] InnoDB: re-enabled adaptive hash index.
Работа изменения размеров выполнена фоновым потоком. Увеличивая размер буферного пула:
Добавляются страницы в кусок
(размер куска определен
innodb_buffer_pool_chunk_size
).
В то время как эти операции происходят, другие потоки заблокированы на доступ к буферному пулу.
Уменьшение размера буферного пула:
Дефрагментация пула и освобождение страниц.
куске
(размер куска определен
innodb_buffer_pool_chunk_size
).Из этих операций только дефрагментация и удаление страниц позволяют другим потокам доступ к буферному пулу одновременно.
Для систем с буферными пулами в диапазоне нескольких гигабайт
деление буферного пула на отдельные экземпляры может улучшить параллелизм,
уменьшая столкновения потоков при доступе к кэшируемым страницам.
Эта особенность как правило предназначается для систем с
многогигабайтным буфером.
Многократные буферные экземпляры сконфигурированы, используя опцию
innodb_buffer_pool_instances
, и Вы могли бы также корректировать
innodb_buffer_pool_size
.
Когда буферный пул является большим, много запросов данных могут быть удовлетворены, получая из памяти. Вы могли бы столкнуться с узкими местами от многократных потоков, пытающихся получить доступ к буферному пулу сразу. Вы можете позволить многим буферным пулам минимизировать это. Каждая страница, которая сохранена в (или считана из) буферного пула, назначена на один из буферных пулов беспорядочно, используя хеширующую функцию. Каждый буферный пул управляет своими собственными свободными списками, списками потока, LRU и всеми другими структурами данных, соединенными с буферным пулом. До MySQL 8.0 каждый буферный пул был защищен его собственным mutex. В MySQL 8.0 и позже mutex был заменен несколькими списками и хешем, чтобы уменьшить накладные расходы.
Чтобы включить многократные буферы, установите опцию
innodb_buffer_pool_instances
к значению больше 1 (значение по
умолчанию), но до 64 (максимум).
Эта опция вступает в силу только, когда Вы устанавливаете
innodb_buffer_pool_size
к размеру 1GB или больше.
Полный размер, который Вы определяете, разделен среди всех буферных пулов.
Для лучшей эффективности, определите комбинацию
innodb_buffer_pool_instances
и
innodb_buffer_pool_size
так, чтобы каждый экземпляр буфера
был по крайней мере в 1GB.
Для информации об изменении размера буфера InnoDB
см.
раздел 16.6.3.2.
Вместо того, чтобы использовать строгий алгоритм
LRU InnoDB
использует метод, чтобы минимизировать объем данных, который принесен в
буферный пул, но не используется
никогда больше. Цель состоит в том, чтобы удостовериться, что часто
используемые (горячие) страницы
остаются в буферном пуле, как раз когда
предвыборка и
полное сканирование таблицы
вводят новые блоки, которые не факт, что будут использованы позже.
Недавно считанные блоки вставлены в середину списка LRU. Все недавно
прочитанные страницы вставлены в место, которое по умолчанию занимает место в
3/8
от хвоста списка LRU. Страницы перемещены в начало списка,
когда к ним получают доступ в буферном пуле впервые.
Таким образом, страницы, к которым никогда не получают доступ, никогда не
добираются до передней части списка LRU и вычеркиваются
скорее, чем со строгим подходом LRU. Это расположение делит список LRU на два
сегмента, где страницы сдвигаются вниз от точки вставки.
Для объяснения внутренних работ буферного пула InnoDB
и специфических особенностей алгоритма LRU см.
раздел 16.6.3.1.
Вы можете управлять точкой вставки в списке LRU и выбрать
применяет ли InnoDB
ту же самую оптимизацию к блокам,
принесенным в буферный пул просмотром таблицы или индекса. Параметр
конфигурации
innodb_old_blocks_pct
управляет процентом
старых блоков в списке LRU. Значение по умолчанию
innodb_old_blocks_pct
37
соответствует оригинальному отношению 3/8.
Диапазон значения от 5
(новые страницы в буфере стареют очень
быстро) до 95
(только 5% буферного пула сохранены для горячих
страниц, делая алгоритм близким к знакомой стратегии LRU).
Оптимизация, которая препятствует буферному пулу взбалтываться
предвыборкой, может избежать подобных проблем из-за просмотров таблицы или
индекса. В этих просмотрах к странице данных как правило получают доступ
несколько раз в быстрой последовательности и никогда не затрагивают ее снова.
Параметр конфигурации
innodb_old_blocks_time
определяет окно времени (в
миллисекундах) после первого доступа к странице, во время которого к ней
можно получить доступ, не перемещая ее в начало списка LRU.
Значение по умолчанию
innodb_old_blocks_time
1000
. Увеличение этого
значения делает все больше блоков стареющими быстро.
innodb_old_blocks_pct
и
innodb_old_blocks_time
являются динамическими, глобальными и может быть определены в файле опции
MySQL (my.cnf
или my.ini
)
или изменены во время выполнения через SET GLOBAL
.
Изменение настроек требует привилегии SUPER
.
Помочь Вам измерить эффект этих параметров может отчет команды
SHOW ENGINE INNODB STATUS
о буферной статистике пула.
Для деталей см. раздел
16.6.3.9.
Поскольку эффекты этих параметров могут значительно различаться в зависимости от Вашей конфигурации аппаратных средств, Ваших данных и деталей Вашей рабочей нагрузки, всегда определяйте эффективность, чтобы проверить что получилось прежде, чем изменить эти настройки в любой критической по отношению к работе или производственной среде.
В смешанных рабочих нагрузках, где большая часть деятельности OLTP с
с периодическими запросами сообщения пакета, которые приводят к большим
просмотрам, установка значения
innodb_old_blocks_time
во время пакетных выполнений может помочь
сохранить рабочий набор нормальной рабочей нагрузки в буферном пуле.
Просматривая большие таблицы, которые не могут поместиться полностью в
буферном пуле, установите
innodb_old_blocks_pct
к маленькому значению, чтобы не дать данным, которые только
считаны однажды, заполнить весь буфер. Например, установка
innodb_old_blocks_pct=5
ограничивает эти данные 5%
размера буферного пула.
Когда просматриваете маленькие таблицы, которые действительно вписываются
в память, уменьшите накладные расходы на перемещение страниц в буфере,
установив
innodb_old_blocks_pct
в его значение по умолчанию или еще выше,
например, innodb_old_blocks_pct=50
.
Эффект изменения
innodb_old_blocks_time
предсказать трудней, чем
innodb_old_blocks_pct
, так как он
изменяется больше с рабочей нагрузкой. Чтобы достигнуть оптимального
значения, проведите свои собственные точки отсчета, если изменение
производительности от корректировки
innodb_old_blocks_pct
недостаточно.
Предвыборка это запрос
ввода/вывода предварительно принести страницы в
буферный пул
асинхронно, в ожидании, что эти страницы скоро будут необходимы. Запросы
получают все страницы в одном экстенте
. InnoDB
использует два алгоритма предвыборки, чтобы
улучшить работу ввода/вывода:
Линейная предвыборка
метод, который предсказывает, какие страницы могли бы скоро быть необходимы,
основываясь на страницах в буферном пуле. Вы управляете, когда
InnoDB
выполняет работу предвыборки, корректируя число
последовательных доступов к странице, требуемых, чтобы вызвать асинхронный
запрос чтения, используя параметр конфигурации
innodb_read_ahead_threshold
.
Параметр конфигурации
innodb_read_ahead_threshold
контролирует, насколько
чувствителен InnoDB
в обнаружении образцов последовательного
доступа страницы. Если число чтения страниц последовательно из экстента
больше чем или равно
innodb_read_ahead_threshold
, InnoDB
начинает асинхронную работу чтения следующего экстента целиком.
innodb_read_ahead_threshold
может быть установлен в любое значение
от 0 до 64. По умолчанию 56. Чем выше значение, тем более строгая проверка
образца доступа. Например, если Вы устанавливаете значение в 48,
InnoDB
вызывает линейный запрос предвыборки только когда к 48
страницам в текущем экстенте получили доступ последовательно.
Если значение 8, InnoDB
вызывает линейный запрос предвыборки
даже если только к 8 страницам в экстенте получают доступ последовательно.
Вы можете установить значение этого параметра в
файле конфигурации MySQL
или изменить это динамически с помощью SET GLOBAL
, но для этого
надо иметь привилегиюSUPER
.
Случайная это метод,
который предсказывает, когда страницы могли бы скоро быть необходимы,
основываясь на страницах, которые уже в буферном пуле, независимо от порядка,
в котором были считаны те страницы. Если 13 последовательных страниц из
того же самого экстента найдены в буферном пуле, InnoDB
делает запрос предварительно загрузить остающиеся страницы экстента.
Чтобы активировать эту опцию, установите переменную конфигурации
innodb_random_read_ahead
в ON
.
Команда SHOW ENGINE INNODB STATUS
показывает статистику,
чтобы помочь Вам оценить эффективность алгоритма чтения. Статистические
данные включают счетчики для следующих глобальных переменных состояния:
Эта информация может быть полезной, точно настраивая
innodb_random_read_ahead
.
Для получения дополнительной информации о работе ввода/вывода см. разделы 9.5.8 и 9.12.1.
InnoDB
выполняет определенные задачи в фоне, включая
сброс
of грязных страниц (те страницы,
которые были изменены, но еще не записаны в файлы базы данных) из
буферного пула.
InnoDB
начинает сбрасывать страницы пула, когда процент
грязных страниц в буферном пуле достигает нижнего предела, определенного
innodb_max_dirty_pages_pct_lwm
. Эта опция предназначена, чтобы
управлять отношением грязных страниц в буферном пуле и идеально
препятствовать тому, чтобы процент грязных страниц достиг
innodb_max_dirty_pages_pct
. Если процент грязных страниц в
буферном пуле превышает
innodb_max_dirty_pages_pct
, InnoDB
начинает сброс буферных страниц немедленно.
InnoDB
использует алгоритм, чтобы оценить
необходимый уровень сброса, основанный на скорости генерации журнала redo
и действующего коэффициента сброса. Намерение состоит в том, чтобы пригладить
эффективность работы, гарантируя, что буферная деятельность потока не отстает
от потребности сохранить буферный пул чистым.
Автоматическая корректировка уровня сброса может помочь избежать внезапных
падений пропускной способности, когда сброс буферного пула начинает мешать
обычному вводу-выводу.
InnoDB
использует файлы системного журнала круговым способом.
Прежде, чем снова использовать часть файла системного журнала,
InnoDB
сбрасывает на диск все грязные буферные страницы, чьи
записи содержатся в этой части файла системного журнала, это процесс
острой контрольной точки.
Если рабочая нагрузка записи интенсивная, она производит много информации в
журнале redo. Если все свободное место в файлах системного журнала
израсходовано, острая контрольная точка происходит, вызывая временное
сокращение пропускной способности. Эта ситуация может произойти, даже если
innodb_max_dirty_pages_pct
не достигнут.
InnoDB
использует эвристический алгоритм, чтобы избежать
такого сценария, измеряя число грязных страниц в буферном пуле и уровень
прироста журнала redo. Основываясь на этих числах, InnoDB
решает, сколько грязных страниц сбросить из буферного пула каждую секунду.
Этот адаптивный алгоритм в состоянии иметь дело с внезапными
изменениями в рабочей нагрузке.
Внутренний сопоставительный анализ показал, что этот алгоритм не только поддерживает пропускную способность в течение долгого времени, но и может также значительно улучшить полную пропускную способность.
Поскольку адаптивный сброс может значительно затронуть образец
ввода/вывода рабочей нагрузки, параметр
innodb_adaptive_flushing
позволяет Вам выключать эту особенность.
Значение по умолчанию для
innodb_adaptive_flushing
TRUE
,
адаптивный алгоритм включен. Вы можете установить значение этого параметра в
файле опции MySQL (my.cnf
или my.ini
)
или изменить это динамически с помощью
SET GLOBAL
, имея привилегию SUPER
.
Для информации о точной настройке сброса пула в InnoDB
см. раздел 16.6.3.7.
Для получения дополнительной информации о работе ввода/вывода
InnoDB
см. раздел
9.5.8.
Опции
innodb_flush_neighbors
и
innodb_lru_scan_depth
позволяют Вам точно настраивать определенные аспекты процесса
сброса для
буферного пула
InnoDB
. Эти опции прежде всего помогают
рабочим нагрузкам с интенсивной
записью. С большой активностью DML
сброс может отстать, если это недостаточно агрессивно, приводя к чрезмерному
использованию памяти в буферном пуле. С другой стороны сброс
может перегрузить Вашу систему ввода/вывода, если этот механизм слишком
агрессивен. Идеальные настройки зависят от Вашей рабочей нагрузки, образцов
доступа к данным и конфигурации хранения (например, хранятся ли данные на
HDD или
SSD).
Для систем с постоянными тяжелыми рабочими нагрузками или рабочими нагрузками, которые широко колеблются, несколько параметров конфигурации позволяют Вам точно настраивать поведение сброса для таблиц:
Эти опции подпитывают формулу, используемую параметром
innodb_adaptive_flushing
.
Опции
innodb_adaptive_flushing
,
innodb_io_capacity
и
innodb_max_dirty_pages_pct
ограничены или расширены следующими опциями:
Механизм адаптивного сброса
InnoDB
не является подходящим во всех случаях. Это приносит
большинство пользы, когда журнал redo
рискует заполниться. Опция
innodb_adaptive_flushing_lwm
определяет процент
нижнего предела заполнения журнала redo,
когда этот порог пересечен, InnoDB
включает адаптивный сброс даже если не определена опция
innodb_adaptive_flushing
.
Если активность сброса слишком мала, InnoDB
может сбрасывать более настойчиво, чем указано в
innodb_io_capacity
.
innodb_io_capacity_max
представляет верхний предел нагрузки
ввода/вывода, используемой в таких чрезвычайных ситуациях, чтобы пик
ввода/вывода не потреблял всю пропускную способность сервера.
InnoDB
старается сбросить данные из буферного пула так, чтобы
процент грязных страниц не превысил значение
innodb_max_dirty_pages_pct
. Значение по умолчанию для
innodb_max_dirty_pages_pct
75.
innodb_max_dirty_pages_pct
устанавливает цель для активности
сброса. Это не затрагивает уровень сброса. Для информации об управлении
уровнем сброса см.
раздел 16.6.3.6.
Опция
innodb_max_dirty_pages_pct_lwm
определяет значение, которое
представляет процент грязных страниц, при котором предварительному сбросу
позволяют управлять отношением грязных страниц и идеально препятствовать
тому, чтобы процент грязных страниц достиг
innodb_max_dirty_pages_pct
. Значение
innodb_max_dirty_pages_pct_lwm=0
отключает
предсброс.
Большинство опций, на которые ссылаются выше, наиболее применимы к серверам, которые работают с большими рабочими нагрузками по записи в течение долгих промежутков времени.
innodb_flushing_avg_loops
определяет число итераций для которого
InnoDB
сохраняет ранее расчитанный снимок состояния сброса,
который управляет, как быстро адаптивный сброс отвечает на изменения
загрузки. Указание большого значения для
innodb_flushing_avg_loops
предписывает хранить
расчитанный снимок дольше, таким образом, адаптивный сброс
отвечает более медленно. Высокое значение также уменьшает позитивные отклики
между передним планом и фоновой работой, но задание большого значения очень
важно, чтобы гарантировать, что использование InnoDB
журнала
redo не достигает 75% (предел, при котором запускается сброс), и что
innodb_max_dirty_pages_pct
сохраняет число грязных страниц на
уровне, который является подходящим для рабочей нагрузки.
Системы с последовательными рабочими нагрузками, большим
innodb_log_file_size
и маленькими пиками, которые не достигают 75% использования места
в журнале redo, должны использовать верхний уровень
innodb_flushing_avg_loops
, чтобы продолжить сбрасывать
столь гладко, насколько возможно. Для систем с экстремальными пиками
загрузки или файлами системного журнала, которые не обеспечивают много
пространства, должны использовать меньшее значение
innodb_flushing_avg_loops
.
Меньшее значение позволяет сбрасывать так, чтобы точно отследить загрузку и
помогает избежать использования 75% пространства журнала redo.
Чтобы уменьшить период загрузки
после перезапуска сервера, InnoDB
сохраняет процент последний
раз используемых страниц для каждого буферного пула при завершении работы
сервера и восстанавливает эти страницы при запуске сервера. Процент недавно
используемых страниц, который сохранен, определен параметром
innodb_buffer_pool_dump_at_shutdown
.
После перезапуска занятого сервера как правило есть период разминки с устойчиво увеличивающейся пропускной способностью, поскольку дисковые страницы, которые были в буферном пуле, возвращены в память (поскольку те же самые данные запрошены, обновлены и так далее). Способность восстановить буферный пул при запуске сокращает период разминки, перезагружая дисковые страницы, которые были в буферном пуле перед перезапуском вместо того, чтобы ждать операций DML, чтобы получить доступ к соответствующим строкам. Кроме того, запросы ввода/вывода могут быть выполнены в больших пакетах, делая полный ввод/вывод быстрее. Загрузка страниц происходит в фоне и не задерживает запуск базы данных.
В дополнение к сохранению состояния буферного пула при завершении работы и восстановлении его при запуске, Вы можете сохранить и восстановить состояние буферного пула в любое время, в то время как сервер работает. Например, Вы можете сохранить состояние после достижения устойчивой пропускной способности при устойчивой рабочей нагрузке. Вы можете также восстановить предыдущее состояние буферного пула после выполнения отчетов или заданий обслуживания, которые приносят страницы данных в буферный пул, которые нужны только для тех операций, или после выполнения некоторой другой нетипичной рабочей нагрузки.
Даже при том, что буферный пул может быть много
гигабайт в размере, данные пула, которые InnoDB
сохраняет на
диск являются крошечными. Только ID табличного пространства и ID страницы,
необходимые, чтобы определить местонахождение соответствующих страниц,
сохранены на диск. Эта информация получена из таблицы
INNODB_BUFFER_PAGE_LRU
INFORMATION_SCHEMA
.
По умолчанию ID табличного пространства и страницы сохранены в файле
ib_buffer_pool
, в кталоге данных InnoDB
.
Имя файла и местоположение могут быть изменены, используя параметр
innodb_buffer_pool_filename
.
Поскольку данные кэшируются и устаревают в пуле, нет никакой проблемы, если дисковые страницы были недавно обновлены, или если работа DML вовлекает данные, которые еще не были загружены. Механизм загрузки пропускает требуемые страницы, которые больше не существуют.
Основной механизм вовлекает фоновый поток, чтобы выполнить операции загрузки и дамп.
Дисковые страницы от сжатых таблиц загружены в буферный пул в их сжатой форме. Страницы разсжаты, когда к содержанию страницы получают доступ во время операций DML. Поскольку разсжатие страниц является процессом, серьезно нагружающим центральный процессор, более эффективно для параллелизма выполнить работу в потоке соединения, а не в единственном потоке, который выполняет работу восстановления пула.
Прежде, чем вывести страницы из буферного пула, Вы можете сконфигурировать
процент используемых буферных страниц, которые Вы хотите вывести,
устанавливая опцию
innodb_buffer_pool_dump_pct
.
Если Вы планируете вывести буферные страницы в то время, как сервер работает,
Вы можете сконфигурировать опцию динамически:
SET GLOBAL innodb_buffer_pool_dump_pct=40;
Если Вы планируете вывести буферные страницы при
завершении работы сервера, надо установить
innodb_buffer_pool_dump_pct
в Вашем конфигурационном файле.
[mysqld] innodb_buffer_pool_dump_pct=40
Значение
innodb_buffer_pool_dump_pct
по умолчанию 25 (дамп 25%
используемых последний раз страниц).
Чтобы сохранить статус буферного пула при завершении работы сервера, сделайте следующее запрос до закрытия сервера:
SET GLOBAL innodb_buffer_pool_dump_at_shutdown=ON;
innodb_buffer_pool_dump_at_shutdown
включена по умолчанию.
Чтобы восстановить статус пула при запуске сервера, определите
опцию --innodb_buffer_pool_load_at_startup
, запуская сервер:
mysqld --innodb_buffer_pool_load_at_startup=ON;
innodb_buffer_pool_load_at_startup
включен по умолчанию.
Чтобы сохранить состояние буферного пула в то время, как сервер MySQL работает, сделайте следующее:
SET GLOBAL innodb_buffer_pool_dump_now=ON;
Чтобы восстановить состояние буферного пула в то время, как сервер MySQL работает, сделайте следующее:
SET GLOBAL innodb_buffer_pool_load_now=ON;
Чтобы вывести на экран процесс сохранения пула на диск, сделайте следующее:
SHOW STATUS LIKE 'Innodb_buffer_pool_dump_status';
Если работа еще не запустилась, вернется not started . Если работа завершена, время завершения напечатано (например, Finished at 110505 12:18:02). Если работа происходит, информация о статусе обеспечена (например, Dumping buffer pool 5/7, page 237/2873).
Чтобы вывести на экран процесс загрузки пула, сделайте следующее:
SHOW STATUS LIKE 'Innodb_buffer_pool_load_status';
Если работа еще не запустилась, вернется not started . Если работа завершена, время завершения напечатано (например, Finished at 110505 12:18:02). Если работа происходит, информация о статусе обеспечена (например, Loaded 123/22300 pages).
Чтобы прервать работу загрузки пула, сделайте следующее:
SET GLOBAL innodb_buffer_pool_load_abort=ON;
Вы можете контролировать ход загрузки пула, используя Performance Schema.
Следующий пример демонстрирует, как включить инструмент этапа событий
stage/innodb/buffer pool load
и связанные потребительские
таблицы, чтобы контролировать продвижение загрузки.
Для информации о дампе пула и процедурах загрузки, используемых в этом примере, см. раздел 16.6.3.8 . Для информации об инструментах этапа Performance Schema и связанных потребителях, см. раздел 23.9.5.
Включите инструмент stage/innodb/buffer pool load
:
mysql> UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE 'stage/innodb/buffer%';
events_stages_current
,
events_stages_history
и
events_stages_history_long
.
mysql> UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE '%stages%';
innodb_buffer_pool_dump_now
.
mysql> SET GLOBAL innodb_buffer_pool_dump_now=ON;
mysql> SHOW STATUS LIKE 'Innodb_buffer_pool_dump_status'\G *************************** 1. row *************************** Variable_name: Innodb_buffer_pool_dump_status Value: Buffer pool(s) dump completed at 150202 16:38:58
innodb_buffer_pool_load_now
:
mysql> SET GLOBAL innodb_buffer_pool_load_now=ON;
events_stages_current
. Столбец WORK_COMPLETED
показывает число загруженных страниц пула. WORK_ESTIMATED
обеспечивает оценку остающейся работы в страницах.
mysql> SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED FROM performance_schema.events_stages_current; +-------------------------------+----------------+----------------+ | EVENT_NAME | WORK_COMPLETED | WORK_ESTIMATED | +-------------------------------+----------------+----------------+ | stage/innodb/buffer pool load | 5353 | 7167 | +-------------------------------+----------------+----------------+
Таблица
events_stages_current
возвращает пустой набор, если работа
загрузки пула завершилась. В этом случае Вы можете проверить таблицу
events_stages_history
, чтобы рассмотреть данные для завершенного случая. Например:
mysql> SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED FROM performance_schema.events_stages_history; +-------------------------------+----------------+----------------+ | EVENT_NAME | WORK_COMPLETED | WORK_ESTIMATED | +-------------------------------+----------------+----------------+ | stage/innodb/buffer pool load | 7167 | 7167 | +-------------------------------+----------------+----------------+
Вы можете также контролировать ход загрузки пула, используя Performance
Schema, загружая буферный пул при запуске с использованием
innodb_buffer_pool_load_at_startup
. В этом случае инструмент
stage/innodb/buffer pool load
и связанные потребители должны быть включены при запуске. Для получения
дополнительной информации см.
раздел 23.2.2
.
Вывод InnoDB
Standard Monitor,
к которому можно получить доступ, используя
SHOW ENGINE INNODB STATUS
, обеспечивает метрики, которые принадлежат работе с пулом
InnoDB
. Буферные метрики пула расположены в разделе
BUFFER POOL AND MEMORY
вывода InnoDB
Standard
Monitor и подобны следующему:
---------------------- BUFFER POOL AND MEMORY ---------------------- Total large memory allocated 2198863872 Dictionary memory allocated 776332 Buffer pool size 131072 Free buffers 124908 Database pages 5720 Old database pages 2071 Modified db pages 910 Pending reads 0 Pending writes: LRU 0, flush list 0, single page 0 Pages made young 4, not young 0 0.10 youngs/s, 0.00 non-youngs/s Pages read 197, created 5523, written 5060 0.00 reads/s, 190.89 creates/s, 244.94 writes/s Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000 Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s LRU len: 5720, unzip_LRU len: 0 I/O sum[0]:cur[0], unzip sum[0]:cur[0]
Следующая таблица описывает метрики пула, о которых сообщает
InnoDB
Standard Monitor.
Средние числа в секунду в выводе InnoDB
Standard Monitor
основаны на прошедшем времени с последнего вывода
InnoDB
Standard Monitor.
Таблица 16.2. Метрики пула
Имя | Описание |
---|---|
Total memory allocated | Полная память, которая выделена для буферного пула в байтах. |
Dictionary memory allocated | Полная память, выделенная для
словаря данных InnoDB в байтах. |
Buffer pool size | Полный размер в страницах буферного пула. |
Free buffers | Полный размер в страницах свободного списка. |
Database pages | Полный размер в страницах списка LRU. |
Old database pages | Полный размер в страницах старого подсписка LRU. |
Modified db pages | Текущее число страниц, измененных в буферном пуле. |
Pending reads | Число страниц, ждущих считывания в пул. |
Pending writes LRU | Число старых грязных страниц в буферном пуле, которые будут записаны от конца списка LRU. |
Pending writes flush list | Число страниц пула, которые будут сброшены во время установки контрольных точек. |
Pending writes single page | Число независимых страниц в ожидании записи в буферном пуле. |
Pages made young | Общее количество молодых страниц в списке LRU (перемещенных к началу подсписка новых страниц). |
Pages made not young | Общее количество страниц, не сделанных молодыми в списке LRU (страницы, которые остались в подсписке старых, не будучи сделанным молодыми). |
youngs/s | Среднее число доступов в секунду к старым страницам в списке LRU, которые привели к созданию молодых страниц. См. примечания, которые следуют за этой таблицей для получения дополнительной информации. |
non-youngs/s | Среднее число доступов в секунду к старым страницам в списке LRU, которые не привели к созданию молодых страниц. |
Pages read | Общее количество страниц, прочитанных из буферного пула. |
Pages created | Общее количество страниц, созданных в буферном пуле. |
Pages written | Общее количество страниц, записанных из буферного пула. |
reads/s | Среднее число в секунду прочитанных страниц. |
creates/s | Среднее число в секунду создаваемых буферных страниц. |
writes/s | Среднее число записываемых буферных страниц в секунду. |
Buffer pool hit rate | Частота успешных обращений к странице для страниц из буферной памяти, а не с диска. |
young-making rate | Средняя частота успешных обращений, в которых доступ к странице привел к созданию молодых страниц. |
not (young-making rate) | Средняя частота успешных обращений, в которых доступ к странице не привел к созданию молодых страниц. |
Pages read ahead | Среднее число операций предвыборки в секунду. |
Pages evicted without access | Среднее число вычеркнутых страниц в секунду, к которым не получен доступ из буферного пула. |
Random read ahead | Среднее число операций случайного чтения в секунду. |
LRU len | Полный размер в страницах списка LRU. |
unzip_LRU len | Полный размер в страницах списка unzip_LRU. |
I/O sum | Общее количество страниц списка LRU, к которым был доступ в течение прошлых 50 секунд. |
I/O cur | Общее количество страниц списка LRU, к которым получают доступ сейчас. |
I/O unzip sum | Общее количество страниц списка unzip_LRU, к которым получали доступ. |
I/O unzip cur | Общее количество страниц списка unzip_LRU, к которым получают доступ сейчас. |
Примечания:
Метрика youngs/s
касается только
старых страниц. Это основано на числе доступов к страницам, а не числе
страниц. Могут быть многократные доступы к данной странице, которые все
посчитаны. Если Вы видите очень низкое значение youngs/s
, когда
нет никакого большого появления просмотров, Вы, возможно, должны были бы
уменьшить время задержки или увеличить процент буферного пула, используемого
для старого подсписка. Увеличение процента делает старый подсписок больше,
таким образом, у страниц в этом подсписке уходит больше времени, чтобы
переместиться в хвост и быть вычеркнутыми. Это увеличивает вероятность, что к
страницам получат доступ снова и сделают их молодыми.
non-youngs/s
касается только
старых страниц. Это основано на числе доступов к страницам, а не числе
страниц. Могут быть многократные доступы к данной странице, которые все
посчитаны. Если Вы не видите много non-youngs/s
, когда Вы
делаете большое сканирование таблицы (и много youngs/s
),
увеличьте значение задержки.young-making
учитывает доступы ко всем страницам
пула, не только доступы к страницам в старом подсписке. Коэффициенты
young-making
и not
обычно не составляют в сумме
полную частоту успешных обращений к пулу.not (young-making rate)
средняя частота успешных обращений,
в которой доступы к страницам не привели к созданию молодых страниц из-за
задержки, определенной
innodb_old_blocks_time
, или из-за попаданий на страницы
в новом подсписке, которые не приводили к страницам, перемещаемым к началу.
Этот уровень составляет доступы ко всем страницам пула, не только доступы к
страницам в старом подсписке.Переменные статуса сервера
пула InnoDB
и таблица
INNODB_BUFFER_POOL_STATS
обеспечивает многие из тех же самых
метрик пула, найденных в таблице
INNODB_BUFFER_POOL_STATS
, см.
пример 16.19.
Когда INSERT
,
UPDATE
и
DELETE
выполнены на таблице, значения индексированных столбцов (особенно значения
вторичных ключей) часто находятся в несортированном порядке,
требуя существенного ввода/вывода, чтобы принести вторичный индекс.
InnoDB
имеет буфер
изменений, который кэширует изменения вторичного индекса, когда
соответствующая страница не находится в
буферном пуле, таким образом
избегая дорогих операций ввода/вывода, не читая немедленно страницу с диска.
Буферизованные изменения слиты, когда страница загружена в буферный пул, и
обновленная страница позже сбрасывается на диск. Основной поток
InnoDB
объединяет изменения, когда сервер почти неактивен, и во
время медленной парковки.
Поскольку это может привести к меньшему количеству обращений к диску, эта особенность является самой ценной для рабочих нагрузок, которые имеют большой ввод-вывод, например приложения с большим объемом операций DML, таких как большой объем вставок.
Однако, буфер изменения занимает часть буферного пула, уменьшая память, доступную страницам данных о кэше. Если рабочий набор данных почти помещается в буферный пул, или если Ваши таблицы имеют, относительно немногие вторичные индексы, может быть полезно отключить буферизацию изменения. Если работа помещается в буфере полностью, буферизация изменения не налагает дополнительных издержек, потому что это только относится к страницам, которые не находятся в буферном пуле.
Вы можете управлять степенью, в которой InnoDB
выполняет буферизацию изменения, используя параметр
innodb_change_buffering
. Вы можете включить или отключить
буферизацию для вставок и удалений (когда индексные записи
первоначально отмечены для удаления) и операций чистки (когда индексные
записи физически удалены). Обновления это комбинация вставки и удаления.
Значение по умолчанию для
innodb_change_buffering
all
.
Разрешенные значения
innodb_change_buffering
:
all
Значение по умолчанию: вставки в буфер, операции удаления и чистки.
Не буферизировать ничего.
Буферизировать только вставки.
Буферизировать только удаления.
Буферизировать только удаления и вставки.
Буферизировать физические операции удаления, которые происходят в фоне.
Вы можете установить
innodb_change_buffering
в файле опций MySQL
(my.cnf
или my.ini
) или измените это динамически с
помощью SET GLOBAL
(нужна привилегия SUPER
). Изменение установки затрагивает
буферизацию новых операций, слияние существующих буферизованных
записей не затронуто.
Подробности в разделе 16.4.2 . Для информации о конфигурировании размера буфера изменения см. раздел 16.6.4.1.
Опция
innodb_change_buffer_max_size
позволяет Вам конфигурировать
максимальный размер буфера изменения как процент полного размера буферного
пула. По умолчанию
innodb_change_buffer_max_size
установлена в 25. Максимум 50.
Вы могли бы рассмотреть увеличение
innodb_change_buffer_max_size
на сервере MySQL с тяжелой вставкой,
обновлением и удалением, где буферное слияние изменения не идет в ногу с
новыми буферными записями изменения, заставляя буфер изменения достичь его
максимального предела размера.
Вы могли бы рассмотреть уменьшение
innodb_change_buffer_max_size
на сервере MySQL со статическими данными, используемыми для отчетов,
или если буфер изменения потребляет слишком много места в памяти, которое
совместно использовано с буферным пулом, заставляя страницы стареть
скорее, чем надо.
Проверьте различные настройки с представительной рабочей нагрузкой, чтобы
определить оптимальную конфигурацию. Настройка
innodb_change_buffer_max_size
является динамической, что позволяет
Вам изменять ее, не перезапуская сервер.
InnoDB
использует потоки
операционной системы, чтобы обработать запросы от пользовательских
транзакций. Транзакции могут выпустить много запросов к
InnoDB
перед завершением. На современных операционных системах и
серверах с мультиядерными процессорами, где переключение контекста
эффективно, большинство рабочих нагрузок, выполнены хорошо без особого
предела на число параллельных потоков.
В ситуациях, где полезно минимизировать контекст, переключающийся между
потоками, InnoDB
может использовать много методов, чтобы
ограничить число параллельного выполнения потоков операционной системы
(и таким образом число запросов, которые обработаны в любой момент). Когда
InnoDB
получает новый запрос от пользовательского сеанса, если
число одновременно выполняющихся потоков дошло до предопределенного предела,
запрос спит в течение короткого времени прежде, чем попробует еще раз.
Запрос, который не может быть запланирован после сна, помещен в очередь
first-in/first-out и в конечном счете обработан. Потоки, ждущие блокировок,
не посчитаны в числе параллельного выполнения потоков.
Вы можете ограничить число параллельных потоков, устанавливая параметры
конфигурации
innodb_thread_concurrency
. Как только число выполняемых потоков
достигает этого предела, дополнительные потоки спят
в течение числа микросекунд, установленного параметром конфигурации
innodb_thread_sleep_delay
,
прежде, чем быть помещенными в очередь.
Вы можете установить параметр конфигурации
innodb_adaptive_max_sleep_delay
к самому высокому значению,
которое Вы разрешаете для
innodb_thread_sleep_delay
, и InnoDB
автоматически
корректирует
innodb_thread_sleep_delay
в зависимости от текущей и планируемой
активности потоков. Эта динамическая корректировка помогает механизму
планирования потока работать гладко в течение времен, когда система слегка
загружена и когда она занята максимально.
Значение по умолчанию для
innodb_thread_concurrency
и подразумеваемый предел значения по
умолчанию числа параллельных потоков был изменен в различных выпусках MySQL и
InnoDB
. Значение по умолчанию для
innodb_thread_concurrency
0
,
чтобы по умолчанию не было никакого предела числа
параллельного выполнения потоков.
InnoDB
отправляет потоки в спячку только, когда число
параллельных потоков ограничено. Когда нет никакого предела числа потоков,
все работают одинаково. Таким образом, если
innodb_thread_concurrency
0
, значение
innodb_thread_sleep_delay
проигнорировано.
Когда есть предел числа потоков (когда
innodb_thread_concurrency
> 0), InnoDB
уменьшает издержки переключения контекста, разрешая многократные запросы
во время выполнения одного запроса SQL, не
проверяя предела, установленного
innodb_thread_concurrency
. Так как запрос SQL
может включить многострочные операции в пределах InnoDB
,
InnoDB
назначает конкретное количество
тикетов, которые позволяют потоку неоднократно
планироваться с минимальными издержками.
Когда новый запрос SQL запускается, у потока нет никаких тикетов, и это
должно работать согласно
innodb_thread_concurrency
. Как только поток входит в
InnoDB
, этому назначают много тикетов, которые это может
использовать для того, чтобы впоследствии выполнить операции со строками.
Если тикеты заканчиваются, поток вычеркивается, и
innodb_thread_concurrency
снова отслеживается, чтобы
поместить поток назад в очередь first-in/first-out потоков ожидания.
Когда поток еще раз попадает туда, тикеты назначены снова. Число назначенных
тикетов определено глобальной опцией
innodb_concurrency_tickets
, 5000 по умолчанию. Потоку, который
ждет блокировки, дают один тикет, как только блокировка становится доступной.
Правильные значения этих переменных зависят от Вашей среды и рабочей
нагрузки. Попробуйте диапазон различных значений, чтобы определить, какое
значение работает на Ваших приложениях. Прежде, чем ограничить число
параллельного выполнения потоков, рассмотрите параметры конфигурации, которые
могут улучшить исполнение InnoDB
, например,
innodb_adaptive_hash_index
.
Для общей информации об обработке потока MySQL см. раздел 9.12.4.1.
InnoDB применяет фоновые потоки
, чтобы обслужить различные типы запросов ввода/вывода. Вы можете
сконфигурировать число фоновых потоков, используя параметры конфигурации
innodb_read_io_threads
и
innodb_write_io_threads
. Эти параметры показывают число фоновых
потоков, используемых для чтения и записи, соответственно. Они эффективны на
всех поддержанных платформах. Вы можете установить значение этих параметров в
файле опции MySQL (my.cnf
или my.ini
),
Вы не можете изменить их динамически. Значение по умолчанию для этих
параметров 4
допустимые значения 1-64
.
Цель этого изменения состоит в том, чтобы сделать InnoDB более
масштабируемым на системах высокого класса. Каждый фоновый поток может
обработать до 256 запросов ввода/вывода. Основной источник фонового
ввода/вывода это запросы
предвыборки. InnoDB
пытается сбалансировать загрузку входящих запросов таким способом, которым
большая часть фоновой доли потоков работает одинаково. InnoDB также пытается
выделить запросы чтения от того же самого экстента к тому же самому потоку,
чтобы увеличить возможности соединения запросов вместе.
Если у Вас есть подсистема ввода/вывода высокого класса, и Вы видите больше,
чем 64 ждущих чтения запросов в SHOW ENGINE INNODB STATUS
, Вы
могли бы извлечь пользу, увеличивая значение
innodb_read_io_threads
.
Для получения дополнительной информации о работе ввода/вывода InnoDB см. раздел 9.5.8.
Мастер-поток в InnoDB это поток, который выполняет различные задачи в фоне. Большинство этих задач связаны с вводом/выводом, такие, как сброс грязных страниц из буферного пула или запись изменений из буфера вставки в соответствующий вторичный индекс. Основной поток пытается выполнить эти задачи способом, который не оказывает негативное влияние на нормальную работу сервера. Это пытается оценить свободную доступную пропускную способность ввода/вывода и настроить свои действия, чтобы использовать в своих интересах эту свободную способность. Исторически InnoDB использовал твердое кодированное значение 100 IOPs (операций ввода/вывода в секунду) как полная способность ввода/вывода сервера.
Параметр
innodb_io_capacity
указывает на полную способность ввода/вывода,
доступную InnoDB. Эти параметры должны быть установлены к приблизительному
числу операций ввода/вывода, которые система может выполнить в секунду.
Значение зависит от Вашей системной конфигурации. Когда
innodb_io_capacity
задано, основной поток оценивает пропускную способность
ввода/вывода, доступную для фоновых задач, исходя из этого значения.
Установка значения в 100
возвращает к старому поведению.
Вы можете установить значение
innodb_io_capacity
к числу 100 или больше. Значение по умолчанию 200
,
отражает, что производительность типичных современных устройств ввода/вывода
выше, чем в первые годы MySQL. Как правило, значения около предыдущего
значения по умолчанию 100 являются подходящими для устройств хранения данных
потребительского уровня, таких как жесткие диски до 7200 RPM.
Более быстрые жесткие диски, конфигурации RAID и SSD
извлекают выгоду из более высоких значений.
innodb_io_capacity
задает полный предел для всех экземпляров буферного пула. Когда
грязные страницы сбрасываются, предел
innodb_io_capacity
разделен одинаково среди экземпляров буферного пула.
Для получения дополнительной информации см. описание переменной
innodb_io_capacity
.
Вы можете установить значение этого параметра в файле опций MySQL
или изменить динамически с помощью SET GLOBAL
, при
наличии привилегии SUPER
.
Опция
innodb_flush_sync
предписывает игнорировать
innodb_io_capacity
во время взрывов деятельности ввода/вывода, которые происходят в
контрольных точках.
innodb_flush_sync
включена по умолчанию.
В более ранних выпусках MySQL основной поток InnoDB
также
выполнял любые необходимые операции чистки
. Те операции ввода/вывода теперь выполнены другими фоновыми потоками,
числом которых управляет опция
innodb_purge_threads
.
Для получения дополнительной информации о работе ввода/вывода InnoDB см. раздел 9.5.8.
Много InnoDB mutex и rw-блокировок сохранены в течение короткого времени. На мультиядерной системе может быть более эффективно для потока непрерывно проверять, может ли это приобрести mutex или rw-блокировку некоторое время перед сном. Если mutex или rw-блокировка становятся доступными во время этого периода, поток может немедленно продолжиться в том же самом интервале времени. Однако, также частый опрос многократными потоками совместно используемого объекта может вызвать перегрузку кэша. InnoDB минимизирует эту проблему при ожидании случайное время между последующими опросами. Задержка осуществлена как цикл.
Вы можете управлять максимальной задержкой между тестированием mutex или
rw-блокировки, используя параметр
innodb_spin_wait_delay
. Продолжительность цикла задержки зависит
от компилятора C и целевого процессора. В эру Pentium на 100 МГц задержка
была одной микросекундой. На системе, где все ядра процессора совместно
используют быструю кэш-память, Вы могли бы уменьшить максимальную задержку
или отключить цикл, устанавливая
innodb_spin_wait_delay=0
. На многопроцессорной системе
эффект аннулирования кэша может быть более существенным, и Вы могли бы
увеличить максимальную задержку.
Значение по умолчанию
innodb_spin_wait_delay
6
.
Задержка это динамический глобальный параметр, который Вы можете определить в
файле опции MySQL или командой SET GLOBAL
innodb_spin_wait_delay=
, где
delay
желаемая максимальная задержка.
Изменение настроек требует привилегии delay
SUPER
.
Для исполнительных соображений операций блокировки в InnoDB см. раздел 9.11.
Чистка (тип сбора мусора), которую InnoDB выполняет автоматически, теперь сделана в одном или более отдельных потоках, а не как часть мастер-потока. Это изменение улучшает масштабируемость, потому что основные операции базы данных работают независимо от работы обслуживания, происходящей в фоне.
Чтобы управлять этой особенностью, увеличьте значение параметра
конфигурации
innodb_purge_threads
. Если действие DML сконцентрировано на
единственной таблице или нескольких таблицах, сохраните установку низкой так,
чтобы потоки не боролись друг с другом за доступ к занятым таблицам. Если
операции DML распространены на многие таблицы,
увеличивайте установку. Ее максимум 32.
Есть другой связанный параметр конфигурации
innodb_purge_batch_size
со значением по умолчанию 300 и
максимальным значением 5000. Эта опция, главным образом, предназначена для
экспериментирования и настройки операций чистки и не должна быть
интересной типичным пользователям.
Для получения дополнительной информации о работе ввода/вывода InnoDB см. раздел 9.5.8.
Этот раздел описывает, как сконфигурировать постоянную статистику для
таблиц InnoDB
.
Статистические данные сохранены через перезапуски сервера, учитывая большую стабильность плана и и более последовательную работу запроса. Постоянные статистические данные также обеспечивают управление и гибкость с этими дополнительными выгодами:
Вы можете использовать параметр конфигурации
innodb_stats_auto_recalc
, чтобы управлять, обновлены ли
статистические данные автоматически после существенных изменений в таблице.
STATS_PERSISTENT
,
STATS_AUTO_RECALC
и STATS_SAMPLE_PAGES
в
CREATE TABLE
и
ALTER TABLE
, чтобы
сконфигурировать статистику для отдельных таблиц.mysql.innodb_table_stats
и
mysql.innodb_index_stats
.last_update
таблиц
mysql.innodb_table_stats
и
mysql.innodb_index_stats
, чтобы видеть, когда
статистические данные обновлялись.mysql.innodb_table_stats
и
mysql.innodb_index_stats
, чтобы вызвать определенный план
оптимизации запроса или проверить альтернативные планы,
не изменяя базу данных.Постоянная опция статистики активирована по умолчанию
(
innodb_stats_persistent=ON
).
Нестойкие статистические данные очищены на каждом перезапуске сервера и после некоторых других операций, и повторно вычислены при следующем доступе к таблице. В результате различные оценки могли быть произведены при перевычислении статистики, приводя к различному выбору в планах выполнения и изменениям в работе запроса.
Этот раздел также предоставляет информацию об оценке сложности
ANALYZE TABLE
, которая может
быть полезной, пытаясь достигнуть баланса между точной статистикой и
временем выполнения ANALYZE TABLE
.
Постоянная статистика улучшает стабильность плана, храня статистику на диске и делая ее постоянной через перезапуски сервера так, чтобы оптимизатор, более вероятно, сделал последовательный выбор каждый раз для данного запроса.
Статистические данные сохранены на диск, когда
innodb_stats_persistent=ON
или когда отдельные таблицы составлены
или изменены с STATS_PERSISTENT=1
.
innodb_stats_persistent
включен по умолчанию.
Прежде статистика была очищена при каждом перезапуске сервера и после некоторых других операций и повторно вычислена при следующем доступе к таблице. Следовательно, различные оценки могли быть произведены, повторно вычисляя статистику, приводя к различному выбору в планах выполнения запроса и таким образом изменениям в работе запроса.
Постоянные статистические данные сохранены в таблицах
mysql.innodb_table_stats
и
mysql.innodb_index_stats
, как описано в
разделе 16.6.10.1.5.
Чтобы вернуться к использованию нестойкой
статистики, Вы можете изменить таблицы, используя
ALTER TABLE
.
Для соответствующей информации см.
раздел 16.6.10.2.tbl_name
STATS_PERSISTENT=0
Опция
innodb_stats_auto_recalc
, которая включена по умолчанию,
определяет, вычислены ли статистические данные автоматически всякий раз,
когда таблица подвергается существенным изменениям (больше, чем 10% строк).
Вы можете также сконфигурировать автоматический перерасчет статистики для
отдельных таблиц, используя параметр STATS_AUTO_RECALC
в
CREATE TABLE
или
ALTER TABLE
.
innodb_stats_auto_recalc
включен по умолчанию.
Из-за асинхронной природы автоматического перерасчета статистики
(который происходит в фоне), статистика не может быть повторно вычислена
немедленно после выполнения работы DML, которая затрагивает больше, чем
10% таблицы, даже когда включен
innodb_stats_auto_recalc
.
В некоторых случаях перерасчет статистики может быть отсрочен на несколько
секунд. Если современные статистические данные требуются немедленно после
изменения существенных частей таблицы, выполните
ANALYZE TABLE
, чтобы
начать синхронный перерасчет статистики.
Если
innodb_stats_auto_recalc
отключен, гарантируйте точность
статистики через ANALYZE TABLE
для каждой применимой таблицы после существенных изменений
индексированных столбцов. Вы могли бы выполнить этот запрос в своих скриптах
после того, как представительные данные были загружены в таблицу, и
периодически после того, как операции DML значительно изменяют содержание
индексированных столбцов, или по графику во время низкой активности.
Когда новый индекс добавлен к существующей таблице,
статистика вычисленыа и добавлена к таблице innodb_index_stats
независимо от значения
innodb_stats_auto_recalc
.
Чтобы гарантировать сбор статистики, когда новый индекс создается,
включите
innodb_stats_auto_recalc
или выполните
ANALYZE TABLE
после создания
каждого нового индекса, когда постоянный режим статистики включен.
innodb_stats_persistent
,
innodb_stats_auto_recalc
и
innodb_stats_persistent_sample_pages
глобальные параметры конфигурации. Чтобы переопределить эти настройки в
масштабе всей системы и сконфигурировать параметры статистики для отдельных
таблиц, Вы можете определить параметры STATS_PERSISTENT
,
STATS_AUTO_RECALC
и STATS_SAMPLE_PAGES
в
CREATE TABLE
или
ALTER TABLE
.
STATS_PERSISTENT
определяет, включить ли
постоянную статистику
для таблицы InnoDB
. Значение DEFAULT
заставляет постоянную установку статистики для таблицы быть определенной
опцией
innodb_stats_persistent
. Значение 1
включает постоянную статистику для таблицы, в то время как значение
0
выключает эту особенность. После включения постоянной
статистики через CREATE TABLE
или ALTER TABLE
скомандуйте ANALYZE TABLE
,
чтобы вычислить статистику, после загрузки представительных данных в таблицу.
STATS_AUTO_RECALC
определяет, вычислить ли повторно
автоматически постоянную
статистику для таблицы InnoDB
. Значение DEFAULT
предписывает взять значение опции
innodb_stats_auto_recalc
. Значение 1
указывает, что
статистика будет повторно вычислена, когда 10% данных в таблице изменились.
Значение 0
предотвращает автоматический пересчет для этой
таблицы, с этой установкой скомандуйте
ANALYZE TABLE
, чтобы повторно вычислить статистику после
существенных изменений в таблице.STATS_SAMPLE_PAGES
определяет число индексных страниц в
образце, оценивая количество элементов и другую статистику для
индексированного столбца, таких как вычисленные
ANALYZE TABLE
.Все три пункта определены в следующем примере
CREATE TABLE
:
CREATE TABLE `t1` (`id` int(8) NOT NULL auto_increment, `data` varchar(255), `date` datetime, PRIMARY KEY (`id`), INDEX `DATE_IX` (`date`)) ENGINE=InnoDB, STATS_PERSISTENT=1, STATS_AUTO_RECALC=1, STATS_SAMPLE_PAGES=25;
MySQL запрашивают оцененную
статистику использования
ключевых распределений, чтобы выбрать индексирование для плана выполнения,
основанное на относительной
селективности индексирования.
Такие операции, как ANALYZE TABLE
просят InnoDB
пробовать случайные страницы каждого
индекса таблицы, чтобы оценить
количество элементов
индексирования. Этот метод известен как
случайные погружения.
Чтобы дать Вам контроль над качеством оценки статистики (и таким образом
лучшую информацию для запроса), Вы можете изменить число выбранных страниц,
используя параметр
innodb_stats_persistent_sample_pages
,
который может быть установлен во время выполнения.
innodb_stats_persistent_sample_pages
имеет значение по умолчанию 20. Как общее руководство, рассмотрите изменение
этого параметра, сталкиваясь со следующими проблемами:
Statistics are not accurate enough and the
optimizer chooses suboptimal plans в выводе
EXPLAIN
.
Точность статистики может быть проверена, сравнивая фактическое количество
элементов индексирования (как возвращено
SELECT DISTINCT
на столбцах индекса с оценками, обеспеченными таблице
mysql.innodb_index_stats
.
Если решено, что статистические данные недостаточно точны, значение
innodb_stats_persistent_sample_pages
должно быть увеличено, пока оценки статистики не станут достаточно точными.
Увеличение
innodb_stats_persistent_sample_pages
, однако, может вызвать
замедление ANALYZE TABLE
.
ANALYZE TABLE
работает медленно. В этом случае
innodb_stats_persistent_sample_pages
надо уменьшить до приемлемой
скорости ANALYZE TABLE
.
Уменьшение значения, однако, могло привести к первой проблеме неточной
статистики и подоптимальных планов выполнения запроса.
Если баланс не может быть достигнут между точной статистикой и скоростью
statistics and ANALYZE TABLE
помните, что сокращение числа индексированных столбцов в таблице или
ограничение числа разделов уменьшает сложность
ANALYZE TABLE
.
Число столбцов в первичном ключе таблицы также важно, поскольку столбцы
первичного ключа добавлены к каждому групповому индексу.
Для соответствующей информации см. раздел 16.6.10.3.
По умолчанию InnoDB
читает нейтральные данные, вычисляя
статистику. В случае нейтральной транзакции, которая удаляет строки из
таблицы, InnoDB
исключает записи, которые отмечены как
удаленные, вычисляя оценки строки и индексную статистику, которая может
привести к неоптимальным планам выполнения относительно других транзакций,
которые воздействуют на таблицу, одновременно используя операционный уровень
изоляции, кроме READ
UNCOMMITTED
. Чтобы обойти эту ситуацию, опция
innodb_stats_include_delete_marked
может быть включена, чтобы
гарантировать, что InnoDB
добавляет записи, которые отмечены как
удаленные, вычисляя постоянную статистику.
При включении
innodb_stats_include_delete_marked
ANALYZE TABLE
рассматривает помеченные как удаленные записи, повторно вычисляя статистику.
innodb_stats_include_delete_marked
глобальная установка, которая
затрагивает все таблицы. Это применимо только к постоянной статистике.
innodb_stats_include_delete_marked
была введена в MySQL 8.0.1.
Постоянная статистика полагается на таблицы
innodb_table_stats
и
innodb_index_stats
в базе данных mysql
.
Эти таблицы настроены автоматически в ходе установки и обновления.
Таблица 16.3. Столбцы innodb_table_stats
Имя столбца | Описание |
---|---|
database_name | Имя базы данных |
table_name | Имя таблицы, имя раздела или подраздела |
last_update | timestamp, указывающий последнее время обновления этой строки |
n_rows | Число строк в таблице |
clustered_index_size | Размер первичного индекса в страницах |
sum_of_other_index_sizes | Полный размер других (не первичных) индексов в страницах |
Таблица 16.4. Столбцы innodb_index_stats
Столбец | Описание |
---|---|
database_name | Имя базы данных |
table_name | Имя таблицы, имя раздела или подраздела |
index_name | Имя индекса |
last_update | timestamp, указывающий последнее время обновления этой строки |
stat_name | Название статистической величины, о
значении которой сообщают в столбце stat_value |
stat_value | Значение статистической величины,
которая названа в столбце stat_name |
sample_size | Число страниц, выбранных для оценки
величины в столбце stat_value |
stat_description |
Описание статистической величины, которую называют в столбце
stat_name |
Таблицы innodb_table_stats
и
innodb_index_stats
включают столбец
last_update
, показывающий, когда InnoDB
в последний
раз обновлени индексную статистику, как показано в следующем примере:
mysql> select * from innodb_table_stats \G *************************** 1. row *************************** database_name: sakila table_name: actor last_update: 2014-05-28 16:16:44 n_rows: 200 clustered_index_size: 1 sum_of_other_index_sizes: 1 ... mysql> select * from innodb_index_stats \G *************************** 1. row *************************** database_name: sakila table_name: actor index_name: PRIMARY last_update: 2014-05-28 16:16:44 stat_name: n_diff_pfx01 stat_value: 200 sample_size: 1 ...
Таблицы innodb_table_stats
и
innodb_index_stats
это обычные таблицы и могут быть обновлены
вручную. Способность обновить статистику вручную позволяет вызвать
определенный план оптимизации запроса или проверить альтернативные планы, не
изменяя базу данных. Если Вы вручную обновляете статистику, скомандуйте
FLUSH TABLE
, чтобы заставить
MySQL перезагрузить обновленную статистику.tbl_name
Таблица innodb_table_stats
содержит одну строку на таблицу.
Собранные данные продемонстрированы в следующем примере.
Таблица t1
содержит первичный индекс (столбцы
a
, b
), вторичный индекс
(столбцы c
, d
) и уникальный индекс
(столбцы e
, f
):
CREATE TABLE t1 (a INT, b INT, c INT, d INT, e INT, f INT, PRIMARY KEY (a, b), KEY i1 (c, d), UNIQUE KEY i2uniq (e, f)) ENGINE=INNODB;
После вставки пяти строк типовых данных таблица выглядит так:
mysql> SELECT * FROM t1; +---+---+----+----+-----+-----+ | a | b | c | d | e | f | +---+---+----+----+-----+-----+ | 1 | 1 | 10 | 11 | 100 | 101 | | 1 | 2 | 10 | 11 | 200 | 102 | | 1 | 3 | 10 | 11 | 100 | 103 | | 1 | 4 | 10 | 12 | 200 | 104 | | 1 | 5 | 10 | 12 | 100 | 105 | +---+---+----+----+-----+-----+
Чтобы немедленно обновить статистику, скомандуйте
ANALYZE TABLE
(если включена
innodb_stats_auto_recalc
, статистические данные обновлены
автоматически в течение нескольких секунд, предполагая, что порог 10%
для измененных строк таблицы достигнут):
mysql> ANALYZE TABLE t1; +---------+---------+----------+----------+ | Table | Op | Msg_type | Msg_text | +---------+---------+----------+----------+ | test.t1 | analyze | status | OK | +---------+---------+----------+----------+
Табличная статистика для таблицы показывает: обновлена в последний раз
2014-03-14 14:36:34
, число строк в таблице (5
),
размер кластеризируемого индекса (1
страница)
и объединенный размер других индексов (2
страницы).
mysql> SELECT * FROM mysql.innodb_table_stats WHERE table_name like 't1'\G *************************** 1. row *************************** database_name: test table_name: t1 last_update: 2014-03-14 14:36:34 n_rows: 5 clustered_index_size: 1 sum_of_other_index_sizes: 2
Таблица innodb_index_stats
содержит многократные строки для
каждого индекса. Каждая строка в таблице innodb_index_stats
обеспечивает, данные, связанные с индексируемой статистической величиной,
которую называют в столбце stat_name
и описывают в
stat_description
, например:
mysql> SELECT index_name, stat_name, stat_value, stat_description -> FROM mysql.innodb_index_stats WHERE table_name like 't1'; +------------+--------------+------------+-----------------------------------+ | index_name | stat_name | stat_value | stat_description | +------------+--------------+------------+-----------------------------------+ | PRIMARY | n_diff_pfx01 | 1 | a | | PRIMARY | n_diff_pfx02 | 5 | a,b | | PRIMARY | n_leaf_pages | 1 | Number of leaf pages in the index | | PRIMARY | size | 1 | Number of pages in the index | | i1 | n_diff_pfx01 | 1 | c | | i1 | n_diff_pfx02 | 2 | c,d | | i1 | n_diff_pfx03 | 2 | c,d,a | | i1 | n_diff_pfx04 | 5 | c,d,a,b | | i1 | n_leaf_pages | 1 | Number of leaf pages in the index | | i1 | size | 1 | Number of pages in the index | | i2uniq | n_diff_pfx01 | 2 | e | | i2uniq | n_diff_pfx02 | 5 | e,f | | i2uniq | n_leaf_pages | 1 | Number of leaf pages in the index | | i2uniq | size | 1 | Number of pages in the index | +------------+--------------+------------+-----------------------------------+
Столбец stat_name
показывает следующие типы статистики:
size
: Где stat_name
=size
,
столбец stat_value
выводит на экран общее
количество страниц в индексе.
n_leaf_pages
: Где stat_name
=n_leaf_pages
, столбец stat_value
выводит на экран
число страниц в индексе.n_diff_pfxNN
: Где
stat_name
=n_diff_pfx01
, столбец
stat_value
выводит на экран число отличных значений в первом
столбце индексирования. Где stat_name
=n_diff_pfx02
,
столбец stat_value
столбец выводит на экран число отличных
значений в первых двух столбцах индексирования и так далее. Дополнительно где
stat_name
=n_diff_pfxNN
,
столбец stat_description
показывает список разделенных запятой
значений индексированных столбцов, которые посчитаны.Далее n_diff_pfx
это
статистическая величина, которая обеспечивает данные о количестве элементов,
рассматриваемых в примере таблицы NN
t1
. Как показано ниже,
таблица t1
составлена с первичным индексом
(столбцы a
, b
), вторичным индексом (столбцы
c
, d
) и уникальным индексом (столбцы
e
, f
):
CREATE TABLE t1 (a INT, b INT, c INT, d INT, e INT, f INT, PRIMARY KEY (a, b), KEY i1 (c, d), UNIQUE KEY i2uniq (e, f)) ENGINE=INNODB;
После вставки пяти строк типовых данных таблица выглядит так:
mysql> SELECT * FROM t1; +---+---+----+----+-----+-----+ | a | b | c | d | e | f | +---+---+----+----+-----+-----+ | 1 | 1 | 10 | 11 | 100 | 101 | | 1 | 2 | 10 | 11 | 200 | 102 | | 1 | 3 | 10 | 11 | 100 | 103 | | 1 | 4 | 10 | 12 | 200 | 104 | | 1 | 5 | 10 | 12 | 100 | 105 | +---+---+----+----+-----+-----+
Когда Вы запрашиваете index_name
,
stat_name
, stat_value
и
stat_description
, где stat_name LIKE 'n_diff%'
,
следующий набор результатов возвращен:
mysql> SELECT index_name, stat_name, stat_value, stat_description -> FROM mysql.innodb_index_stats -> WHERE table_name like 't1' AND stat_name LIKE 'n_diff%'; +------------+--------------+------------+------------------+ | index_name | stat_name | stat_value | stat_description | +------------+--------------+------------+------------------+ | PRIMARY | n_diff_pfx01 | 1 | a | | PRIMARY | n_diff_pfx02 | 5 | a,b | | i1 | n_diff_pfx01 | 1 | c | | i1 | n_diff_pfx02 | 2 | c,d | | i1 | n_diff_pfx03 | 2 | c,d,a | | i1 | n_diff_pfx04 | 5 | c,d,a,b | | i2uniq | n_diff_pfx01 | 2 | e | | i2uniq | n_diff_pfx02 | 5 | e,f | +------------+--------------+------------+------------------+
Для индекса PRIMARY
есть две строки n_diff%
.
Число строк равно числу столбцов в индексировании.
Для группового индекса InnoDB
добавляет
столбцы первичного ключа.
Где index_name
=PRIMARY
и
stat_name
=n_diff_pfx01
,
stat_value
1
,
который указывает, что есть единственное отличное значение в первом столбце
индексирования (столбец a
). Число отличных значений в столбце
a
подтверждено, рассматривая данные в столбце
a
таблицы t1
, в котором есть единственное отличное
значение (1
). Посчитанный столбец (a
) показан в
столбце stat_description
набора результатов.
index_name
=PRIMARY
и
stat_name
=n_diff_pfx02
,
stat_value
5
,
который указывает, что есть пять отличных значений в двух столбцах
индексирования (a,b
). Число отличных значений в столбцах
a
и b
подтверждено, рассматривая данные в столбцах
a
и b
таблицы t1
,
в которых есть пять отличных значений: (1,1
),
(1,2
), (1,3
), (1,4
) и
(1,5
). Посчитанные столбцы (a,b
) показаны в
столбце stat_description
набора результатов.Для вторичного индекса (i1
) есть четыре строки
n_diff%
. Только два столбца определены для вторичного индекса
(c,d
), но есть четыре строки n_diff%
для него,
потому что InnoDB
соединяет все групповые индексы с первичным
ключом. В результате есть четыре строки n_diff%
вместо двух,
чтобы сосчитать оба столбца вторичного индекса (c,d
)
и столбцы первичного ключа (a,b
).
Где index_name
=i1
и
stat_name
=n_diff_pfx01
,
stat_value
1
, который указывает, что есть
единственное отличное значение в первом столбце индексирования (столбец
c
). Число отличных значений в столбце c
подтверждено, рассматривая данные в столбце c
в таблице
t1
, в котором есть единственное отличное значение:
(10
). Посчитанный столбец (c
) показан в столбце
stat_description
набора результатов.
index_name
=i1
и
stat_name
=n_diff_pfx02
,
stat_value
2
,
который указывает, что есть два отличных значения в первых двух столбцах
индексирования (c,d
). Число отличных значений в столбцах
c
и d
подтверждено, рассматривая данные в столбцах
c
и d
в таблице t1
, в которых есть два
отличных значения: (10,11
) и (10,12
).
Посчитанные столбцы (c,d
) показаны в столбце
stat_description
набора результатов.index_name
=i1
и
stat_name
=n_diff_pfx03
,
stat_value
2
,
который указывает, что есть два отличных значения в первых трех столбцах
индексирования (c,d,a
). Число отличных значений в столбцах
c
, d
и a
подтверждено, рассматривая данные в столбцах
c
, d
и a
таблицы t1
,
в которых есть два отличных значения: (10,11,1
) и
(10,12,1
). Посчитанные столбцы (c,d,a
) показаны в
столбце stat_description
набора результатов.index_name
=i1
и
stat_name
=n_diff_pfx04
,
stat_value
5
,
который указывает, что есть пять отличных значений в четырех столбцах
индексирования (c,d,a,b
). Число отличных значений в столбцах
c
, d
, a
и b
подтверждено, рассматривая данные в столбцах c
,
d
, a
и b
в таблице t1
,
в которых есть пять отличных значений:
(10,11,1,1
), (10,11,1,2
), (10,11,1,3
),
(10,12,1,4
) и (10,12,1,5
). Посчитанные столбцы
(c,d,a,b
) показаны в столбце stat_description
набора результатов.Для уникального индекса (i2uniq
) есть
две строки n_diff%
.
Где index_name
=i2uniq
и
stat_name
=n_diff_pfx01
,
stat_value
2
,
который указывает, что есть два отличных значения в первом столбце индекса
(столбец e
). Число отличных значений в столбце e
подтверждено, рассматривая данные в столбце e
в таблице
t1
, в котором есть два отличных значения: (100
) и
(200
). Посчитанный столбец (e
) показан в столбце
stat_description
набора результатов.
index_name
=i2uniq
и
stat_name
=n_diff_pfx02
,
stat_value
is 5
,
который указывает, что есть пять отличных значений в двух столбцах индекса
(e,f
). Число отличных значений в столбцах e
и f
подтверждено, рассматривая данные в столбцах
e
и f
в таблице t1
,
в котором есть пять отличных значений:
(100,101
), (200,102
), (100,103
),
(200,104
) и (100,105
). Посчитанные столбцы
(e,f
) показаны в столбце
stat_description
набора результатов.Размер индекса для таблицы, раздела или подраздела
может быть получен, используя таблицу innodb_index_stats
.
В следующем примере размеры индексов получены для таблицы t1
.
Для определения таблицы t1
и соответствующей статистики см.
раздел
16.6.10.1.6.
mysql> SELECT SUM(stat_value) pages, index_name, -> SUM(stat_value)*@@innodb_page_size size -> FROM mysql.innodb_index_stats WHERE table_name='t1' AND -> stat_name = 'size' GROUP BY index_name; +-------+------------+-------+ | pages | index_name | size | +-------+------------+-------+ | 1 | PRIMARY | 16384 | | 1 | i1 | 16384 | | 1 | i2uniq | 16384 | +-------+------------+-------+
Для раздела или подраздела подойдет тот же запрос, но с измененным
WHERE
. Например, следующий запрос получает размеры индексов
для раздела таблицы t1
:
mysql> SELECT SUM(stat_value) pages, index_name, -> SUM(stat_value)*@@innodb_page_size size -> FROM mysql.innodb_index_stats WHERE table_name like 't1#P%' AND -> stat_name = 'size' GROUP BY index_name;
Этот раздел описывает, как сконфигурировать нестойкую статистику.
Статистические данные не сохранены на диске, когда
innodb_stats_persistent=OFF
или когда отдельные таблицы составлены
или изменены с STATS_PERSISTENT=0
. Вместо этого статистические данные сохранены в памяти и потеряны,
когда сервер закрыт. Статистические данные также периодически обновляются
определенными операциями и при определенных условиях.
Статистические данные сохранены на диск по умолчанию при включении опции
innodb_stats_persistent
. Для информации о постоянной
статистике см. раздел 16.6.10.1
.
Статистические данные обновлены когда:
Выполнена ANALYZE TABLE
.
SHOW TABLE STATUS
, SHOW INDEX
или
запросы к таблице
INFORMATION_SCHEMA.TABLES
или
INFORMATION_SCHEMA.STATISTICS
с включенной опцией
innodb_stats_on_metadata
.
Настройка по умолчанию для
innodb_stats_on_metadata
OFF
. Включение
innodb_stats_on_metadata
может уменьшить скорость доступа для
схем, у которых есть большое количество таблиц или индексов, и уменьшить
стабильность планов выполнения относительно запросов, которые вовлекают
таблицы InnoDB
.
innodb_stats_on_metadata
сконфигурирована глобально, используя
SET
.
SET GLOBAL innodb_stats_on_metadata=ON
--auto-rehash
, что является значением по умолчанию. Опция
auto-rehash
предписывает повторно вычислить статистику.
Чтобы улучшить время запуска
mysql и обновления статистики, Вы можете выключить
auto-rehash
,
используя опцию
--disable-auto-rehash
.
auto-rehash
позволяет автоматическое завершение имени базы данных, таблицы и столбцов
для интерактивных пользователей.
InnoDB
обнаруживает, что 1/16 таблицы была изменены с
прошлого обновления статистических данных.Оптимизатор MySQL запрашивают оцененную
статистику о ключевых
распределениях, чтобы выбрать индексирование для плана выполнения,
основанного на относительной
селективности индекса.
Когда InnoDB
обновляет статистику, это пробует случайные
страницы от каждого индекса в таблицы, чтобы оценить
количество элементов индекса.
Этот метод известен как
случайные погружения.
Чтобы дать Вам контроль над качеством оценки статистики (и таким образом
лучшую информацию для запроса), Вы можете изменить число выбранных страниц,
используя параметр
innodb_stats_transient_sample_pages
.
Число значения по умолчанию выбранных страниц 8 может быть недостаточным,
чтобы произвести точную оценку. Этот метод особенно важен для больших таблиц
и таблиц, используемых в
joins. Ненужное
полное сканирование таблицы
для таких таблиц может быть существенной исполнительной проблемой. См.
раздел 9.2.1.21
для подсказок относительно настройки таких запросов.
innodb_stats_transient_sample_pages
глобальный параметр, который может быть установлен во время выполнения.
Значение
innodb_stats_transient_sample_pages
влияет на осуществление
выборки для всех таблиц и нидексов InnoDB
, когда
innodb_stats_persistent=0
. Знайте о следующем потенциально
существенном влиянии, когда Вы изменяете объем выборки:
Маленькие значения как 1 или 2 могут привести к неточным оценкам количества элементов.
innodb_stats_transient_sample_pages
могло бы потребовать большего количества дисковых чтений.
Значения, намного больше 8 (например, 100), могут вызвать существенное
замедление во время открытия таблицы или выполнения
SHOW TABLE STATUS
.Выберите значение, которое приводит к разумно точным оценкам для всех
таблиц в Вашей базе данных, не требуя чрезмерного ввода/вывода. Поскольку
статистические данные автоматически повторно вычислены неоднократно кроме
выполнения ANALYZE TABLE
,
не имеет смысла увеличивать объем выборки, запуская
ANALYZE TABLE
,
уменьшите объем выборки.
Меньшие таблицы вообще требуют меньшие образцы индекса,
чем большие таблицы. Если у Вашей базы данных есть много больших таблиц,
рассмотрите использование более высокого значения для
innodb_stats_transient_sample_pages
,
чем если бы у Вас есть главным образом маленькие таблицы.
Сложность ANALYZE TABLE
для таблицы InnoDB
зависит от:
Числа выбранных страниц, как определено
innodb_stats_persistent_sample_pages
.
Используя эти параметры, приблизительная формула для того, чтобы оценить
сложность ANALYZE TABLE
:
Значение
innodb_stats_persistent_sample_pages
* число индексированных столбцов в таблице * число разделов.
Как правило, чем больше получающееся значение, тем больше время выполнения
для ANALYZE TABLE
.
innodb_stats_persistent_sample_pages
определяет число страниц,
выбранных на глобальном уровне. Чтобы определить число страниц, выбранных для
отдельной таблицы, используйте опцию STATS_SAMPLE_PAGES
в
CREATE TABLE
или
ALTER TABLE
. Подробности в
разделе 16.6.10.1.
Если
innodb_stats_persistent=OFF
, число выбранных страниц определено
innodb_stats_transient_sample_pages
. См.
раздел 16.6.10.2.
Для более всестороннего подхода к оценке сложности ANALYZE
TABLE
рассмотрите следующий пример.
В записи Big O сложность
ANALYZE TABLE
описана как:
O(n_sample * (n_cols_in_uniq_i + n_cols_in_non_uniq_i + n_cols_in_pk * (1 + n_non_uniq_i)) * n_part)
Здесь:
n_sample
число выбранных страниц (определено
innodb_stats_persistent_sample_pages
).
n_cols_in_uniq_i
общее количество всех столбцов всех
уникальных индексов (не считая столбцы первичного ключа).n_cols_in_non_uniq_i
общее количество всех столбцов
всех неуникальных индексов.n_cols_in_pk
число столбцов в первичном ключе (если
первичный ключ не определен, InnoDB
создает единственный первичный ключ столбца внутренне).n_non_uniq_i
число групповых индексов в таблице.n_part
число разделов. Если никакое разделение не
определено, таблица является единственным разделом.Теперь, рассмотрите следующую таблицу (таблица t
),
у которой есть первичный ключ (2 столбца), уникальный индекс
(2 столбца) и два групповых индекса (по два столбца каждый):
CREATE TABLE t (a INT, b INT, c INT, d INT, e INT, f INT, g INT, h INT, PRIMARY KEY (a, b), UNIQUE KEY i1uniq (c, d), KEY i2nonuniq (e, f), KEY i3nonuniq (g, h));
Для данных столбца и индекса, требуемых алгоритмом, описанным выше,
запрашивают постоянный индекс статистики из
mysql.innodb_index_stats
для таблицы t
.
Статистические данные n_diff_pfx%
показывают столбцы, которые
посчитаны для каждого индекса. Например, столбцы
a
и b
посчитаны для индекса первичного ключа.
Для неуникальных индексов столбцы первичного ключа (a,b)
посчитаны в дополнение к определяемым пользователем столбцам.
Для дополнительной информации о постоянных таблицах статистики
InnoDB
см. раздел
16.6.10.1.
SELECT index_name, stat_name, stat_description FROM mysql.innodb_index_stats WHERE database_name='test' AND table_name='t' AND stat_name like 'n_diff_pfx%'; +------------+--------------+------------------+ | index_name | stat_name | stat_description | +------------+--------------+------------------+ | PRIMARY | n_diff_pfx01 | a | | PRIMARY | n_diff_pfx02 | a,b | | i1uniq | n_diff_pfx01 | c | | i1uniq | n_diff_pfx02 | c,d | | i2nonuniq | n_diff_pfx01 | e | | i2nonuniq | n_diff_pfx02 | e,f | | i2nonuniq | n_diff_pfx03 | e,f,a | | i2nonuniq | n_diff_pfx04 | e,f,a,b | | i3nonuniq | n_diff_pfx01 | g | | i3nonuniq | n_diff_pfx02 | g,h | | i3nonuniq | n_diff_pfx03 | g,h,a | | i3nonuniq | n_diff_pfx04 | g,h,a,b | +------------+--------------+------------------+
Основываясь на индексных данных о статистике, показанных выше, и табличном определении, следующие значения могут быть определены:
n_cols_in_uniq_i
,
общее количество всех столбцов во всех уникальных индексах, не считая
столбцов первичного ключа, 2 (c
и d
).
n_cols_in_non_uniq_i
, общее количество всех столбцов
во всех неуникальных индексах 4 (e
, f
,
g
и h
).n_cols_in_pk
, число столбцов в первичном ключе
2 (a
и b
).n_non_uniq_i
, число групповых индексов в таблице 2
(i2nonuniq
и i3nonuniq
)).n_part
, число разделов 1.Вы можете теперь вычислить
innodb_stats_persistent_sample_pages
* (2 + 4
+ 2 * (1 + 2)) * 1, чтобы определить число страниц, которые отсканированы. С
установкой innodb_stats_persistent_sample_pages
в
значение по умолчанию 20
и с размером страницы по умолчанию
16 KiB
(
innodb_page_size
=16384) Вы можете тогда оценить, что
20 * 12 * 16384 байт
считаны из таблицы t
или приблизительно 4 MiB
.
Все 4 MiB
возможно, не будут считаны с диска, поскольку
некоторые страницы могут уже кэшироваться в буферном пуле.
Вы можете сконфигурировать значение MERGE_THRESHOLD
для
индексных страниц. Если процент полных страниц
для индексной страницы падает ниже MERGE_THRESHOLD
, когда строка
удалена или сокращена через UPDATE
,
InnoDB
пробует слить индексную страницу с соседней индексной
страницей. Значение по умолчанию MERGE_THRESHOLD
50, что
является ранее неизменным значением.
Минимум MERGE_THRESHOLD
1 и максимальное значение 50.
Когда процент полных страниц
для индексной страницы падает ниже 50%, что является значением по умолчанию
для MERGE_THRESHOLD
, InnoDB
пробует
слить индексную страницу с соседней страницей. Если обе страницы близки к
полным 50%, разделение страницы может произойти вскоре после того, как
страницы слиты. Если это происходит часто, у него может быть неблагоприятное
влияние на производительность. Чтобы избежать частых разделений слияния, Вы
можете понизить MERGE_THRESHOLD
так, чтобы InnoDB
сливал страницы при более низком проценте
полных страниц. Слияние страниц в более низком
проценте полной страницы освобождает больше места в индексных страницах и
помогает уменьшить разделение после слияния.
MERGE_THRESHOLD
для индексных страниц может быть определен
для таблицы или индекса. MERGE_THRESHOLD
для отдельного индекса
берет приоритет над MERGE_THRESHOLD
для таблицы. Если не
определен, значение MERGE_THRESHOLD
по умолчанию 50.
Вы можете установить значение MERGE_THRESHOLD
для таблицы, используя предложение параметр COMMENT
в
CREATE TABLE
:
CREATE TABLE t1 (id INT, KEY id_index (id)) COMMENT='MERGE_THRESHOLD=45';
Вы можете также установить значение MERGE_THRESHOLD
для существующей таблицы, используя параметр COMMENT
в
ALTER TABLE
:
CREATE TABLE t1 (id INT, KEY id_index (id)); ALTER TABLE t1 COMMENT='MERGE_THRESHOLD=40';
Установить значение MERGE_THRESHOLD
для индекса можно через
параметр COMMENT
в запросах
CREATE TABLE
,
ALTER TABLE
или
CREATE INDEX
:
CREATE TABLE t1 (id INT, KEY id_index (id) COMMENT 'MERGE_THRESHOLD=40');
Или:
CREATE TABLE t1 (id INT, KEY id_index (id)); ALTER TABLE t1 DROP KEY id_index; ALTER TABLE t1 ADD KEY id_index (id) COMMENT 'MERGE_THRESHOLD=40';
Или:
CREATE TABLE t1 (id INT); CREATE INDEX id_index ON t1 (id) COMMENT 'MERGE_THRESHOLD=40';
Вы не можете изменить MERGE_THRESHOLD
на уровне индекса
для GEN_CLUST_INDEX
, который является кластеризируемым индексом,
создаваемым InnoDB
, когда таблица составлена без первичного
ключа или индекса уникального ключа. Вы можете только изменить
MERGE_THRESHOLD
для GEN_CLUST_INDEX
установкой
MERGE_THRESHOLD
для таблицы.
Текущее значение MERGE_THRESHOLD
для индекса может быть
получено, запрашивая таблицу
INNODB_SYS_INDEXES
:
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES WHERE NAME='id_index' \G *************************** 1. row *************************** INDEX_ID: 91 NAME: id_index TABLE_ID: 68 TYPE: 0 N_FIELDS: 1 PAGE_NO: 4 SPACE: 57 MERGE_THRESHOLD: 40
Вы можете использовать SHOW
CREATE TABLE
, чтобы посмотреть значение
MERGE_THRESHOLD
для таблицы, если явно определено, используя
предложение table_option
COMMENT
:
mysql> SHOW CREATE TABLE t2 \G *************************** 1. row *************************** Table: t2 Create Table: CREATE TABLE `t2` ( `id` int(11) DEFAULT NULL, KEY `id_index` (`id`) COMMENT 'MERGE_THRESHOLD=40' ) ENGINE=InnoDB DEFAULT CHARSET=latin1
MERGE_THRESHOLD
для индексного уровня берет приоритет над
MERGE_THRESHOLD
уровня таблицы. Если не определено, то 50%
(MERGE_THRESHOLD=50
).
Аналогично, Вы можете использовать SHOW
INDEX
для просмотра MERGE_THRESHOLD
для индексирования, если явно определено, используя COMMENT
:
mysql> SHOW INDEX FROM t2 \G *************************** 1. row *************************** Table: t2 Non_unique: 1 Key_name: id_index Seq_in_index: 1 Column_name: id Collation: A Cardinality: 0 Sub_part: NULL Packed: NULL Null: YES Index_type: BTREE Comment: Index_comment: MERGE_THRESHOLD=40
Таблица INNODB_METRICS
обеспечивает два счетчика, которые могут использоваться, чтобы
измерить эффект MERGE_THRESHOLD
на слияниях индексной страницы.
mysql> SELECT NAME, COMMENT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME like '%index_page_merge%'; +-----------------------------+----------------------------------------+ | NAME | COMMENT | +-----------------------------+----------------------------------------+ | index_page_merge_attempts | Number of index page merge attempts | | index_page_merge_successful | Number of successful index page merges | +-----------------------------+----------------------------------------+
Понижение значения MERGE_THRESHOLD
дает:
Меньшее число попыток и успешные слияния страниц.
Установка MERGE_THRESHOLD
, которая является слишком
маленькой, могла привести к большим файлам с данными из-за чрезмерного
количества пустого пространства страницы.
Для информации об использовании счетчиков
INNODB_METRICS
см.
раздел 16.14.6
.
Этот раздел описывает, как увеличить или уменьшить
системное табличное пространство InnoDB
.
Самый легкий способ увеличить размер системного табличного пространства
это сконфигурировать его сначала на авторасширение. Определите атрибут
autoextend
для последнего файла с данными в определении
табличного пространства. Тогда InnoDB
увеличивает размер этого
файла автоматически порциями по 64MB, когда это исчерпывает пространство.
Размер порции может быть изменен, устанавливая значение
innodb_autoextend_increment
, которая измерена в мегабайтах.
Вы можете расширить системное табличное пространство определенным количеством, добавляя другой файл с данными:
Закройте сервер MySQL.
autoextend
, измените его определение, чтобы использовать
фиксированный размер, основанный на том, как это фактически выросло.
Проверьте размер файла с данными, округлите это в меньшую сторону к самому
близкому числу, кратному 1024*1024 байт (=1MB),
и определите этот округленный размер явно в
innodb_data_file_path
.
innodb_data_file_path
, произвольно делая автомасштабирование
файла. Только последний файл с данными в
innodb_data_file_path
может быть определен как автомасштабируемый.Например, у этого табличного пространства есть только один
автомасштабируемый файл с данными ibdata1
:
innodb_data_home_dir = innodb_data_file_path = /ibdata/ibdata1:10M:autoextend
Предположите, что этот файл с данными в течение долгого времени вырос до 988MB. Вот строка конфигурации после изменения оригинального файла с данными, чтобы использовать фиксированный размер и добавления нового файла:
innodb_data_home_dir = innodb_data_file_path = /ibdata/ibdata1:988M;/disk2/ibdata2:50M:autoextend
Когда Вы добавляете новый файл с данными к системной конфигурации
табличного пространства, удостоверьтесь, что имя файла не обращается к
существующему файлу. InnoDB
создает и инициализирует файл, когда
Вы перезапускаете сервер.
Вы не можете удалить файл с данными из системного табличного пространства. Чтобы уменьшить размер табличного пространства, используйте эту процедуру:
Используйте
mysqldump, чтобы вывести в дамп все Ваши таблицы
InnoDB
, включая таблицы InnoDB
,
расположенные в базе данных MySQL.
mysql> select table_name from information_schema.tables where table_schema='mysql' and engine='InnoDB'; +---------------------------+ | table_name | +---------------------------+ | columns_priv | | db | | engine_cost | | gtid_executed | | help_category | | help_keyword | | help_relation | | help_topic | | innodb_index_stats | | innodb_table_stats | | plugin | | procs_priv | | proxies_priv | | server_cost | | servers | | slave_master_info | | slave_relay_log_info | | slave_worker_info | | tables_priv | | time_zone | | time_zone_leap_second | | time_zone_name | | time_zone_transition | | time_zone_transition_type | | user | +---------------------------+
*.ibd
), включая ibdata
и ib_log
.
Не забывайте удалять *.ibd
для таблиц, расположенных в
базе данных MySQL.Если Ваши базы данных используют только механизм InnoDB
,
может быть более просто вывести в дамп все
базы данных, остановить сервер, удалить все базы данных и файлы системного
журнала InnoDB
, перезапустить сервер и
импортировать файлы дампа.
Изменить число или размер файлов журнала redo можно так:
Остановите сервер MySQL и удостоверьтесь, что он закрывается без ошибок.
my.cnf
, чтобы изменить конфигурацию
файла системного журнала. Чтобы изменить размер файла системного журнала,
надо сконфигурировать
innodb_log_file_size
. Чтобы увеличить число файлов системного
журнала, надо сконфигурировать
innodb_log_files_in_group
.Если InnoDB
обнаруживает, что
innodb_log_file_size
отличается от размера файла системного журнала, это напишет
контрольную точку журнала, закроет и удалит старые файлы, создаст новые файлы
в требуемом размере и откроет их.
Вы можете использовать сырой раздел в качестве файлов с данными в
системном табличном
пространстве InnoDB
. Этот метод включает небуферизованный
вводу/выводу в Windows и некоторых системах Linux и Unix без издержек
файловой системы. Выполните тесты с и без сырого разделения, чтобы проверить,
улучшает ли это изменение фактически работу относительно Вашей системы.
Когда Вы используете сырой дисковый раздел, гарантируете, что
пользовательский ID, который выполняет сервер MySQL, имеет привилегии чтения
и записи для того раздела. Например, если Вы выполняете сервер как
mysql
, раздел должен быть читаем и записываем для
mysql
. Если Вы выполняете сервер с опцией
--memlock
, сервер
должен быть выполнен как root
, таким образом, раздел
должен быть доступен для root
.
Процедуры, описанные ниже, вовлекают модификацию файла опции. Для дополнительной информации см. раздел 5.2.6.
Когда Вы создаете новый файл с данными, определите
ключевое слово newraw
сразу после размера файла с данными для
опции
innodb_data_file_path
. Раздел должен быть, по крайней мере, столь
же большим как размер, который Вы определяете.
[mysqld] innodb_data_home_dir= innodb_data_file_path=/dev/hdd1:3Gnewraw;/dev/hdd2:2Gnewraw
InnoDB
найдет ключевое слово
newraw
и инициализирует новый раздел. Однако, не создавайте или
изменяйте таблицы. Иначе, когда Вы затем перезапускаете сервер,
InnoDB
повторно инициализирует раздел, и Ваши изменения
потеряны. Как мера по безопасности InnoDB
препятствует тому,
чтобы пользователи изменили данные, когда любой
раздел определен с newraw
.InnoDB
инициализировал новый раздел,
остановите сервер и измените newraw
на raw
:
[mysqld] innodb_data_home_dir= innodb_data_file_path=/dev/hdd1:3Graw;/dev/hdd2:2Graw
InnoDB
теперь разрешает
вносить любые изменения.В Windows те же самые шаги , описанные для систем Linux и Unix,
применяются за исключением того, что
innodb_data_file_path
расходится немного в Windows.
Когда Вы создаете новый файл с данными, определите
ключевое слово newraw
сразу после размера файла с данными для
опции
innodb_data_file_path
:
[mysqld] innodb_data_home_dir= innodb_data_file_path=//./D::10Gnewraw
//./
соответствует синтаксису Windows \\.\
для того, чтобы получить доступ к физическим дискам. В примере выше
D:
имя диска раздела.
InnoDB
найдет ключевое слово
newraw
и инициализирует новый раздел.newraw
на raw
:
[mysqld] innodb_data_home_dir= innodb_data_file_path=//./D::10Graw
InnoDB
теперь может работать.
Исторически все таблицы и индексы InnoDB
были сохранены в
системном табличном
пространстве. Этот монолитный подход был хорош в машинах, посвященных
полностью обработке базы данных, с тщательно запланированным ростом данных,
где любое дисковое хранение, выделенное MySQL, никогда не будет необходимо в
других целях. Табличное пространство InnoDB
's
file-per-table
обеспечивает более гибкую альтернативу, где каждая таблица и индекс
InnoDB
сохранены в отдельном файле
.ibd
.
Каждый такой файл .ibd
представляет отдельное табличное
пространство. Этой особенностью управляет опция
innodb_file_per_table
, которая включена по умолчанию.
Вы можете исправить дисковое пространство, усекая или удаляя
таблицу, сохраненную в файле. Усечение или удаление таблиц, сохраненных в
совместно используемом
системном табличном пространстве создает свободное пространство внутренне
в системных файлах с данными табличного пространства
(файлах ibdata),
которое может использоваться только для новых данных InnoDB
.
Точно так же копирование таблицы ALTER
TABLE
на таблице, которая находится в совместно используемом
табличном пространстве, может увеличить количество места, использованного
табличным пространством. Такие операции могут потребовать такого большого
количества дополнительного места, как данные в таблице плюс индекс.
TRUNCATE TABLE
быстрее, когда выполнено на таблицах, сохраненных в файле.CREATE TABLE ... DATA DIRECTORY =
absolute_path_to_directory
, как описано в
разделе 16.7.5.OPTIMIZE TABLE
, чтобы уплотнить или обновить табличное пространство
file-per-table. Когда Вы выполняете
OPTIMIZE TABLE
, InnoDB
создает новый файл
.ibd
с временным именем, используя только место, требуемое,
чтобы сохранить фактические данные. Когда оптимизация завершена,
InnoDB
удаляет старый файл .ibd
и заменяет его новым. Если предыдущий файл .ibd
вырос значительно, но фактические данные составляли только часть его размера,
OPTIMIZE TABLE
может восстановить неиспользуемое место.BLOB
или TEXT
, используя
динамический формат строки
.innodb_flush_method
установлено O_DIRECT
. В результате есть возможные
исполнительные усовершенствования, используя табличные пространства
file-per-table в соединении с
innodb_flush_method
.С табличными пространствами file-per-table у каждой таблицы может быть неиспользуемое место, которое может быть использовано только строками той же самой таблицы. Это могло привести к потраченному впустую пространству если не должным образом управляется.
fsync
должен работать на каждой открытой таблице, а не на
единственном файле. Поскольку есть отдельный fsync
для каждого файла, операции записи на многих таблицах не могут быть
объединены в единственную работу ввода/вывода. Это может потребовать
выполнить более высокое общее количество fsync
.
innodb_file_per_table
включен по умолчанию. Вы можете рассмотреть
отключение этого параметра, если обратная совместимость с MySQL 5.5 или ранее
является важной. Отключение
innodb_file_per_table
не даст
ALTER TABLE
переместить
таблицы InnoDB
из системного табличного пространства в
отдельные файлы .ibd
в случаях, где
ALTER TABLE
обновляет таблицу (ALGORITHM=COPY
).
Например, когда идет реструктурирование кластеризируемого индека для
InnoDB
, таблица обновлена, используя текущую установку для
innodb_file_per_table
. Это поведение не применяется, добавляя или удаляя вторичные
индексы. Когда вторичный индекс создается, не восстанавливая таблицу,
индексирование сохранено в том же самом файле, где табличные данные,
независимо от текущего значения
innodb_file_per_table
. Это поведение также не относится к таблицам, добавленным к
системному табличному пространству через
CREATE TABLE ... TABLESPACE
или ALTER TABLE ... TABLESPACE
. Эти таблицы не затронуты настройкой
innodb_file_per_table
.
DROP TABLE
и замедлить сканирование таблицы.
Однако, когда фрагментацией управляют, файлы в их собственном табличном
пространстве могут улучшить работу.
innodb_autoextend_increment
, которая определяет размер инкремента
(в MB) для автомасштабирования совместно используемого файла табличного
пространства, когда это становится полным, не относится к файлам табличного
пространства file-per-table, которые масштабируются независимо от
innodb_autoextend_increment
.
Начальные расширения небольшие, после них расширения
происходят в инкрементах 4 МБ.Опция
innodb_file_per_table
включена по умолчанию.
Установить
innodb_file_per_table
можно как параметр командной строки
--innodb_file_per_table
или добавив строку в раздел
[mysqld]
файла my.cnf
:
[mysqld] innodb_file_per_table=1
Вы можете также установить
innodb_file_per_table
динамически, в то время как сервер работает:
SET GLOBAL innodb_file_per_table=1;
При включении
innodb_file_per_table
Вы можете сохранить таблицы
InnoDB
в файл
.
В отличие от механизма хранения tbl_name
.ibdMyISAM
с его отдельными
файлами
и
tbl_name
.MYD
, tbl_name
.MYIInnoDB
хранит данные и индексы вместе в файле .ibd
.
При выключении
innodb_file_per_table
в Ваших опциях запуска и перезапуске сервера
или отключении этого через SET GLOBAL
, InnoDB
составляет новые таблицы в системном табличном пространстве, если Вы явно не
поместили таблицу в табличное пространство file-per-table
или общее табличное пространство, используя опцию
CREATE TABLE ... TABLESPACE
.
Вы можете всегда читать и писать любую таблицу InnoDB
,
независимо от установки file-per-table.
Чтобы переместить таблицу из системного табличного пространства в свое,
измените
innodb_file_per_table
и пересоздайте таблицу:
SET GLOBAL innodb_file_per_table=1;
ALTER TABLE table_name
ENGINE=InnoDB;
Таблицы, добавленные к системному табличному пространству через
CREATE TABLE ... TABLESPACE
или ALTER TABLE ... TABLESPACE
не затронуты
innodb_file_per_table
. Чтобы переместить эти таблицы из системного
табличного пространства в свое табличное пространство, они должны быть
перемещены явно, используя
ALTER TABLE ... TABLESPACE
.
InnoDB
всегда нуждается в системном табличном пространстве,
потому что помещает свой внутренний
словарь данных
и журналы отмены там. Файлы
.ibd
недостаточны для работы InnoDB
.
Когда таблица перемещена из системного табличного пространства в свое,
файлы с данными, которые составляют системное табличное пространство,
остаются того же самого размера. Место, прежде занятое таблицей, может быть
снова использовано для новых данных, но не для использования операционной
системой. Перемещая большие таблицы из системного табличного пространства,
где дисковое пространство ограничено, Вы можете предпочесть включить
innodb_file_per_table
и обновите весь экземпляр, применяя
mysqldump.
Как упомянуто выше, таблицы, добавленные к системному табличному пространству
через CREATE TABLE ... TABLESPACE
или ALTER TABLE ... TABLESPACE
не затронуты настройкой
innodb_file_per_table
. Эти таблицы должны быть перемещены индивидуально.
Чтобы создать новое табличное пространство
file-per-table
в определенном местоположении вне каталога данных MySQL, используйте параметр
DATA DIRECTORY =
в absolute_path_to_directory
CREATE TABLE
.
Запланируйте местоположение заранее, потому что Вы не можете использовать
DATA DIRECTORY
с ALTER TABLE
. Каталог, который Вы определяете, мог быть на другом устройстве
хранения данных с особыми характеристиками, таком как быстрый
SSD или особо большой
HDD.
В пределах целевого каталога MySQL создает подкаталог, соответствующий имени базы данных, и в его пределах файл .ibd для новой таблицы.
Следующий пример демонстрирует создание табличного пространства
file-per-table вне каталога данных MySQL. Это показывает
.ibd
, создаваемый в указанном каталоге.
mysql> USE test; Database changed mysql> SHOW VARIABLES LIKE 'innodb_file_per_table'; +-----------------------+-------+ | Variable_name | Value | +-----------------------+-------+ | innodb_file_per_table | ON | +-----------------------+-------+ 1 row in set (0.00 sec) mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) DATA DIRECTORY = '/alternative/directory'; Query OK, 0 rows affected (0.03 sec) # MySQL creates a .ibd file for the new table in a # subdirectory that corresponding # to the database name db_user@ubuntu:~/alternative/directory/test$ ls t1.ibd
Вы можете также использовать
CREATE TABLE ... TABLESPACE
в комбинации с DATA DIRECTORY
, чтобы создать табличное
пространство вне каталога данных MySQL. Чтобы сделать так, Вы должны
определить innodb_file_per_table
как имя табличного пространства.
CREATE TABLE t2 (c1 INT PRIMARY KEY) TABLESPACE = innodb_file_per_table DATA DIRECTORY = '/alternative/directory';
Вы не должны включать
innodb_file_per_table
, используя этот метод.
MySQL первоначально держит открытым файл .ibd
,
препятствуя Вам демонтировать устройство, но мог бы в конечном счете закрыть
таблицу, если сервер занят. Бойтесь случайно демонтировать внешнее
устройство, в то время как MySQL работает, или запустить MySQL, в то время
как устройство отмонтировано. Попытка получить доступ к таблице, когда
связанный файл .ibd
отсутствует, это
серьезная ошибка, которая требует перезапуска сервера.
Перезапуск сервера снимает ошибки и предупреждения, если файл
.ibd
не в ожидаемом пути.
.ibd
, всегда
используйте FLUSH TABLES ... FOR EXPORT
сначала, чтобы удостовериться, что все изменения, которые были
буферизованы в памяти, сброшены на
диск прежде, чем резервное копирование произойдет.DATA DIRECTORY
поддерживает
использование символических ссылок,
которые всегда был проблематичны и никогда не поддерживались
для таблиц InnoDB
tables.Этот раздел описывает, как скопировать табличные пространства
file-per-table
от одного сервера базы данных на другой. Свойство известно как
мобильность. Эта
особенность также поддерживает разделенные таблицы InnoDB
.
Для информации о других методах копирования таблиц InnoDB
см. раздел 16.8.3.
Есть много причин, почему Вы могли бы скопировать табличное пространство
InnoDB
file-per-table на другой сервер базы данных:
Выполнять отчеты, не создавая дополнительную нагрузку производственному серверу.
Процедура копирования табличного пространства возможна только,
когда включен параметр
innodb_file_per_table
, что является настройкой по умолчанию.
Таблицы, находящиеся в совместно используемом системном табличном
пространстве, не могут быть скопированы.
ALTER TABLE ... DISCARD TABLESPACE
поддержан для разделенных таблиц InnoDB
и
ALTER TABLE ... DISCARD PARTITION ...
TABLESPACE
поддержан для разделов.DISCARD TABLESPACE
не поддержан для табличных пространств с
родительским дочерним элементом (внешний ключ первичного ключа), когда
foreign_key_checks
установлен в 1
. Прежде, чем отказаться от табличного
пространства для родительско-дочерних таблиц, установите
foreign_key_checks=0
. Разделенные таблицы InnoDB
не поддерживают внешние ключи.ALTER TABLE ... IMPORT TABLESPACE
не проводит в жизнь ограничения внешнего ключа на импортированные
данные. Если есть ограничения внешнего ключа между таблицами, все таблицы
должны быть экспортированы в том же самом (логическом) моменте времени.
Разделенные таблицы InnoDB
не поддерживают внешние ключи.ALTER TABLE ...
IMPORT TABLESPACE
и
ALTER
TABLE ... IMPORT PARTITION ... TABLESPACE
не требуют
метафайл .cfg
с данными, чтобы импортировать табличное
пространство. Однако, проверки метаданных не выполнены, импортируя без
файла .cfg
, и предупреждение, подобное следующему, будет:
Message: InnoDB: IO Read error: (2, No such file or directory) Error opening '.\test\t.cfg', will attempt to import without schema verification 1 row in set (0.00 sec)
Способность импортировать без файла .cfg
может быть более
удобна, когда никакие несоответствия схемы не ожидаются. Дополнительно,
способность импортировать без файла .cfg
может быть полезна в сценариях восстановления катастрофического отказа, в
которых метаданные не могут быть собраны в файле .ibd
.
Если файл .cfg
не используется, InnoDB
использует эквивалент SELECT MAX(ai_col) FROM
, чтобы инициализировать
счетчик автоинкремента в памяти, который используется в назначении значений
для столбца table_name
FOR UPDATEAUTO_INCREMENT
. Иначе текущее максимальное значение
счетчика автоинкремента считано из
InnoDB
AUTO_INCREMENT Counter Initialization.
ALTER TABLE ...
DISCARD PARTITION ... TABLESPACE
и
ALTER TABLE ...
IMPORT PARTITION ... TABLESPACE
на разделенных таблицах позволены
имена разделов и подразделов таблицы. Когда имя раздела определено, подраздел
того раздела включен в работу.innodb_file_per_table
должна быть ON
на ведущем и на ведомом устройствах.InnoDB
табличное пространство и имена таблиц
внутренне хранятся в нижнем регистре. Чтобы избежать проблем импорта на
чувствительных к регистру операционных системах, таких как Linux и UNIX,
создайте все базы данных, табличные пространства и таблицы, используя
строчные имена. Удобный способ достигнуть этого состоит в том, чтобы добавить
следующую строку к разделу [mysqld]
файла
my.cnf
или my.ini
прежде, чем создать базы данных, табличные пространства или таблицы:
[mysqld] lower_case_table_names=1
ALTER TABLE ... DISCARD TABLESPACE
и ALTER TABLE ...IMPORT
TABLESPACE
не поддержаны с таблицами, которые принадлежат
общему табличному пространству InnoDB
. Для получения
дополнительной информации см.
CREATE TABLESPACE
.InnoDB
настраивается
параметром
innodb_default_row_format
.
Попытка импортировать таблицу, которая явно не определяет формат строки
(ROW_FORMAT
) или использует ROW_FORMAT=DEFAULT
,
может привести к ошибке несоответствия схемы, если
innodb_default_row_format
на исходном сервере отличается от
установки на целевом сервере. Для соответствующей информации см.
раздел 16.10.2.InnoDB
производит файл .cfp
в дополнение к метафайлу .cfg
.
Файл .cfp
должен быть скопирован к целевому серверу вместе с
.cfg
и файлом табличного пространства прежде, чем
скомандовать ALTER TABLE ... IMPORT
TABLESPACE
на целевом сервере. .cfp
содержит ключ передачи и зашифрованный ключ табличного пространства. При
импорте InnoDB
использует ключ передачи, чтобы дешифровать ключ
табличного пространства. Для соответствующей информации см.
раздел 16.7.10.
Если Вы транспортируете таблицы, которые зашифрованы, используя шифрование табличного пространства см. здесь прежде, чем Вы начнете для дополнительной процедурной информации.
Эта процедура демонстрирует, как скопировать таблицу с одного экземпляра MySQL на другой. Та же самая процедура с незначительными корректировками может использоваться, чтобы выполнить полное табличное восстановление на том же самом сервере.
На исходном сервере составьте таблицу, если ее нет:
mysql> use test; mysql> CREATE TABLE t(c1 INT) engine=InnoDB;
mysql> use test; mysql> CREATE TABLE t(c1 INT) engine=InnoDB;
InnoDB
должен отказаться от табличного пространства, которое
присоединено к таблице получения.
mysql> ALTER TABLE t DISCARD TABLESPACE;
FLUSH TABLES ... FOR EXPORT
,
чтобы создать метафайл .cfg
с данными:
mysql> use test; mysql> FLUSH TABLES t FOR EXPORT;
Метафайл (.cfg
) создается в
каталоге данных InnoDB
.
FLUSH TABLES ... FOR EXPORT
гарантирует, что изменения названной таблицы сброшены на диск
так, чтобы двоичная табличная копия могла быть сделана в то время, как сервер
работает. Когда выполняется
FLUSH TABLES ... FOR EXPORT
,
InnoDB
делает файл .cfg
в том же самом каталоге базы данных, где таблица. Файл .cfg
содержит метаданные, используемые для проверки схемы, импортируя
файл табличного пространства.
Скопируйте файлы .ibd
и .cfg
с исходного сервера на целевой:
shell> scp/path/to/datadir
/test/t.{ibd,cfg} destination-server:/path/to/datadir
/test
Файлы .ibd
и .cfg
должны быть скопированы прежде, чем выпустить совместно используемые
блокировки, как описано в следующем шаге.
На исходном сервере скомандуйте
UNLOCK TABLES
, чтобы
выпустить блокировки, приобретенные
FLUSH TABLES ... FOR EXPORT
:
mysql> use test; mysql> UNLOCK TABLES;
mysql> use test; mysql> ALTER TABLE t IMPORT TABLESPACE;
ALTER TABLE ... IMPORT TABLESPACE
не проводит в жизнь ограничения внешнего ключа на импортированные
данные. Если есть ограничения внешнего ключа между таблицами, все таблицы
должны быть экспортированы в том же самом (логическом) моменте времени. В
этом случае Вы прекратите обновлять таблицы, закроете все транзакции,
приобрете совместно используемые блокировки на таблицах и затем
выполните экспортную работу.
Эта процедура демонстрирует, как скопировать разделенную таблицу
InnoDB
с одного сервера на другой. Та же самая процедура с
незначительными корректировками может использоваться, чтобы выполнить полное
восстановление разделенной таблицы на том же самом сервере.
На исходном сервере составьте разделенную таблицу, если ее нет. В следующем примере составлена таблица с тремя разделами (p0, p1, p2):
mysql> use test; mysql> CREATE TABLE t1 (i int) ENGINE = InnoDB PARTITION BY KEY (i) PARTITIONS 3;
В каталоге /
Вы будете видеть отдельное табличное пространство (datadir
/test.ibd
)
для каждого из этих трех разделов.
mysql> \! ls /path/to/datadir
/test/
t1#P#p0.ibd t1#P#p1.ibd t1#P#p2.ibd
mysql> use test; mysql> CREATE TABLE t1 (i int) ENGINE = InnoDB PARTITION BY KEY (i) PARTITIONS 3;
В каталоге /
Вы будете видеть отдельное табличное пространство (datadir
/test.ibd
)
для каждого из этих трех разделов.
mysql> \! ls /path/to/datadir
/test/
t1#P#p0.ibd t1#P#p1.ibd t1#P#p2.ibd
mysql> ALTER TABLE t1 DISCARD TABLESPACE;
Три файла .ibd
, которые составляют табличное пространство для
разделенной таблицы, исчезают из каталога
/
.datadir
/test
FLUSH TABLES ... FOR EXPORT
, что
создаст файл .cfg
:
mysql> use test; mysql> FLUSH TABLES t1 FOR EXPORT;
Файлы данных, один для каждого табличного пространства (.ibd
), и метафайл (.cfg
) создаются в каталоге
/
на исходном сервере:
datadir
/test
mysql> \! ls /path/to/datadir
/test/
t1#P#p0.ibd t1#P#p1.ibd t1#P#p2.ibd
t1#P#p0.cfg t1#P#p1.cfg t1#P#p2.cfg
FLUSH TABLES ... FOR EXPORT
гарантирует, что изменения названной таблицы сброшены на диск так, чтобы
двоичная табличная копия могла быть сделана в то время, как сервер работает.
Когда выполняется FLUSH TABLES ...
FOR EXPORT
, InnoDB
создает файл
.cfg
с данными для файлов табличного пространства таблицы в том
же самом каталоге базы данных, где таблица. .cfg
содержат метаданные, используемые для проверки схемы, импортируя файлы
табличного пространства. FLUSH TABLES ... FOR
EXPORT
может быть выполнен только на таблице, не на
отдельном табличном разделе.
Скопируйте файлы .ibd
и .cfg
на сервер назначения:
shell> scp/path/to/datadir
/test/t1*.{ibd,cfg} destination-server:/path/to/datadir
/test
Файлы .ibd
и .cfg
должны быть скопированы прежде, чем выпустить совместно используемые
блокировки, как описано в следующем шаге.
На исходном сервере скомандуйте
UNLOCK TABLES
, чтобы снять блокировки, приобретенные
FLUSH TABLES ... FOR EXPORT
:
mysql> use test; mysql> UNLOCK TABLES;
mysql> use test; mysql> ALTER TABLE t1 IMPORT TABLESPACE;
Эта процедура демонстрирует, как скопировать табличный раздел. Та же самая процедура с незначительными корректировками может использоваться, чтобы выполнить восстановление раздела. В следующем примере разделенная таблица с четырьмя разделами (p0, p1, p2, p3) составлена на исходном сервере. Два раздела (p2 и p3) скопированы целевому серверу.
На исходном сервере составьте разделенную таблицу, если ее нет. В следующем примере составлена таблица с четырьмя разделами (p0, p1, p2, p3):
mysql> use test; mysql> CREATE TABLE t1 (i int) ENGINE = InnoDB PARTITION BY KEY (i) PARTITIONS 4;
В каталоге /
Вы будете видеть отдельное табличное пространство (datadir
/test.ibd
)
для каждого из этих четырех разделов.
mysql> \! ls /path/to/datadir
/test/
t1#P#p0.ibd t1#P#p1.ibd t1#P#p2.ibd t1#P#p3.ibd
mysql> use test; mysql> CREATE TABLE t1 (i int) ENGINE = InnoDB PARTITION BY KEY (i) PARTITIONS 4;
В каталоге /
Вы будете видеть отдельное табличное пространство (datadir
/test.ibd
)
для каждого из этих четырех разделов.
mysql> \! ls /path/to/datadir
/test/
t1#P#p0.ibd t1#P#p1.ibd t1#P#p2.ibd t1#P#p3.ibd
mysql> ALTER TABLE t1 DISCARD PARTITION p2, p3 TABLESPACE;
Файлы .ibd
для двух разделов, от которых отказываются,
удалены из каталога /
на целевом сервере, оставляя следующие файлы:
datadir
/test
mysql> \! ls /path/to/datadir
/test/
t1#P#p0.ibd t1#P#p1.ibd
Когда ALTER TABLE ... DISCARD
PARTITION ... TABLESPACE
работает на разделенных таблицах имена
таблиц и подразделов позволены. Когда имя раздела определено, подраздел того
раздела включен в работу.
На исходном сервере выполните
FLUSH TABLES ... FOR EXPORT
, чтобы
получить файл .cfg
.
mysql> use test; mysql> FLUSH TABLES t1 FOR EXPORT;
Файл (.cfg
) для каждого раздела создается в каталоге
/
на исходном сервере. Есть
datadir
/test.cfg
для каждого табличного пространства (.ibd
).
mysql> \! ls /path/to/datadir
/test/
t1#P#p0.ibd t1#P#p1.ibd t1#P#p2.ibd t1#P#p3.ibd
t1#P#p0.cfg t1#P#p1.cfg t1#P#p2.cfg t1#P#p3.cfg
FLUSH TABLES ...
FOR EXPORT
гарантирует, что изменения в названной таблице
сброшены на диск так, чтобы двоичная табличная копия могла быть сделана в то
время, как сервер работает. Когда
FLUSH TABLES ...
FOR EXPORT
работает, InnoDB
производит файл
.cfg
с данными для файлов табличного пространства таблицы в том
же самом каталоге базы данных, где таблица. .cfg
содержат метаданные, используемые для проверки схемы, импортируя файлы
табличного пространства. FLUSH TABLES ...
FOR EXPORT
может быть выполнен только на таблице, не на
отдельном табличном разделе.
Скопируйте файлы .ibd
и .cfg
на сервер назначения. В этом примере только файлы
.ibd
and .cfg
для разделов 2 (p2) и 3 (p3)
скопированы в каталог data
на сервере назначения. Другие разделы
остаются на исходном сервере.
shell> scp t1#P#p2.ibd t1#P#p2.cfg t1#P#p3.ibd t1#P#p3.cfg \
destination-server:/path/to/datadir
/test
Файлы .ibd
и .cfg
должны быть скопированы прежде, чем выпустить совместно используемые
блокировки, как описано в следующем шаге.
На исходном сервере скомандуйте
UNLOCK TABLES
, чтобы
выпустить блокировки, приобретенные
FLUSH TABLES ... FOR EXPORT
:
mysql> use test; mysql> UNLOCK TABLES;
mysql> use test; mysql> ALTER TABLE t1 IMPORT PARTITION p2, p3 TABLESPACE;
Когда ALTER TABLE ... DISCARD
PARTITION ... TABLESPACE
работает на разделенных таблицах имена
таблиц и подразделов позволены. Когда имя раздела определено, подраздел того
раздела включен в работу.
Следующая информация описывает внутренности и сообщения в журнале ошибок для процедуры копирования мобильных табличных пространств.
Когда ALTER TABLE
... DISCARD TABLESPACE
выполнена на целевом сервере:
Таблица заблокирована в режиме X.
Когда FLUSH TABLES ... FOR EXPORT
выполнен на исходном сервере:
Таблица заблокирована в совместно используемом режиме.
.cfg
.
Ожидаемые сообщения журнала ошибок для этой работы:
2013-09-24T13:10:19.903526Z 2 [Note] InnoDB: Sync to disk of '"test"."t"' started. 2013-09-24T13:10:19.903586Z 2 [Note] InnoDB: Stopping purge 2013-09-24T13:10:19.903725Z 2 [Note] InnoDB: Writing table metadata to './test/t.cfg' 2013-09-24T13:10:19.904014Z 2 [Note] InnoDB: Table '"test"."t"' flushed to disk
Когда UNLOCK TABLES
выполнен на исходном сервере:
Двоичный файл .cfg удален.
Ожидаемые сообщения журнала ошибок для этой работы:
2013-09-24T13:10:21.181104Z 2 [Note] InnoDB: Deleting the meta-data file './test/t.cfg' 2013-09-24T13:10:21.181180Z 2 [Note] InnoDB: Resuming purge
Когда ALTER TABLE ... IMPORT
TABLESPACE
выполнен на целевом сервере, алгоритм импорта выполняет
следующие операции для каждого импортируемого табличного пространства:
Каждая страница табличного пространства проверена на повреждение.
Ожидаемые сообщения журнала ошибок для этой работы:
2013-07-18 15:15:01 34960 [Note] InnoDB: Importing tablespace for table 'test/t' that was exported from host 'ubuntu' 2013-07-18 15:15:01 34960 [Note] InnoDB: Phase I - Update all pages 2013-07-18 15:15:01 34960 [Note] InnoDB: Sync to disk 2013-07-18 15:15:01 34960 [Note] InnoDB: Sync to disk - done! 2013-07-18 15:15:01 34960 [Note] InnoDB: Phase III - Flush changes to disk 2013-07-18 15:15:01 34960 [Note] InnoDB: Phase IV - Flush complete
Вы можете также получить предупреждение, что от табличного пространства
отказываются (если Вы отказались от табличного пространства для целевой
таблицы) и сообщение, что статистика не может быть вычислена из-за
отсутствия файла .ibd
:
2013-07-18 15:14:38 34960 [Warning] InnoDB: Table "test"."t" tablespace is set as discarded. 2013-07-18 15:14:38 7f34d9a37700 InnoDB: cannot calculate statistics for table "test"."t" because the .ibd file is missing. For help, please refer to http://dev.mysql.com/doc/refman/5.8/en/innodb-troubleshooting.html
Вы можете сохранить журналы отмены в одном или более отдельных табличных пространствах отмены за пределами системного табличного пространства. Это расположение отличается от конфигурации значения по умолчанию, где журнал отмены это часть системного табличного пространства. Образцы ввода/вывода для журнала отмены делают эти табличные пространства хорошими кандидатами, чтобы переместить на SSD, сохраняя системное табличное пространство на жестком диске. Пользователи не могут удалить отдельные табличные пространства, создаваемые, чтобы хранить журналы или отдельные сегменты в тех табличных пространствах. Однако, журналы отмены, сохраненные в табличных пространствах отмены, могут быть усеченными. Для получения дополнительной информации см. раздел 16.7.8.
Поскольку эти файлы обрабатывают операции ввода/вывода, прежде сделанные в системном табличном пространстве, мы расширяем определение системного табличного пространства, чтобы включать эти новые файлы.
Журналы отмены также упоминаются как сегменты отмены.
Эта особенность вовлекает следующие новые или переименованные параметры конфигурации:
innodb_undo_directory
innodb_rollback_segments
становится
innodb_undo_logs
. Старое название все еще доступно для совместимости.Поскольку особенность
журнала отмены вовлекает установку двух нединамических переменных запуска
(
innodb_undo_tablespaces
и
innodb_undo_directory
), эта опция может быть активирована только
инициализируя экземпляр MySQL.
Чтобы использовать эту функцию:
Выберите путь, где хранить журналы отмены. Вы определите
путь как параметр
innodb_undo_directory
в Вашем конфигурационном файле MySQL или
скрипте запуска. Если никакой путь не определен, табличные пространства
отмены создаются в каталоге данных MySQL, как определено
datadir
.
innodb_undo_logs
. Вы можете запустить с относительно низким значением и увеличить его в
течение долгого времени, чтобы исследовать эффект.
Один журнал отмены всегда назначается на системное табличное пространство,
и 32 журнала отмены сохранены для использования временными таблицами и
размещены во временном табличном пространстве (ibtmp1
).
Поэтому, чтобы выделить журналы отмены для табличных пространств отмены,
innodb_undo_logs
должен быть установлен в значение, больше 33. Например, если у Вас есть
два табличных пространства отмены
(
innodb_undo_tablespaces=2
),
innodb_undo_logs
должен быть установлен в 35, чтобы назначить один журнал отмены на
каждое из двух табличных пространств отмены.
Когда Вы конфигурируете отдельные табличные пространства отмены, журнал отмены в системном табличном пространстве бездействует.
Выберите ненулевое значение для
innodb_undo_tablespaces
. Множественные журналы отмены,
определенные
innodb_undo_logs
, разделены между этим числом отдельных табличных
пространств (файлы .ibd
). Это значение установлено для жизни сервера MySQL,
так что, если Вы не уверены в оптимальном значении, повысьте его.
innodb_undo_logs
и повторно делайте тесты производительности. Найдите значение, где Вы
прекращаете получать улучшение в работе ввода/вывода.Хранение журналов отмены позволяют MySQL осуществлять ввод/вывод и оптимизацию памяти, связанную с этими транзакционными данными. Например, потому что данные об отмене написаны на диск и затем редко используются (только в случае восстановления катастрофического отказа), это не должно быть сохранено в кэш-памяти файловой системы, в свою очередь позволяя более высокий процент системной памяти выделить буферному пулу.
Типичная передовая практика SSD: хранить системное табличное пространство на жестком диске и переместить табличные пространства per-table на SSD.
Физические файлы табличного пространства называют
undo
, где N
N
ID пространства, включая начальные нули.
Вы можете усечь журналы отмены, которые находятся в табличных пространствах отмены. Для получения дополнительной информации см. раздел 16.7.8.
Вы можете усечь журналы отмены, которые находятся в табличных пространствах отмены, при условии, что следующие условия верны:
Ваш случай MySQL сконфигурирован минимум с
двумя табличными пространствами отмены
(
innodb_undo_tablespaces=2
).
Когда табличное пространство отмены является усеченным, оно временно
отключается. Чтобы сервер функционировал, должно быть по крайней мере одно
активное табличное пространство отмены. Число табличных пространств отмены
определено опцией
innodb_undo_tablespaces
, которая может быть установлена только,
когда сервер MySQL инициализирован. Значение по умолчанию 0. Проверить
значение
innodb_undo_tablespaces
можно так:
mysql> SELECT @@innodb_undo_tablespaces; +---------------------------+ | @@innodb_undo_tablespaces | +---------------------------+ | 2 | +---------------------------+ 1 row in set (0.00 sec)
innodb_undo_logs
, который определяет число
сегментов отмены,
используемых InnoDB
, должен быть установлен в 35 или больше.
Установка 35 или больше гарантирует, что журнал отмены, назначен на каждое из
двух табличных пространств отмены. С
innodb_undo_logs
35:
Первый сегмент отмены всегда находится в системном табличном пространстве (когда табличные пространства отмены присутствуют, этот сегмент отмены является бездействующим).
ibtmp1
).Есть отношения "многие к одному" между сегментами отмены и
табличными пространствами отмены. Если число выделенных сегментов отмены
больше 35, доаолнитльные
сегменты отмены назначаются табличным пространствам круговым способом.
Например, если у Вас есть 2 табличных пространства отмены (табличное
пространство отмены 1 и табличное пространство отмены 2) и
innodb_undo_logs=37
, табличному пространству отмены 1 и табличному пространству отмены 2
каждому назначили бы второй сегмент отмены.
По умолчанию
innodb_undo_logs
128, что является также максимальным значением.
Проверить значение
innodb_undo_logs
можно так:
mysql> SELECT @@innodb_undo_logs; +--------------------+ | @@innodb_undo_logs | +--------------------+ | 128 | +--------------------+ 1 row in set (0.00 sec)
innodb_undo_logs
динамическая глобальная переменная и может быть сконфигурирована,
используя SET GLOBAL
:
mysql> SET GLOBAL innodb_undo_logs=128;
Чтобы усечь журналы отмены, которые находятся в табличных пространствах
отмены, Вы должны сначала включить
innodb_undo_log_truncate
.
mysql> SET GLOBAL innodb_undo_log_truncate=ON;
Когда Вы включаете
innodb_undo_log_truncate
, файлы табличного пространства
отмены, которые превышают предел размера, определенный
innodb_max_undo_log_size
, отмечены для усечения.
innodb_max_undo_log_size
динамическая глобальная переменная со
значением по умолчанию 1024 MiB (1073741824 байт).
mysql> SELECT @@innodb_max_undo_log_size; +----------------------------+ | @@innodb_max_undo_log_size | +----------------------------+ | 1073741824 | +----------------------------+ 1 row in set (0.00 sec)
Вы можете сконфигурировать
innodb_max_undo_log_size
с использованием SET GLOBAL
:
mysql> SET GLOBAL innodb_max_undo_log_size=2147483648; Query OK, 0 rows affected (0.00 sec)
Когда
innodb_undo_log_truncate
включена:
Табличные пространства отмены, которые превышают
innodb_max_undo_log_size
, отмечены для усечения. Выбор табличного
пространства отмены для усечения выполнен круговым способом, чтобы не усекать
то же самое табличное пространство отмены каждый раз.
Если Вы проверяете размер табличного пространства отмены после того
усечения, размер файла может быть больше 10 МБ из-за непосредственного
использования после завершения работы усечения. Опция
innodb_undo_directory
определяет местоположение файлов табличного пространства отмены.
Значение по умолчанию . представляет каталог, где
InnoDB
создает другие файлы системного журнала по умолчанию.
mysql> select @@innodb_undo_directory; +-------------------------+ | @@innodb_undo_directory | +-------------------------+ | . | +-------------------------+ 1 row in set (0.00 sec)
Сегменты отмены включены так, чтобы они могли быть выделены новым транзакциям.
Табличное пространство отмены не может быть усечено, пока его сегменты
отмены не освобождены. Обычно система чистки освобождает сегменты отмены
каждый 128-й раз. Чтобы ускорить усечение табличных пространств отмены, Вы
можете использовать опцию
innodb_purge_rseg_truncate_frequency
, чтобы временно увеличить
частоту, с которой система чистки освобождает сегменты отмены. По умолчанию
innodb_purge_rseg_truncate_frequency
128, что
является также максимальным значением.
mysql> select @@innodb_purge_rseg_truncate_frequency; +----------------------------------------+ | @@innodb_purge_rseg_truncate_frequency | +----------------------------------------+ | 128 | +----------------------------------------+ 1 row in set (0.00 sec)
Чтобы увеличить частоту, с которой поток чистки освобождает сегменты
отмены, уменьшите значение
innodb_purge_rseg_truncate_frequency
:
mysql> SET GLOBAL innodb_purge_rseg_truncate_frequency=32; Query OK, 0 rows affected (0.00 sec)
В то время как работа усечения табличного пространства отмены происходит,
сегменты отмены в одном табличном пространстве отмены временно
дезактивированы. Например, если у Вас есть 2 табличных пространства отмены
(
innodb_undo_tablespaces=2
) и 128 выделенных журналов отмены
(innodb_undo_logs=128
), 95 из журналов отмены находятся в двух табличных пространствах
отмены (48 сегментов отмены в одном табличном пространстве отмены и 47 в
другом). Если первое табличное пространство отмены взято офлайн, 48 журналов
отмены сделаны бездействующими, уменьшая ресурс журнала отмены немного
больше, чем наполовину. В то время, как работа усечения происходит,
остающиеся журналы отмены принимают на себя всю системную нагрузку, что может
привести к небольшой исполнительной деградации.
Степень исполнительной деградации зависит в ряде факторов, включая:
Число табличных пространств отмены.
Общее табличное пространство это особенность табличного пространства, которая обеспечивает следующие способности:
Подобно системному табличному пространству, общие табличные пространства это совместно используемые табличные пространства, которые могут хранить данные для многих таблиц.
innodb_file_format
или
innodb_file_per_table
и при этом эти переменные не имеют никакого
эффекта на общие табличные пространства.TABLESPACE
может использоваться с
CREATE TABLE
, чтобы
составлять таблицы в общих табличных пространствах, табличных пространствах
file-per-table или в системном табличном пространстве.TABLESPACE
может использоваться с
ALTER TABLE
, чтобы
перемещать таблицы между общими табличными пространствами, табличными
пространствами file-per-table и системным табличным пространством. Ранее не
было возможно переместить таблицу от табличного пространства file-per-table
к системному табличному пространству. С общей особенностью табличного
пространства Вы можете теперь сделать так.Общие табличные пространства создаются, используя
CREATE TABLESPACE
.
CREATE TABLESPACE tablespace_name ADD DATAFILE 'file_name' [FILE_BLOCK_SIZE = value] [ENGINE [=] engine_name]
Общее табличное пространство может быть создано в каталоге данных MySQL или в каталоге за пределами каталога данных MySQL. Чтобы избегать конфликтов с неявно создаваемыми табличными пространствами file-per-table, создание общего табличного пространства в подкаталоге в соответствии с каталогом данных MySQL не поддержано. Кроме того, создавая общее табличное пространство за пределами каталога данных MySQL, каталог должен существовать до создания табличного пространства.
Например:
Создание общего табличного пространства в каталоге данных MySQL:
mysql> CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB;
Создание общего табличного пространства в каталоге за пределами каталога данных MySQL:
mysql> CREATE TABLESPACE `ts1` ADD DATAFILE '/my/tablespace/directory/ts1.ibd' Engine=InnoDB;
Вы можете определить путь относительно каталога данных MySQL, пока каталог
табличного пространства не является подкаталогом каталога данных MySQL. В
этом примере my_tablespace
каталог на том же самом уровне, как
каталог данных MySQL:
mysql> CREATE TABLESPACE `ts1` ADD DATAFILE '../my_tablespace/ts1.ibd' Engine=InnoDB;
ENGINE = InnoDB
должен быть определен как часть
CREATE TABLESPACE
или InnoDB
должен быть определен как механизм хранения по
умолчанию (
default_storage_engine=InnoDB
).
После создания общего табличного пространства, Вы можете использовать
CREATE TABLE
или
tbl_name
... TABLESPACE [=] tablespace_name
ALTER TABLE
, чтобы добавить таблицы к
табличному пространству, как показано в следующих примерах:tbl_name
TABLESPACE [=]
tablespace_name
mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1 ROW_FORMAT=COMPACT;
mysql> ALTER TABLE t2 TABLESPACE ts1;
Для подробной информации о синтаксисе см.
CREATE TABLE
и
ALTER TABLE
.
Общие табличные пространства поддерживают все форматы строки таблицы
(REDUNDANT
, COMPACT
,
DYNAMIC
, COMPRESSED
), но сжатые и несжатые таблицы
не могут сосуществовать в том же самом общем табличном пространстве из-за
различных физических размеров страницы.
Для общего табличного пространства, чтобы содержать сжатые таблицы
(ROW_FORMAT=COMPRESSED
), FILE_BLOCK_SIZE
должен быть определен, и FILE_BLOCK_SIZE
должно быть допустимым сжатым размером страницы относительно
innodb_page_size
. Кроме того, физический размер страницы сжатой таблицы
(KEY_BLOCK_SIZE
) должен быть равным
FILE_BLOCK_SIZE/1024
. Например, если
innodb_page_size=16K
и FILE_BLOCK_SIZE=8K
,
KEY_BLOCK_SIZE
из таблицы должен быть 8.
Следующая таблица показывает допустимые
FILE_BLOCK_SIZE
и KEY_BLOCK_SIZE
для каждого
innodb_page_size
. FILE_BLOCK_SIZE
могут также быть определены в байтах.
Определить допустимое KEY_BLOCK_SIZE
для данного
FILE_BLOCK_SIZE
можно, поделив
FILE_BLOCK_SIZE
на 1024. Табличное сжатие не поддерживает
размеры страницы 32K и 64K. Для получения дополнительной информации о
KEY_BLOCK_SIZE
см.
CREATE TABLE
и
раздел 16.9.1.2.
Таблица 16.5. FILE_BLOCK_SIZE и KEY_BLOCK_SIZE для CREATE TABLESPACE
Размер страницы InnoDB (innodb_page_size) | Permitted FILE_BLOCK_SIZE | Permitted KEY_BLOCK_SIZE |
---|---|---|
64K | 64K (65536) | Сжатие не поддерживается |
32K | 32K (32768) | Сжатие не поддерживается |
16K | 16K (16384) | N/A: Если
innodb_page_size
равно FILE_BLOCK_SIZE ,
табличное пространство не может содержать сжатую таблицу. |
8K (8192) | 8 | |
4K (4096) | 4 | |
2K (2048) | 2 | |
1K (1024) | 1 | |
8K | 8K (8192) | N/A: Если
innodb_page_size
равно FILE_BLOCK_SIZE ,
табличное пространство не может содержать сжатую таблицу. |
4K (4096) | 4 | |
2K (2048) | 2 | |
1K (1024) | 1 | |
4K | 4K (4096) | N/A: Если
innodb_page_size
равно FILE_BLOCK_SIZE ,
табличное пространство не может содержать сжатую таблицу. |
2K (2048) | 2 | |
1K (1024) | 1 |
Этот пример демонстрирует создание общего табличного пространства и
добавление сжатой таблицы. Пример принимает значение по умолчанию
innodb_page_size
16K. FILE_BLOCK_SIZE
8192 требует, чтобы у сжатой таблицы
был KEY_BLOCK_SIZE
8.
mysql> CREATE TABLESPACE `ts2` ADD DATAFILE 'ts2.ibd' FILE_BLOCK_SIZE = 8192 Engine=InnoDB; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE t4 (c1 INT PRIMARY KEY) TABLESPACE ts2 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; Query OK, 0 rows affected (0.00 sec)
Если Вы не определяете FILE_BLOCK_SIZE
,
создавая общее табличное пространство, FILE_BLOCK_SIZE
по умолчанию
innodb_page_size
. Когда
FILE_BLOCK_SIZE
=
innodb_page_size
, табличное пространство может содержать
только таблицы с несжатым форматом строки
(COMPACT
, REDUNDANT
и DYNAMIC
).
Вы можете использовать ALTER TABLE
с опцией TABLESPACE
, чтобы переместить неразделенную
таблица к существующему общему табличному пространству, к новому табличному
пространству file-per-table или к системному табличному пространству.
Выполнение ALTER TABLE
на
разделенной таблице только изменяет табличное
пространство по умолчанию таблицы. Это не перемещает разделы таблицы.tbl_name
TABLESPACE [=]
tablespace_name
Чтобы переместить неразделенную таблицу от табличного пространства
file-per-table или системного табличного пространства в общее, определите
название общего табличного пространства. Общее табличное пространство должно
уже существовать. См. CREATE
TABLESPACE
.
ALTER TABLE tbl_name TABLESPACE [=] tablespace_name
Чтобы переместить неразделенную таблицу от общего табличного пространства
или табличного пространства file-per-table в системное, надо определить
innodb_system
как имя табличного пространства.
ALTER TABLE tbl_name ... TABLESPACE [=] innodb_system
Чтобы переместить неразделенную таблицу от системного табличного
пространства или общего табличного пространства в file-per-table, укажите
innodb_file_per_table
как имя табличного пространства.
ALTER TABLE tbl_name ... TABLESPACE [=] innodb_file_per_table
ALTER TABLE ... TABLESPACE
всегда вызывает полное пересоздание таблицы, даже если атрибут
TABLESPACE
не изменился от его предыдущего значения.
ALTER TABLE ... TABLESPACE
не поддерживает перемещение
таблицы из временного табличного пространства в постоянное.
DATA DIRECTORY
разрешен с CREATE TABLE ...
TABLESPACE=innodb_file_per_table
, но иное не поддержано для
использования в комбинации с опцией TABLESPACE
.
Опция TABLESPACE
может использоваться, чтобы назначить
отдельный табличный раздел или подраздел к
общему табличному
пространству, отдельному табличному пространству file-per-table
или системному табличному пространству. Все разделы должны принадлежать тому
же самому механизму хранения.
Использование продемонстрировано в следующих примерах.
mysql> CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB; mysql> CREATE TABLESPACE `ts2` ADD DATAFILE 'ts2.ibd' Engine=InnoDB; mysql> CREATE TABLE t1 (a INT, b INT) ENGINE = InnoDB -> PARTITION BY RANGE(a) SUBPARTITION BY KEY(b) ( -> PARTITION p1 VALUES LESS THAN (100) TABLESPACE=`ts1`, -> PARTITION p2 VALUES LESS THAN (1000) TABLESPACE=`ts2`, -> PARTITION p3 VALUES LESS THAN (10000) TABLESPACE `innodb_file_per_table`, -> PARTITION p4 VALUES LESS THAN (100000) TABLESPACE `innodb_system`); mysql> CREATE TABLE t2 (a INT, b INT) ENGINE = InnoDB -> PARTITION BY RANGE(a) SUBPARTITION BY KEY(b) ( -> PARTITION p1 VALUES LESS THAN (100) TABLESPACE=`ts1` -> (SUBPARTITION sp1, SUBPARTITION sp2), -> PARTITION p2 VALUES LESS THAN (1000) -> (SUBPARTITION sp3, -> SUBPARTITION sp4 TABLESPACE=`ts2`), -> PARTITION p3 VALUES LESS THAN (10000) -> (SUBPARTITION sp5 TABLESPACE `innodb_system`, -> SUBPARTITION sp6 TABLESPACE `innodb_file_per_table`));
Опция TABLESPACE
также допустима с
ALTER TABLE
.
mysql> ALTER TABLE t1 ADD PARTITION (PARTITION p5 VALUES LESS THAN (1000000) TABLESPACE = `ts1`);
Если опция TABLESPACE =
не определена, tablespace_name
ALTER TABLE ...
ADD PARTITION
добавляет раздел к табличному пространству по
умолчанию таблицы, которое может быть определено на табличном уровне во время
CREATE TABLE
или
ALTER TABLE
.
Чтобы проверить, что раздел был помещен в указанные табличные
пространства, Вы можете запросить
INFORMATION_SCHEMA.INNODB_SYS_TABLES
:
mysql> SELECT NAME, SPACE, SPACE_TYPE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES -> WHERE NAME LIKE '%t1%'; +-----------------------+-------+------------+ | NAME | SPACE | SPACE_TYPE | +-----------------------+-------+------------+ | test/t1#P#p1#SP#p1sp0 | 57 | General | | test/t1#P#p2#SP#p2sp0 | 58 | General | | test/t1#P#p3#SP#p3sp0 | 59 | Single | | test/t1#P#p4#SP#p4sp0 | 0 | System | | test/t1#P#p5#SP#p5sp0 | 57 | General | +-----------------------+-------+------------+ mysql> SELECT NAME, SPACE, SPACE_TYPE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES -> WHERE NAME LIKE '%t2%'; +---------------------+-------+------------+ | NAME | SPACE | SPACE_TYPE | +---------------------+-------+------------+ | test/t2#P#p1#SP#sp1 | 57 | General | | test/t2#P#p1#SP#sp2 | 57 | General | | test/t2#P#p2#SP#sp3 | 60 | Single | | test/t2#P#p2#SP#sp4 | 58 | General | | test/t2#P#p3#SP#sp5 | 0 | System | | test/t2#P#p3#SP#sp6 | 61 | Single | +---------------------+-------+------------+
Чтобы переместить табличное разделение в иное табличное пространство, Вы
должны переместить каждый раздел, используя ALTER TABLE
.tbl_name
REORGANIZE PARTITION
Следующий пример демонстрирует, как переместить табличное разделение в
иное табличное пространство.
INFORMATION_SCHEMA.INNODB_SYS_TABLES
и
INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES
запрошены, чтобы проверить, что разделение помещено в
ожидаемое табличное пространство.
Если опция TABLESPACE =
не определена в запросе tablespace_name
REORGANIZE PARTITION
,
InnoDB
перемещает разделение в табличное пространство
по умолчанию таблицы. В этом примере табличное пространство ts1
,
которое определено на табличном уровне, является табличным пространством по
умолчанию для таблицы t1
. Раздел P3
перемещен от системного табличного пространства в ts1
, поскольку
нет опции TABLESPACE
в ALTER
TABLE t1 REORGANIZE PARTITION
для раздела P3
.
Чтобы изменить табличное пространство
по умолчанию разделенной таблицы, Вы можете сделать
ALTER TABLE
на
разделенной таблице.tbl_name
TABLESPACE [=]
tablespace_name
mysql> CREATE TABLESPACE ts1 ADD DATAFILE 'ts1.ibd'; mysql> CREATE TABLESPACE ts2 ADD DATAFILE 'ts2.ibd'; mysql> CREATE TABLE t1 ( a INT NOT NULL, PRIMARY KEY (a)) -> ENGINE=InnoDB TABLESPACE ts1 -> PARTITION BY RANGE (a) PARTITIONS 3 ( -> PARTITION P1 VALUES LESS THAN (2), -> PARTITION P2 VALUES LESS THAN (4) TABLESPACE `innodb_file_per_table`, -> PARTITION P3 VALUES LESS THAN (6) TABLESPACE `innodb_system`); mysql> SELECT A.NAME as partition_name, A.SPACE_TYPE as space_type, B.NAME as space_name -> FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES A -> LEFT JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES B -> ON A.SPACE = B.SPACE WHERE A.NAME LIKE '%t1%' ORDER BY A.NAME; +----------------+------------+--------------+ | partition_name | space_type | space_name | +----------------+------------+--------------+ | test/t1#P#P1 | General | ts1 | | test/t1#P#P2 | Single | test/t1#P#P2 | | test/t1#P#P3 | System | NULL | +----------------+------------+--------------+ mysql> ALTER TABLE t1 REORGANIZE PARTITION P1 -> INTO (PARTITION P1 VALUES LESS THAN (2) TABLESPACE = `ts2`); mysql> ALTER TABLE t1 REORGANIZE PARTITION P2 -> INTO (PARTITION P2 VALUES LESS THAN (4) TABLESPACE = `ts2`); mysql> ALTER TABLE t1 REORGANIZE PARTITION P3 -> INTO (PARTITION P3 VALUES LESS THAN (6)); mysql> SELECT A.NAME AS partition_name, A.SPACE_TYPE AS space_type, B.NAME AS space_name -> FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES A -> LEFT JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES B -> ON A.SPACE = B.SPACE WHERE A.NAME LIKE '%t1%' ORDER BY A.NAME; +----------------+------------+------------+ | partition_name | space_type | space_name | +----------------+------------+------------+ | test/t1#P#P1 | General | ts2 | | test/t1#P#P2 | General | ts2 | | test/t1#P#P3 | General | ts1 | +----------------+------------+------------+
DROP TABLESPACE
используется, чтобы удалить общее табличное пространство.
Все таблицы должны быть исключены из табличного пространства до
DROP TABLESPACE
.
Если табличное пространство не пусто,
DROP TABLESPACE
возвращает ошибку.
Табличное пространство не удалено автоматически, когда последняя
таблица в табличном пространстве удалена. Табличное пространство должно быть
удалено явно, используя
DROP TABLESPACE
.tablespace_name
Общее табличное пространство не принадлежит никакой особой базе данных.
DROP DATABASE
может удалить таблицы, которые принадлежат общему табличному пространству, но
она не может удалить табличное пространство, даже если
DROP DATABASE
удаляет все таблицы, которые принадлежат табличному пространству. Общее
табличное пространство должно быть явно, используя
DROP TABLESPACE
.
tablespace_name
Подобно системному табличному пространству, удаление
таблиц, сохраненных в общем табличном пространстве, создает свободное
пространство внутренне в общем табличном пространстве
файле данных .ibd,
которое может использоваться только для новых данных InnoDB
.
Пространство не освобождено назад к операционной системе, как
табличное пространство file-per-table удалено во время
DROP TABLE
.
Этот пример демонстрирует, как удалить
общее табличное пространство. Общее табличное пространство ts1
создается с единственной таблицей. Таблица должна быть удалена прежде, чем
все табличное пространство.
mysql> CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts10 Engine=InnoDB; Query OK, 0 rows affected (0.02 sec) mysql> DROP TABLE t1; Query OK, 0 rows affected (0.01 sec) mysql> DROP TABLESPACE ts1; Query OK, 0 rows affected (0.01 sec)
чувствительный к регистру идентификатор в MySQL.tablespace_name
Существующее табличное пространство не может быть изменено на общее табличное пространство.
ALTER TABLE
на таблице, которая находится в совместно используемом табличном
пространстве (общее табличное пространство или системное табличное
пространство) может увеличить количество места, использованного табличным
пространством. Такие операции требуют такого большого количества
дополнительного пространства, как данные в таблице плюс индекс.
Дополнительное пространство требуется для копирования таблицы.ALTER TABLE ...
DISCARD TABLESPACE
и
ALTER TABLE ... IMPORT TABLESPACE
не поддержаны для таблиц, которые принадлежат
общему табличному пространству.Для получения дополнительной информации см. раздел 14.1.16.
InnoDB
допускает шифрование данных для
таблиц, сохраненных в табличных пространствах
file-per-table.
Эта особенность обеспечивает шифрование для физических файлов с
данными табличного пространства.
Шифрование табличного пространства использует две архитектуры ключа
шифрования ряда, состоя из основного ключа шифрования и ключей табличного
пространства. Когда таблица зашифрована, ключ табличного пространства
зашифрован и сохранен в заголовке табличного пространства. Когда приложение
или пользователь хотят получить доступ к зашифрованным данным табличного
пространства, InnoDB
использует основной ключ шифрования, чтобы
дешифровать ключ табличного пространства. Основной ключ шифрования сохранен в
файле keyring
в местоположении, определенном опцией
keyring_file_data
. Дешифрованная версия ключа табличного пространства никогда не
изменяется, но основной ключ шифрования может быть изменен как требуется.
Это действие упоминается как ротация главного ключа.
Особенность шифрования табличного пространства полагается на плагин keyring для основного управления ключом шифрования.
Шифрование табличного пространства поддерживает алгоритм Advanced Encryption Standard (AES) block-based. Это использует режим блочного шифрования Electronic Codebook (ECB) для ключевого шифрования табличного пространства и режим блочного шифрования Cipher Block Chaining (CBC) для шифрования данных.
Особенность шифрования табличного пространства, предоставленная MySQL Community Edition, не предназначена как решение для соответствия установленным требованиям. Стандарты безопасности, такие как PCI, FIPS и другие требуют, чтобы использование систем ключевого менеджмента обеспечило, управляло и защитило ключи в ключевых хранилищах или модулях безопасности аппаратных средств (HSM).
Для часто задаваемых вопросов о особенности шифрования табличного пространства см. раздел A.15 .
Плагин keyring_file
должен быть установлен. Установка
плагина выполнена при запуске, используя опцию
--early-plugin-load
.
Ранняя загрузка гарантирует, что плагин доступен до инициализации
InnoDB
. Для установки плагина и инструкций конфигурации см.
раздел 7.5.3.
После того, как зашифрованные таблицы составлены в случае MySQL, плагин
должен продолжить загружаться, используя
early-plugin-load
до инициализации InnoDB
.
Чтобы проверить, что плагин является активным, используйте
SHOW PLUGINS
или запросите
INFORMATION_SCHEMA.PLUGINS
:
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS -> WHERE PLUGIN_NAME LIKE 'keyring%'; +--------------+---------------+ | PLUGIN_NAME | PLUGIN_STATUS | +--------------+---------------+ | keyring_file | ACTIVE | +--------------+---------------+
innodb_file_per_table
должна быть включена (значение по
умолчанию). Шифрование табличного пространства поддерживает только
табличные пространства
file-per-table. Альтернативно, Вы можете определить опцию
TABLESPACE='innodb_file_per_table'
, составляя зашифрованную
таблицу или изменяя существующую таблицу, чтобы включить шифрование.keyring
немедленно после составления первой зашифрованной таблицы, прежде и после
ротации главного ключа. Местоположение файла keyring
определено
опцией keyring_file_data
. См. раздел 7.5.3.
Чтобы включить шифрование для новой таблицы, укажите опцию
ENCRYPTION
в CREATE TABLE
.
mysql> CREATE TABLE t1 (c1 INT) ENCRYPTION='Y';
Чтобы включить шифрование для существующей таблицы, укажите опцию
ENCRYPTION
в ALTER TABLE
.
mysql> ALTER TABLE t1 ENCRYPTION='Y';
Чтобы выключить шифрование для таблицы, укажите опцию
ENCRYPTION='N'
в ALTER TABLE
.
mysql> ALTER TABLE t1 ENCRYPTION='N';
Запланируйте все, изменяя существующую таблицу с опцией
ENCRYPTION
. ALTER TABLE ...
ENCRYPTION
пересоздает таблицу алгоритмом
ALGORITHM=COPY
. ALGORITM=INPLACE
не поддержан.
Основной ключ шифрования должен периодически меняться и всякий раз, когда Вы подозреваете, что ключ, возможно, поставлен под угрозу.
Ротация главного ключа атомная работа на уровне сервера.
Каждый раз, когда основной ключ шифрования меняется, все ключи табличных
пространств повторно зашифрованы и сохранены назад к их соответствующим
заголовкам табличного пространства. Как атомная работа, перешифрование должно
пройти для всех ключей табличного пространства, как только работа начата.
Если ротация главного ключа прервана отказом сервера, InnoDB
продолжает процесс при перезапуске сервера.
Ротация основного ключа шифрования изменяет только основной ключ шифрования и повторно шифрует ключи табличного пространства. Это не дешифрует или повторно шифрует связанные данные о табличном пространстве.
Ротация основного ключа шифрования требует привилегии
SUPER
.
Чтобы сменить основной ключ шифрования:
mysql> ALTER INSTANCE ROTATE INNODB MASTER KEY;
ALTER INSTANCE
ROTATE INNODB MASTER KEY
поддерживает параллельный DML. Однако,
это не может быть выполнено одновременно с
CREATE TABLE ... ENCRYPTED
или ALTER TABLE ... ENCRYPTED
,
блокировки взяты, чтобы предотвратить конфликты, которые могли явиться
результатом параллельного выполнения этих запросов. Если один из
противоречивых запросов работает, он должно завершиться прежде, чем
другой сможет продолжить.
Если отказ сервера происходит во время ротации
главного ключа, InnoDB
продолжает работу
при перезапуске сервера.
Плагин keyring должен быть загружен до инициализации механизма хранения,
чтобы информация, необходимая, чтобы дешифровать страницы данных о табличном
пространстве, могла быть получена от заголовков табличного пространства
прежде инициализации InnoDB
и востановления
активности доступа к данным.
Когда инициализация и восстановление начинаются, ротация
восстанавливается. Из-за отказа сервера, некоторые ключи табличных
пространств могут уже быть зашифрованы, используя новый основной ключ
шифрования. InnoDB
читает данные о шифровании из каждого
заголовка табличного пространства, и если данные указывают, что ключ
табличного пространства зашифрован, используя старый ключ шифрования,
получает старый ключ и использует это, чтобы дешифровать ключ пространства.
InnoDB
тогда повторно шифрует ключ табличного пространства с
использованием нового основного ключа шифрования и сохраняет повторно
зашифрованный ключ табличного пространства назад в заголовке.
Когда зашифрованная таблица экспортируется, InnoDB
производит ключ передачи, который используется, чтобы
зашифровать ключ табличного пространства. Зашифрованный ключ табличного
пространства и ключ передачи сохранены в файле
.
Этот файл вместе с зашифрованным файлом табличного пространства обязан
выполнять работу импорта. При импорте tablespace_name
.cfpInnoDB
использует ключ передачи, чтобы дешифровать ключ табличного пространства
в
. Подробности в
разделе 16.7.6.tablespace_name
.cfp
ALTER INSTANCE ROTATE
INNODB MASTER KEY
поддержано в среде репликации, если
ведущее устройство и ведомые устройства выполняют версию MySQL, которая
поддерживает функцию шифрования табличного пространства.
ALTER
INSTANCE ROTATE INNODB MASTER KEY
внесен в
двоичный журнал на ведомых устройствах.ALTER INSTANCE ROTATE INNODB
MASTER KEY
провалился, оно не пишется в двоичный журнал и не
копируется на ведомые устройства.ALTER INSTANCE ROTATE
INNODB MASTER KEY
терпит неудачу, если плагин keyring установлен
на ведущем устройстве, но не на ведомом.keyring_file
установлен на ведущем
и на ведомом устройствах, но у ведомого устройства нет файла
keyring
, репликация ALTER
INSTANCE ROTATE INNODB MASTER KEY
создает файл
keyring
на ведомом устройстве, принимая что
данные о файле не кэшируются в памяти.
ALTER INSTANCE ROTATE INNODB MASTER
KEY
будет использовать данные о файле keyring
,
которые кэшируются в памяти, при наличии.Когда опция ENCRYPTION
определена в
CREATE TABLE
или
ALTER TABLE
,
это зарегистрировано в поле CREATE_OPTIONS
в
INFORMATION_SCHEMA.TABLES
.
Это поле может быть запрошена, чтобы идентифицировать зашифрованные таблицы.
mysql> SELECT TABLE_SCHEMA, TABLE_NAME, CREATE_OPTIONS FROM INFORMATION_SCHEMA.TABLES -> WHERE CREATE_OPTIONS LIKE '%ENCRYPTION="Y"%'; +--------------+------------+----------------+ | TABLE_SCHEMA | TABLE_NAME | CREATE_OPTIONS | +--------------+------------+----------------+ | test | t1 | ENCRYPTION="Y" | +--------------+------------+----------------+
Если сервер остановлен во время нормального функционирования, рекомендуется перезапустить сервер, используя те же самые настройки шифрования, которые были сконфигурированы ранее.
ALTER TABLE
tbl_name
ENCRYPTION
,
который является ALGORITHM=COPY
,
которая восстанавливает таблицу.COMPRESSION
и
ENCRYPTION
, сжатие выполнено
прежде, чем данные о табличном пространстве зашифрованы.keyring
пуст или отсутствует, первое выполнение
ALTER INSTANCE ROTATE INNODB MASTER
KEY
создает основной ключ шифрования.keyring_file
не удаляет
существующий файл keyring
.keyring
под каталогом, в котором лежат файлы с данными табличного пространства.
Местоположение keyring
определено опцией
keyring_file_data
.
keyring_file_data
во время выполнения или перезапуск сервера с
новым keyring_file_data
может сделать ранее зашифрованные таблицы недоступными,
приводя к потере данных.Advanced Encryption Standard (AES) является единственным
поддержанным алгоритмом шифрования. InnoDB
шифрование табличного
пространства использует режим блочного шифрования Electronic Codebook (ECB)
для ключевого шифрования табличного пространства и режим блочного шифрования
Cipher Block Chaining (CBC) для шифрования данных.
ENCRYPTION
делается через
ALGORITHM=COPY
. ALGORITHM=INPLACE
не поддержан.
Чтобы создать таблицу, используйте
CREATE TABLE
.
Вы не должны определить ENGINE=InnoDB
, если InnoDB
определен как механизм хранения по умолчанию. Вы могли бы все еще
использовать ENGINE=InnoDB
, если Вы планируете использовать
mysqldump
или репликацию, чтобы повторить CREATE
TABLE
на сервере, где механизм хранения по умолчанию
не InnoDB
.
-- Default storage engine = InnoDB. CREATE TABLE t1 (a INT, b CHAR (20), PRIMARY KEY (a)); -- Backward-compatible with older MySQL. CREATE TABLE t2 (a INT, b CHAR (20), PRIMARY KEY (a)) ENGINE=InnoDB;
Когда включена опция
innodb_file_per_table
, что является значением по умолчанию,
таблица неявно составлена в отдельном табличном пространстве file-per-table.
Наоборот, когда
innodb_file_per_table
выключена, таблица неявно составлена в
системном табличном пространстве. Вы можете использовать
CREATE TABLE ... TABLESPACE
,
чтобы явно создать таблицу в любом из трех типов табличного пространства.
Когда Вы создаете таблицу, MySQL создает каталог базы данных в соответствии с каталогом данных MySQL. Для таблицы, составленной в табличном пространстве file-per-table, создается файл .ibd. Таблица, создаваемая в системном табличном пространстве, составлена в существующем системном табличном пространстве файлов ibdata. Таблица, создаваемая в общем табличном пространстве, составлена в существующем общем табличном пространстве файла .ibd.
Внутренне InnoDB
добавляет запись
для каждой таблицы к словарю данных. Запись включает имя базы данных.
Например, если таблица t1
создается в базе данных
test
, запись будет 'test/t1'
.
Это означает, что Вы можете составить таблицу с тем же самым именем
(t1
) в иной базе данных, и имена таблиц не сталкиваются
внутри InnoDB
.
Используйте SHOW TABLE STATUS
:
mysql > SHOW TABLE STATUS FROM test LIKE 't%' \G; *************************** 1. row *************************** Name: t1 Engine: InnoDB Version: 10 Row_format: Compact Rows: 0 Avg_row_length: 0 Data_length: 16384 Max_data_length: 0 Index_length: 0 Data_free: 0 Auto_increment: NULL Create_time: 2015-03-16 15:13:31 Update_time: NULL Check_time: NULL Collation: latin1_swedish_ci Checksum: NULL Create_options: Comment: 1 row in set (0.00 sec)
В выводе состояния Вы видите, что свойство
Row format таблицы
t1
Compact
. Формат строки
Dynamic
или
Compressed
используют особенности InnoDB
, такие как табличное
сжатие и хранение вне страницы для длинных значений столбцов. Чтобы
использовать эти форматы строки, Вы можете включить
innodb_file_per_table
(по умолчанию):
SET GLOBAL innodb_file_per_table=1; CREATE TABLE t3 (a INT, b CHAR (20), PRIMARY KEY (a)) ROW_FORMAT=DYNAMIC; CREATE TABLE t4 (a INT, b CHAR (20), PRIMARY KEY (a)) ROW_FORMAT=COMPRESSED;
Или Вы можете использовать CREATE
TABLE ... TABLESPACE
, чтобы создать таблицу InnoDB
в общем табличном пространстве. Общие табличные пространства поддерживают
все форматы строки. Для получения дополнительной информации см.
раздел 16.7.9.
CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1 ROW_FORMAT=DYNAMIC;
CREATE TABLE ... TABLESPACE
может также использоваться, чтобы создать таблицу с форматом строки
Dynamic
в системном табличном пространстве, а также таблицы с
форматом строк Compact
или Redundant
.
CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE = innodb_system ROW_FORMAT=DYNAMIC;
Табличные свойства могут также быть запрошены, используя таблицы Information Schema:
SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME='test/t1' \G *************************** 1. row *************************** TABLE_ID: 45 NAME: test/t1 FLAG: 1 N_COLS: 5 SPACE: 35 ROW_FORMAT: Compact ZIP_PAGE_SIZE: 0 SPACE_TYPE: Single
Всегда настраивайте первичный ключ для каждой таблицы, определяя столбец или столбцы, которые:
Ссылаются самыми важными запросами.
Например, в таблице, содержащей информацию о людях, Вы не создали бы
первичный ключ на (firstname, lastname)
потому, что больше чем у
одного человека может быть то же самое имя, у некоторых людей есть пустые
фамилии, и иногда люди меняют свои имена. С очень многими ограничениями часто
нет очевидного набора столбцов, чтобы использовать в качестве первичного
ключа, таким образом, Вы создаете новый столбец с числовым ID, чтобы служить
всем или частью первичного ключа. Вы можете объявить столбец
auto-increment, чтобы
значения были заполнены автоматически, когда строки вставлены:
-- The value of ID can act like a pointer between related items in different tables. CREATE TABLE t5 (id INT AUTO_INCREMENT, b CHAR (20), PRIMARY KEY (id)); -- The primary key can consist of more than one column. Any autoinc column must come first. CREATE TABLE t6 (id INT AUTO_INCREMENT, a INT, b CHAR (20), PRIMARY KEY (id,a));
Хотя таблица работает правильно, не определяя первичный ключ, первичный
ключ связан со многими аспектами работы и является решающим аспектом проекта
для любой большой или часто используемой таблицы. Рекомендуется, чтобы Вы
всегда определили первичный ключ в
CREATE TABLE
.
Если Вы составляете таблицу, вводите данные и затем выполняете
ALTER TABLE
,
чтобы добавить первичный ключ позже, эта работа намного медленнее, чем
определение первичного ключа, составляя таблицу.
Физическая структура строки таблицы зависит от формата строки,
определенного, когда таблица составлена. Если формат строки не определен,
формат строки по умолчанию используется. Формат строки по умолчанию определен
опцией
innodb_default_row_format
, у которой есть значение
по умолчанию DYNAMIC
.
Формат REDUNDANT
доступен, чтобы сохранить совместимость с
более старыми версиями MySQL.
Чтобы проверить формат строки таблицы, Вы можете использовать
SHOW TABLE STATUS
:
mysql> SHOW TABLE STATUS IN test1\G *************************** 1. row *************************** Name: t1 Engine: InnoDB Version: 10 Row_format: Dynamic Rows: 0 Avg_row_length: 0 Data_length: 16384 Max_data_length: 0 Index_length: 16384 Data_free: 0 Auto_increment: 1 Create_time: 2016-09-14 16:29:38 Update_time: NULL Check_time: NULL Collation: latin1_swedish_ci Checksum: NULL Create_options: Comment:
Вы можете также проверить формат строки, запрашивая
INFORMATION_SCHEMA.INNODB_SYS_TABLES
.
mysql> SELECT NAME, ROW_FORMAT FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME='test1/t1'; +----------+------------+ | NAME | ROW_FORMAT | +----------+------------+ | test1/t1 | Dynamic | +----------+------------+
Строки в таблицах, использующие формат REDUNDANT
,
имеют следующие характеристики:
Каждый индекс содержит 6-байтовый заголовок. Заголовок используется, чтобы соединить последовательные записи, а также в блокировке на уровне строки.
InnoDB
хранит символьные столбцы фиксированной
длины, такие как CHAR(10)
,
в формате фиксированной длины. InnoDB
не усекает конечные
пробелы столбцов VARCHAR
.NULL
резервирует один или два байта в
каталоге записей. Помимо этого, SQL NULL
резервирует нулевые байты в части данных, если сохранен в столбце переменной
длины. В столбце фиксированной длины это резервирует фиксированную длину
столбца в части данных. Сохранение фиксированного пространства для
NULL
позволяет обновление столбца от значения NULL
до не-NULL
, не вызывая фрагментацию индексной страницы.Формат строки COMPACT
уменьшает место для хранения строки
приблизительно на 20% по сравнению с REDUNDANT
за счет увеличения использования центрального процессора для некоторых
операций. Если Ваша рабочая нагрузка типичная, которая ограничена частотами
успешных обращений кэша и дисковой скоростью, COMPACT
,
вероятно, будет быстрее. Если рабочая нагрузка редкий случай, который
ограничен скоростью центрального процессора, компактный формат мог
бы быть медленнее.
Строки в таблице имеют следующие характеристики:
Каждая индексная запись содержит 5-байтовый заголовок, которому может предшествовать заголовок переменной длины. Заголовок используется, чтобы соединить последовательные записи, а также в блокировке на уровне строки.
NULL
.
Если число столбцов в индексировании, которые могут быть
NULL
N
, битовый вектор занимает
CEILING(N
/8)
байт.
Например, если есть от 9 до 15 столбцов, которые могут быть
NULL
, битовый вектор занимает два байта. Столбцы, которые
являются NULL
, не занимают место, кроме бита в этом векторе.
Часть переменной длины заголовка также содержит длины столбцов переменной
длины. Каждая длина берет один или два байта, в зависимости от максимальной
длины столбца. Если все столбцы в индексировании NOT NULL
и
имеют фиксированную длину, у заголовка нет никакой части переменной длины.
NULL
поля переменной длины
заголовок содержит длину столбца в одном или двух байтах. Два байта
необходимы только, если часть столбца сохранена внешне в страницах
переполнения, или максимальная длина превышает 255 байтов, и фактическая
длина превышает 127 байтов. Для внешне сохраненного столбца 2-байтовая длина
указывает на длину внутренне сохраненной части плюс 20-байтовый указатель на
внешне сохраненную часть. Внутренняя часть составляет 768 байтов, таким
образом, длина 768+20. 20-байтовый указатель хранит истинную длину столбца.
NULL
.CHAR(10)
в
формате фиксированной длины.
InnoDB
не усекает конечные пробелы в столбцах
VARCHAR
.
utf8mb3
и utf8mb4
, InnoDB
использует для хранения
CHAR(N
)
в N
байт, обрезая конечные пробелы. Если байт длины
CHAR(N
)
столбца превышает N
байт, InnoDB
обрезает конечные пробелы к минимуму длины байта значения столбца.
Максимальная длина столбца
CHAR(N
)
максимальная длина символа *N
.
InnoDB
резервирует минимум
N
байт для
CHAR(
.
Сохранение минимального пространства N
)N
во многих случаях позволяет обновлениям столбца быть сделанными на месте, не
вызывая фрагментацию индексной страницы. В сравнении, для
ROW_FORMAT=REDUNDANT
, столбцы
CHAR(
занимают максимальную символьную длину байта *N
)N
.
CHAR
обработан как тип переменной длины, если длина значения
столбца больше чем или равна 768 байтам, что может произойти, если
максимальная длина байта набора символов больше 3, как с
utf8mb4
. Когда обработано как тип переменной длины,
значение столбца CHAR
может быть выбрано для хранения вне
страницы. Для получения дополнительной информации см.
раздел 16.10.
Дескриптор ROW_FORMAT=DYNAMIC
и
ROW_FORMAT=COMPRESSED
хранят
CHAR
таким же образом, как ROW_FORMAT=COMPACT
.
Форматы строк DYNAMIC
и COMPRESSED
это варианты формата COMPACT
.
Для информации об этих форматах строки см.
раздел 16.10.3.
Этот раздел описывает методы для перемещения или копирования некоторых
или всех таблиц InnoDB
на другой сервер.
Например, Вы могли бы переместить весь экземпляр MySQL на больший, более
быстрый сервер, Вы могли бы клонировать весь экземпляр MySQL к новому
ведомому серверу репликации, Вы могли бы скопировать отдельные таблицы на
другой сервер, чтобы развить и проверить приложение, или к серверу хранилища
данных, чтобы представить доклады.
Методы для перемещения или копирования таблиц включают:
В Windows InnoDB
всегда хранит имена базы данных и таблиц
внутренне в нижнем регистре. Чтобы переместить базы данных в двоичном формате
из Unix в Windows или наоборот, создайте все базы данных и таблицы, используя
строчные имена. Удобный способ достигнуть этого состоит в том, чтобы добавить
следующую строку к группе [mysqld]
файла
my.cnf
or my.ini
прежде, чем создать любые базы данных или таблицы:
[mysqld] lower_case_table_names=1
Мобильные табличные пространства используют
FLUSH TABLES ... FOR EXPORT
, чтобы
скопировать таблицы. Чтобы использовать эту функцию,
таблицы должны быть составлены с
innodb_file_per_table
в ON
, чтобы каждая таблица
имела свое собственное табличное пространство. Для информации об
использовании см. раздел 16.7.6.
MySQL Enterprise Backup позволяет Вам поддерживать рабочую базу данных
MySQL, включая таблицы InnoDB
и MyISAM
, с
минимальным разрушением к операциям, производя последовательный снимок базы
данных. Когда MySQL Enterprise Backup копирует таблицы InnoDB
,
чтение и запись таблиц InnoDB
и MyISAM
могут продолжиться. Во время копирования MyISAM
и других
не-InnoDB таблиц, чтения (но не записи) к тем таблицам разрешены.
Кроме того, MySQL Enterprise Backup может создать сжатые резервные файлы и
поддержать подмножества таблиц InnoDB
.
В соединении с двоичным журналом Вы можете выполнить восстановление момента
времени. MySQL Enterprise Backup включен как часть MySQL Enterprise.
Подробности в разделе 27.2 .
Вы можете переместить база данных, просто копируя все соответствующие файлы, см. раздел 16.17.
Аналогично файлам MyISAM
, InnoDB
данные и файлы системного журнала совместимы на всех платформах, имеющих тот
же самый числовой формат с плавающей запятой. Если форматы с плавающей
запятой отличаются, но Вы не использовали
DOUBLE
в Ваших
таблицах, процедура та же самая: просто скопируйте соответствующие файлы.
Когда Вы перемещаете или копируете файл .ibd
, имя каталога
базы данных должно быть тем же самым на целевых системах и источнике.
Табличное определение, сохраненное в совместно используемом табличном
пространстве включает имя базы данных. Операционные ID
и порядковые номера журнала, сохраненные в файлах табличного пространства,
также отличаются между базами данных.
Перемещать файл .ibd
и связанную таблицу от одной базы данных
к другой можно с помощью RENAME TABLE
:
RENAME TABLEdb1.tbl_name
TOdb2.tbl_name
;
Если у Вас есть резервная копия файла .ibd
,
Вы можете восстановить ее к исходной установке MySQL следующим образом:
Таблица, должно быть, не была удалена или усечена, так
как Вы скопировали .ibd
, табличный ID
сохранен в табличном пространстве.
ALTER TABLE
удалите текущий файл .ibd
:
ALTER TABLE tbl_name
DISCARD TABLESPACE;
.ibd
к надлежащему каталогу базы данных.ALTER TABLE
,
чтобы сказать InnoDB
использовать новый файл
.ibd
для таблицы:
ALTER TABLE tbl_name
IMPORT TABLESPACE;
ALTER TABLE ... IMPORT TABLESPACE
не проводит в жизнь ограничения внешнего ключа
на импортированные данные.
В этом контексте копия файла .ibd
удовлетворяет следующим требованиям:
Нет никаких нейтральных модификаций
транзакциями в файле .ibd
.
.ibd
..ibd
из буферного пула.Вы можете сделать чистое резервное копирование .ibd
:
Остановите всю деятельность mysqld и передайте все транзакции.
SHOW ENGINE INNODB STATUS
покажет, что нет никаких активных транзакций в базе данных, и
состояние основного потока InnoDB
Waiting for server
activity
. Тогда Вы можете сделать копию файла .ibd
.
Другой метод для того, чтобы сделать чистую копию .ibd
:
Используйте MySQL Enterprise Backup.
.ibd
в резервном копировании.Вы можете использовать mysqldump, чтобы вывести Ваши таблицы в дамп на одной машине и затем импортировать файлы дампа на другой машине. Используя этот метод, не имеет значения, отличаются ли форматы или содержат ли Ваши таблицы данные с плавающей запятой.
Один способ увеличить скорость этого метода состоит в том, чтобы выключить режим autocommit, импортируя данные, предполагая, что у табличного пространства есть достаточно пространства для большого сегмента отмены, который производят транзакции импорта. Сделайте передачу только после импортирования целой таблицы или сегмента таблицы.
Если Вы имеете таблицы
MyISAM
, которые Вы хотите преобразовать в
InnoDB
, рассмотрите следующие
подсказки прежде, чем сделать преобразование.
Разделенные таблицы MyISAM
, составленные в предыдущих версиях
MySQL, несовместимы с MySQL 8.0. Такие таблицы должны быть подготовлены до
обновления, удаляя разделение, или преобразовывая их в InnoDB
.
См. раздел
20.6.2.
Поскольку Вы переходите от таблиц MyISAM
, понизьте значение
key_buffer_size
,
чтобы освободить память, больше не нужную для того, чтобы кэшировать
результаты. Увеличьте значение
innodb_buffer_pool_size
, которое выполняет подобную роль выделения
кэш-памяти для InnoDB
.
Буферный пул кэширует табличные данные и индексы, таким образом, это
действительно удваивает ускорение поисков для запросов и хранения результатов
запроса в памяти для повторного использования.
Для руководства относительно буферной конфигурации размера пула см.
раздел 9.12.3.1.
На занятом сервере выполните тесты с выключенным кэшем запроса. Буферный пул обеспечивает подобную выгоду, таким образом, кэш запроса мог бы излишне связывать память.
Поскольку таблицы MyISAM
не поддерживают
транзакции,
Вы, возможно, не обратили много внимания на настройку
autocommit
и команды COMMIT
и
ROLLBACK
.
Эти ключевые слова важны, чтобы позволить многим сеансам читать и писать
таблицы InnoDB
одновременно, обеспечивая
существенную выгоду масштабируемости.
В то время как транзакция открыта, система сохраняет снимок данных в начале транзакции, что может вызвать существенные накладные расходы, если система вставляет, обновляет и удаляет миллионы строк, в то время как беспризорная транзакция продолжает работать. Таким образом, заботьтесь о том, чтобы избежать транзакций, которые работают слишком долго:
Если Вы используете
mysql для интерактивных экспериментов, всегда командуйте
COMMIT
(чтобы завершить изменения)
или ROLLBACK
(чтобы отменить изменения) когда закончите.
Закройте интерактивные сеансы вместо того, чтобы оставить их открытыми в
течение длительных периодов, чтобы избежать долго открытых транзакций.
ROLLBACK
или COMMIT
.ROLLBACK
относительно дорогая работа, потому что операции
INSERT
,
UPDATE
и
DELETE
записаны в таблицы InnoDB
до
COMMIT
,
с ожиданием, что большинство изменений будет передано успешно и обратные
перемотки будут редки. Экспериментируя с большими объемами данных, избегите
производить изменения в больших количествах строк и затем откатывать те
изменения до прежнего уровня.INSERT
, периодически выполняйте
COMMIT
, чтобы
избежать транзакций, которые длятся в течение многих часов.
В типичных операциях загрузки для складирования данных, если что-то идет не
так, как надо, Вы усекаете таблицу (используя
TRUNCATE TABLE
)
и запустите с начала вместо того, чтобы делать
ROLLBACK
.Предыдущие подсказки сохраняют место в памяти и дисковое пространство,
которое может быть потрачено впустую во время слишком длинных транзакций.
Когда транзакции короче, чем они должны быть, проблемой будет чрезмерный
ввод/вывод. С каждым COMMIT
MySQL
удостоверяется, что каждое изменение безопасно зарегистрировано на диске,
что вовлекает некоторый ввод/вывод.
Для большинства операций на таблицах InnoDB
Вы должны использовать установку
autocommit=0
.
С точки зрения эффективности это избегает ненужного ввода/вывода, когда Вы
выпускаете большие количества последовательных
INSERT
,
UPDATE
или
DELETE
.
С точки зрения безопасности это позволяет Вам использовать
ROLLBACK
, чтобы возвратить
потерянные или искаженные данные, если Вы делаете ошибку в командах
mysql
или в обработчике исключения в Вашем приложении.
autocommit=1
является подходящим для таблицы, выполняя последовательность
запросов для того, чтобы произвести отчеты или проанализировать статистику.
В этой ситуации нет никакого лишнего ввода/вывода, связанного с
COMMIT
или
ROLLBACK
, а InnoDB
может автоматически
оптимизировать рабочую нагрузку только для чтения.COMMIT
в конце.
Например, если Вы вставляете связанные сведения в несколько таблиц, сделайте
одиночный COMMIT
после произведения
всех изменений. Или если Вы выполняете много последовательных
INSERT
, сделайте
COMMIT
после того, как все данные
загружены, если Вы делаете миллионы
INSERT
,
возможно разделить огромную транзакцию с помощью
COMMIT
каждые десять тысяч или сто тысяч отчетов, таким образом, транзакция не
становится слишком большой.SELECT
открывает транзакцию, таким образом, после выполнения некоторого отчета или
отладки запросов в интерактивном
mysql, выполните COMMIT
или закройте mysql
.Вы могли бы видеть предупреждающие сообщения о
тупиках в журнале ошибок MySQL или выводе
SHOW ENGINE INNODB STATUS
.
Несмотря на страшно звучащее имя,
тупик не серьезная проблема для
InnoDB
и часто не требуют никакого корректирующего действия.
Когда две транзакции начинают изменять многие таблицы, получая доступ к
таблицам в различном порядке, они могут достигнуть состояния, где каждая
транзакция ждет другую, и ни одна не может продолжить. Когда
определение тупиков
включено (значение по умолчанию), MySQL немедленно обнаруживает это условие,
и отменяет меньшую, позволяя другой продолжиться.
Если обнаружение тупика отключено, используя
innodb_deadlock_detect
, InnoDB
полагается на
innodb_lock_wait_timeout
, чтобы откатить транзакции до прежнего
уровня в случае тупика.
Так или иначе, Ваши приложения нуждаются в логике обработки ошибок, чтобы перезапустить транзакцию, которая насильственно отменена из-за тупика. Когда Вы переиздаете те же самые запросы SQL как прежде, оригинальная проблема синхронизации больше не применяется: или другая транзакция уже закончилась, и Ваша может продолжиться, или другая транзакция все еще происходит, и Ваша транзакция ждет, пока это не заканчивается.
Если предупреждения тупика постоянно происходят, Вы могли бы рассмотреть
код программы, чтобы переупорядочить операции SQL последовательным способом,
или сократить транзакции. Вы можете проверить с включенной опцией
innodb_print_all_deadlocks
, чтобы видеть все предупреждения тупика
в журнале ошибок MySQL, а не только последнее предупреждение в
SHOW ENGINE INNODB STATUS
.
Подробности в разделе 16.5.5.
Получить лучшую работу от InnoDB
Вы можете, скорректировав
много параметров, связанных с расположением хранения.
Когда Вы преобразовываете таблицы MyISAM
, которые являются
большими, часто используемыми и содержащими жизненные данные, исследуйте и
рассмотрите опции
innodb_file_per_table
и
innodb_page_size
, а также параметры
ROW_FORMAT
и
KEY_BLOCK_SIZE
в
CREATE TABLE
.
Во время Ваших начальных экспериментов самая важная установка
innodb_file_per_table
. Когда эта установка включена, что
является значением по умолчанию, новые таблицы неявно составлены в табличных
пространствах file-per-table.
В отличие от системного табличного пространства, табличные пространства
file-per-table позволяют дисковому пространству использоваться операционной
системой, когда таблица является усеченной или удаленной. Табличные
пространства File-per-table также поддерживают строки форматов
DYNAMIC и
COMPRESSED
и связанные особенности, такие как табличное сжатие, хранение вне страницы
для длинных столбцов переменной длины и большой префикс индекса.
Для получения дополнительной информации см.
раздел 16.7.4.
Вы можете также сохранить таблицы в совместно используемом общем табличном пространстве, которое поддерживает многие таблицы и все форматы строки. Для получения дополнительной информации см. раздел 16.7.9.
Преобразовать не-InnoDB
таблицу, чтобы использовать
InnoDB
можно через
ALTER TABLE
:
ALTER TABLE table_name
ENGINE=InnoDB;
Вы могли бы сделать таблицу InnoDB
, которая является клоном
таблицы MyISAM, вместо того, чтобы делать
ALTER TABLE
,
чтобы проверить старую и новую таблицу бок о бок перед переключением.
Создайте пустую таблицу с идентичными определениями столбца и индексов.
Примените show create table
,
чтобы посмотреть полный запрос
table_name
\GCREATE TABLE
.
Смените ENGINE
на ENGINE=INNODB
.
Передать большой объем данных в пустую таблицу, составленную как показано
в предыдущем разделе, можно, вставив строки с помощью INSERT INTO
.innodb_table
SELECT * FROM
myisam_table
ORDER BY
primary_key_columns
Вы можете также создать индексирование для таблицы после вставки данных. Исторически, создание новых вторичных индексов было медленной работой для InnoDB, но теперь Вы можете создать индексирование после того, как данные загружены, относительно легко и быстро.
Если Вы имеете ограничения UNIQUE
на вторичные ключи, Вы
можете ускорить табличный импорт, выключая проверки уникальности временно во
время работы импорта:
SET unique_checks=0;
... import operation ...
SET unique_checks=1;
Для больших таблиц это сохраняет дисковый ввод/вывод потому, что
InnoDB
может использовать
буфер изменения, чтобы
записать вторичный индекс как пакет.
Будьте уверены, что данные не содержат дубликаты ключа.
unique_checks
разрешает, но не требует, чтобы механизмы хранения
проигнорировали дубликаты ключа.
Чтобы получить лучший контроль над процессом вставки, Вы могли бы вставить большие таблицы по частям:
INSERT INTO newtable SELECT * FROM oldtable WHERE yourkey >something
AND yourkey <=somethingelse
;
После того, как все записи были вставлены, Вы можете переименовать таблицы.
Во время преобразования больших таблиц, увеличьте размер буферного пула, чтобы уменьшить дисковый ввод/вывод, максимум до 80% физической памяти. Вы можете также увеличить размер файлов системного журнала.
Если Вы намереваетесь сделать несколько временных копий своих данных в
таблицах во время конверсионного процесса, рекомендуется, чтобы Вы составили
таблицы в табличных пространствах file-per-table, чтобы Вы могли восстановить
дисковое пространство, когда Вы удаляете таблицы. Как упомянуто ранее, когда
innodb_file_per_table
включена (значение по умолчанию), созданные таблицы
неявно составлены в табличных пространствах file-per-table.
Преобразовываете ли Вы MyISAM
непосредственно или создаете
клонированную таблицу InnoDB
, удостоверьтесь, что у Вас есть
достаточное дисковое пространство, чтобы хранить старые и новые таблицы во
время процесса. Таблицы InnoDB требуют большего количества
дискового пространства, чем MyISAM
. Если
ALTER TABLE
исчерпывает пространство, она запускает откат, а это может занять часы.
Для вставок InnoDB
использует буфер вставки, чтобы слить
вторичные индексные записи в пакетах. Это сохраняет много дискового
ввода/вывода. Для отмены не используется такой механизм, и отмена может
занять в 30 раз дольше, чем вставка.
В случае безудержной отмены, если у Вас нет ценных данных в Вашей базе данных, может быть желательно уничтожить процесс базы данных, а не ждать миллионов дисковых операций ввода/вывода. Для полной процедуры см. раздел 16.20.2.
PRIMARY KEY
это критический фактор, затрагивающий исполнение
запросов MySQL и использование пространства для таблиц и индексов.
У каждой строки в таблице должно быть значение первичного ключа, но ни у
каких двух строк не может быть того же самого значения первичного ключа.
Вот направляющие идеи для первичного ключа, сопровождаемые более подробными объяснениями.
Объявите PRIMARY KEY
для каждой таблицы. Как правило,
это самый важный столбец, к которому Вы обращаетесь в WHERE
,
ища единственную строку.
PRIMARY KEY
в
CREATE TABLE
вместо того, чтобы добавить это позже через
ALTER TABLE
.Рассмотрите добавление primary key к любой таблице, у которой его еще нет. Используйте самый маленький практический числовой тип, основанный на максимальном спроектированном размере таблицы. Это может сделать каждую строку немного более компактной, что может привести к существенной экономии места для больших таблиц. Сбережения пространства умножены, если таблица имеет вторичный индекс, потому что значение первичного ключа повторено в каждом вторичном индексе. В дополнение к сокращению размера данных на диске маленький первичный ключ также позволяет большее количество совпадения данных в буферном пуле, ускоряя все виды операций и улучшая параллелизм.
Если у таблицы уже есть первичный ключ на некотором более длинном столбце,
таком как VARCHAR
, рассмотрите добавление нового столбца
unsigned AUTO_INCREMENT
и переключение первичного ключа на
него, даже если на этот столбец не ссылаются в запросах. Это изменение
проекта может произвести существенную экономию места во вторичном индексе.
Вы можете определять прежние столбцы первичного ключа как
UNIQUE NOT NULL
, чтобы провести в жизнь те же самые ограничения,
как PRIMARY KEY
, то есть, чтобы предотвратить двойные или
нулевые значения в этих столбцах.
Если Вы распространяете соответствующую информацию через много таблиц, как правило, каждая таблица использует тот же самый столбец для своего первичного ключа. Например, у базы данных персонала могло бы быть несколько таблиц, каждая с первичным ключом номера служащего. У базы данных продаж могли бы быть некоторые таблицы с первичным ключом номера заказчика и другие таблицы с первичным ключом порядкового номера. Поскольку поиски, используя первичный ключ очень быстры, Вы можете создать эффективные запросы для таких таблиц.
Если Вы не используете PRIMARY KEY
, MySQL создает невидимый.
Это 6-байтовое значение, которое могло бы быть более длинным, чем надо,
таким образом тратя впустую место.
Поскольку это скрыто, Вы не можете обратиться к этому в запросах.
Дополнительная надежность и особенности масштабируемости
InnoDB
действительно потребуют большего количества дискового
места, чем эквивалентные таблицы MyISAM
.
Вы могли бы изменить столбец и определения индекса для лучшего
использования пространства, уменьшенного ввода/вывода и потребления памяти,
обрабатывая наборы результатов, и лучших планов оптимизации запроса, делающих
эффективное использование поисков по индексу.
Если Вы действительно настраиваете числовой столбец ID
для первичного ключа, используйте это значение, чтобы перекрестно сослаться
со связанными значениями в любых других таблицах, особенно для запросов
join. Например, вместо того, чтобы
принять название страны как входное значение и сделать запросы, ищущие то же
самое имя, сделайте один поиск, чтобы определить ID страны, затем сделайте
другие запросы (или единственный запрос), чтобы искать релевантную информацию
в нескольких таблицах. Вместо того, чтобы хранить клиента или номер изделия
по каталогу как строку цифр, потенциально израсходовав несколько байтов,
преобразуйте это в числовой ID для хранения и запросов. 4 байтный столбец
INT
может индексировать более чем 4 миллиарда элементов.
Для диапазонов различных типов целого числа см.
раздел 12.2.1.
Файлы InnoDB
требуют большей заботы, чем MyISAM
:
Вы не должны удалить файлы ibdata, которые представляют системное табличное пространство.
FLUSH TABLES ... FOR EXPORT
и копирования
table_name
.cfg
файла наряду с
table_name
.ibd
.InnoDB
обеспечивает конфигурируемый механизм блокировки,
который может значительно улучшить масштабируемость и исполнение запросов
SQL, которые добавляют строки к таблицам со столбцами
AUTO_INCREMENT
. Чтобы использовать механизм
AUTO_INCREMENT
с таблицей InnoDB
, столбец
AUTO_INCREMENT
должен быть определен как часть индексирования
таким образом, что возможно выполнить эквивалент индексированного поиска
SELECT MAX(
на таблице, чтобы получить максимальное значение столбца. Как правило, это
достигнуто, делая столбец, который индексирует первый
столбец некоторой таблицы.ai_col
)
Этот раздел описывает поведение режимов блокировки
AUTO_INCREMENT
, значения использования для различных
настроек режима блокировки AUTO_INCREMENT
и как
InnoDB
инициализирует счетчик AUTO_INCREMENT
.
Режимы блокировки AUTO_INCREMENT
Этот раздел описывает поведение режимов блокировки
AUTO_INCREMENT
, и как каждый режим блокировки затрагивает
репликацию. Режимы блокировки сконфигурированы при запуске, используя
innodb_autoinc_lock_mode
.
Следующие термины использованы в описании
innodb_autoinc_lock_mode
:
INSERT
-подобные запросы
Все запросы, которые производят новые строки в таблице, включая
INSERT
,
INSERT ... SELECT
,
REPLACE
,
REPLACE ... SELECT
и
LOAD DATA
. Включает
простые вставки, bulk-вставки
и смешанные вставки.
Запросы, для которых число строк, которые будут вставлены, может быть
определено заранее (когда запрос первоначально обработано). Это включает
однострочные и многострочные INSERT
и REPLACE
, у которых нет
вложенного подзапроса, но не
INSERT
... ON DUPLICATE KEY UPDATE
.
Запросы, которыми число строк, которые будут вставлены (и число
необходимых значений auto-increment) не известно заранее. Это включает
INSERT ... SELECT
,
REPLACE ... SELECT
и
LOAD DATA
,
но не простой INSERT
. InnoDB
назначает новые значения для столбца AUTO_INCREMENT
по одному по мере того, как каждая строка обработана.
Это простые вставки, которые определяют значение
auto-increment для некоторых (но не всех) новых строк. Пример следует, где
c1
столбец AUTO_INCREMENT
таблицы t1
:
INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d');
Другой тип смешанных вставок:
INSERT ... ON DUPLICATE KEY
UPDATE
, который в худшем случае является в действительности
INSERT
сопровождаемый
UPDATE
, где выделенное значение для
столбца AUTO_INCREMENT
может или не может использоваться во время фазы обновления.
Есть три возможных настройки для
innodb_autoinc_lock_mode
. Это 0, 1 или 2, соответственно для
режимов traditional, consecutive
или interleaved.
innodb_autoinc_lock_mode = 0
(режим traditional).
Традиционный режим блокировки обеспечивает то же самое поведение, которое
существовало перед тем, как параметр конфигурации
innodb_autoinc_lock_mode
был введен в MySQL 5.1.
Традиционная возможность режима блокировки предоставлена для обратной
совместимости, исполнительного тестирования и обхода проблем со
смешанным режимом вставки из-за возможных различий в семантике.
В этом режиме блокировки все INSERT-подобные
запросы, получают специальную блокировку AUTO-INC
на уровне
таблицы для вставок в таблицы со столбцом AUTO_INCREMENT
.
Эта блокировка остается до конца запроса (не до конца транзакции) и
гарантирует, что значения auto-increment назначены в предсказуемом и
повторимом порядке на данную последовательность запросов
INSERT
, при этом
гарантируя, что значения автоинкремента, назначенные любым
данным запросом, последовательны.
В случае основанной на запросе репликации
это означает, что, когда запрос SQL копируется на ведомом сервере, те же
самые значения используются для столбца auto-increment
на главном сервере. Результат выполнения многократных
INSERT
детерминирован,
и ведомое устройство воспроизводит те же самые данные, как на ведущем
устройстве. Если значения auto-increment, произведенные многократным
INSERT
,
были чередованы, результатом будут два параллельных запроса
INSERT
, которые
недетерминированы, и не могут быть достоверно размножены к ведомому серверу,
используя основанную на запросе репликацию.
Чтобы ясно понять это, рассмотрите пример, который использует эту таблицу:
CREATE TABLE t1 (c1 INT(11) NOT NULL AUTO_INCREMENT, c2 VARCHAR(10) DEFAULT NULL, PRIMARY KEY (c1)) ENGINE=InnoDB;
Предположите, что есть две операции, каждая вставляет строки в таблицу со
столбцом AUTO_INCREMENT
. Одна транзакция использует
INSERT ... SELECT
,
который вставляет 1000 строк, другая использует простой
INSERT
, который
вставляет одну строку:
Tx1: INSERT INTO t1 (c2) SELECT 1000 rows from another table ... Tx2: INSERT INTO t1 (c2) VALUES ('xxx');
InnoDB
не может сказать заранее, сколько строк будет получено
от SELECT
в запросе
INSERT
в Tx1, и это назначает
значения auto-increment по одному, в то время как запрос продолжается. С
блокировкой на уровне таблицы, проводимой до конца запроса, только один
INSERT
, относящийся к таблице
t1
, можно выполнить за один раз, и генерация чисел
auto-increment различными запросами не чередована. Значение, произведенное
для Tx1 запросом INSERT ... SELECT
, будет последовательно, и (единственное) значение, используемое
INSERT
в Tx2,
будет меньше или больше, чем все используемые для Tx1, в зависимости от того,
который запрос выполняется сначала.
Пока запросы SQL выполняют в том же самом порядке, когда повторяют из
двоичного журнала (используя основанную на запросе репликацию
или в скриптах восстановления), результатами будет то же самое, как было,
когда Tx1 и Tx2 сначала работали. Таким образом, блокировки на уровне
таблицы, проводимые до конца запроса, делают запросы
INSERT
, использующие
auto-increment, безопасными для использования с основанной на запросе
репликацией. Однако, те блокировки на уровне таблицы ограничивают параллелизм
и масштабируемость, когда многократные транзакции выполняют вставки
в то же самое время.
В предыдущем примере, если не было никакой блокировки на уровне таблицы,
значения столбца auto-increment, используемого для
INSERT
в Tx2,
зависит от того, когда запрос выполняется. Если
INSERT
в Tx2
выполняется в то время, как
INSERT
в Tx1
работает (а не прежде, чем он запустится или после того, как он завершается),
определенные значения auto-increment, назначенные двумя
INSERT
недетерминированы, и могут измениться.
В режиме
последовательной блокировки InnoDB
может избегать использования на уровне таблицы блокировок
AUTO-INC
для простых вставок, где
число строк известно заранее, и все еще сохраняет детерминированное
выполнение и безопасность для основанной на запросе репликации.
Если Вы не используете двоичный журнал, чтобы переиграть запросы SQL как
часть восстановления или репликации, может использоваться режим блокировки
interleaved
, чтобы устранить все использование на уровне таблицы блокировки
AUTO-INC
для еще большего параллелизма и работы, за счет
разрешения промежутков в числах auto-increment, назначенных запросом и
потенциально назначением чисел, одновременно выполняемых запросов.
innodb_autoinc_lock_mode = 1
(режим блокировки consecutive)
Это режим блокировки значения по умолчанию. В этом режиме
bulk-вставки используют специальную блокировку
AUTO-INC
на уровне таблицы и держат это до конца запроса. Это
относится ко всем запросам INSERT ...
SELECT
, REPLACE ... SELECT
и LOAD DATA
.
Только одно запрос, держащий AUTO-INC
,
может выполниться за один раз.
Простые вставки (число строк, которые будут
вставлены, известно заранее) избегают на уровне таблицы блокировки
AUTO-INC
, получая необходимое число auto-increment
под управлением mutex (легкая блокировка), который проводится только во время
процесса распределения, а не до тех пор, когда запрос завершится.
На уровне таблицы блокировка AUTO-INC
не применяется, если
AUTO-INC
проводится другой транзакцией. Если другая транзакция
держит AUTO-INC
простая вставка
ждет AUTO-INC
, как будто это была
bulk-вставка.
Этот режим блокировки гарантирует, что в запросе
INSERT
, где число строк не известно
заранее (и где числа auto-increment назначены в ходе продвижения запроса),
все значения auto-increment, назначенные любым
INSERT
-подобным
запросом, последовательны, и операции безопасны для основанной
на запросе репликации.
Проще говоря, этот режим блокировки значительно улучшает масштабируемость, будучи безопасным для использования с основанной на запросе репликацией. Далее, как с режимом блокировки traditional, числа auto-increment, назначенные любым данным запросом, последовательны. Нет никакого изменения в семантике по сравнению с режимом traditional ни для какого запроса, с одним важным исключением (ну а как же без него!).
Исключение для смешанного режима вставки,
где пользователь обеспечивает явные значения столбца
AUTO_INCREMENT
для некоторых, но не всех, строк в многострочной
простой вставке. Для таких вставок
InnoDB
выделяет больше значений auto-increment,
чем число строк, которые будут вставлены. Однако, все значения, автоматически
назначенные, последовательно произведены (и таким образом выше) значения
auto-increment, произведенного последний раз выполненным предыдущим запросом.
innodb_autoinc_lock_mode = 2
(режим блокировки interleaved)
В этом режиме блокировки никакие
INSERT
-подобные
запросы не используют на уровне таблицы блокировку
AUTO-INC
, и многократные запросы могут выполняться в то же
самое время. Это является самым быстрым и масштабируемым режимом блокировки,
но не безопасно, используя основанную на запросе
репликацию или скрипты восстановления, когда запросы SQL переигрываются
из двоичного журнала.
В этом режиме блокировки значения auto-increment точно
будут уникальны и монотонно увеличивающимися через все одновременно
выполняющиеся
INSERT
-подобные запросы.
Однако, потому что многократные запросы могут производить числа в то же самое
время (то есть, распределение чисел interleaved),
значения, произведенные для строк, вставленных любым данным запросом,
возможно, не последовательны.
Если единственное выполнение запросов простая вставка , где число строк, которые будут вставлены, известно заранее, не будет никаких промежутков в числах, произведенных для единственного запроса, за исключением смешанного режима вставок. Однако, когда bulk-вставки выполнены, могут быть промежутки в значениях, назначенных любым данным запросом.
Применение auto-increment с репликацией.
Если Вы используете основанную на запросе репликацию, установите
innodb_autoinc_lock_mode
в 0 или 1 и используйте то же самое
значение на ведущем устройстве и его ведомых устройствах. Значения
не будут теми же самыми на ведомых устройствах, как на ведущем устройстве,
если Вы используете
innodb_autoinc_lock_mode
= 2
(interleaved) или конфигурации, где ведущее
устройство и ведомые устройства не используют тот же самый режим блокировки.
Если Вы используете репликацию, основанную на строке или смешанного формата, все режимы блокировки безопасны, так как основанная на строке репликация не чувствителен к порядку выполнения запросов SQL (и смешанный формат использует основанную на строке репликацию для любых запросов, которые опасны для основанной на запросе репликации).
Во всех режимах блокировки (0, 1 и 2), если транзакция, которая произвела
значения, откатывается, те значения потеряны.
Как только значение произведено для столбца, оно не может быть отменено до
прежнего уровня, действительно ли выполнен
INSERT
-подобный
запрос или отменен. Такие потерянные значения снова не использованы.
Таким образом, могут быть промежутки в значениях, сохраненных в
столбце AUTO_INCREMENT
таблицы.
AUTO_INCREMENT
.
Во всех режимах блокировки (0, 1 и 2), если пользователь определяет
NULL или 0 для столбца AUTO_INCREMENT
в
INSERT
, InnoDB
обрабатывает строку, как будто значение не было определено и производит новое
значение для нее.
AUTO_INCREMENT
.
Во всех режимах блокировки (0, 1 и 2) не определено поведение механизма
auto-increment, если Вы назначаете отрицательную величину
столбцу AUTO_INCREMENT
.
AUTO_INCREMENT
становится больше, чем
максимальное целое число для указанного типа целого числа.
Во всех режимах блокировки (0, 1 и 2) не определено поведение механизма auto-increment, если значение становится больше, чем максимальное целое число, которое может быть сохранено в указанном типе целого числа.
С опцией
innodb_autoinc_lock_mode
в значении 0 (traditional
) или 1 (consecutive) значения
auto-increment, произведенные любым данным запросом, последовательны без
промежутков, потому что на уровне таблицы блокировка AUTO-INC
проводится до конца запроса, и только один такой запрос может выполниться
за один раз.
С опцией
innodb_autoinc_lock_mode
в значении 2 (interleaved
), могут быть промежутки в значениях, произведенных
bulk-вставками, но только если там одновременно
выполняются
INSERT
-подобные запросы.
Для режимов блокировки 1 или 2 промежутки могут произойти между последовательными запросами, потому что для bulk-вставок точное число значений auto-increment, требуемых каждым запросм, возможно, не известно заранее, и переоценка возможна.
Полагайте, что смешанный режим,
определяет значение auto-increment для некоторых (но не всех) получающихся
строк. Такой запрос ведет себя по-другому в режимах блокировки 0, 1 и 2.
Например, предположим, что столбец c1
AUTO_INCREMENT
в таблице t1
,
и что новый автоматически произведенный порядковый номер 100.
mysql> CREATE TABLE t1 ( -> c1 INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, -> c2 CHAR(1)) ENGINE = INNODB; mysql> INSERT INTO t1 VALUES(1,'a'),(101,'b'),(5,'c'),(102,'d');
Теперь считайте следующее смешанным режимом вставки:
mysql> INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d');
Если
innodb_autoinc_lock_mode
= 0 (traditional
), четыре новых строки:
mysql> SELECT c1, c2 FROM t1 ORDER BY c2; +-----+----+ | c1 | c2 | +-----+----+ | 1 | a | | 101 | b | | 5 | c | | 102 | d | +-----+----+
Следующее доступное значение 103, потому что значения автоинкремента
выделены по одному, а не все в начале выполнения запроса.
Этот результат верен при выполнении одновременно
INSERT
-подобных
запросов (любого типа).
Если
innodb_autoinc_lock_mode
= 1 (consecutive
), четыре новых строки также:
mysql> SELECT c1, c2 FROM t1 ORDER BY c2; +-----+----+ | c1 | c2 | +-----+----+ | 1 | a | | 101 | b | | 5 | c | | 102 | d | +-----+----+
Однако, в этом случае, следующее доступное значение 105, не 103, потому
что четыре значения выделены в то время, когда запрос обработан, но только
два используются. Этот результат верен при выполнении одновременно
INSERT
-подобных
запросов (любого типа).
Если
innodb_autoinc_lock_mode
= 2 (interleaved
), четыре новых строки:
mysql> SELECT c1, c2 FROM t1 ORDER BY c2; +----+----+ | c1 | c2 | +----+----+ | 1 | a | |x
| b | | 5 | c | |y
| d | +----+----+
Значения x
и y
уникальны и больше, чем любые ранее произведенные строки. Однако,
определенные значения x
и y
зависят от числа значений auto-increment, произведенных
одновременно выполняемыми запросами.
Наконец, рассмотрите следующий запрос, сделанный, когда последний раз произведенный порядковый номер был значением 4:
mysql> INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d');
При любом значении
innodb_autoinc_lock_mode
этот запрос производит ошибку
дублирования ключа 23000 (Can't write; duplicate key in table
)
потому, что 5 выделено для строки (NULL, 'b')
и вставка
строки (5, 'c')
терпит неудачу.
AUTO_INCREMENT
в середине
последовательности INSERT
.
В MySQL 5.7 и ранее изменение значения столбца AUTO_INCREMENT
в середине последовательности INSERT
могло привести к ошибке Duplicate entry.
Например, если Вы запускали UPDATE
,
которая изменила столбец AUTO_INCREMENT
к значению, большему,
чем текущий максимум, последующий
INSERT
, который не определял
неиспользованное значение auto-increment, мог столкнуться с ошибкой
Duplicate entry. В MySQL 8.0 и позже, если Вы
изменяете столбец AUTO_INCREMENT
к значению, больше, чем текущее максимальное значение auto-increment,
новое значение сохранено, и последующие
INSERT
выделяют значения, начиная с нового, большего значения.
Это поведение продемонстрировано в следующем примере.
mysql> CREATE TABLE t1 ( -> c1 INT NOT NULL AUTO_INCREMENT, -> PRIMARY KEY (c1)) ENGINE = InnoDB; mysql> INSERT INTO t1 VALUES(0), (0), (3); mysql> SELECT c1 FROM t1; +----+ | c1 | +----+ | 1 | | 2 | | 3 | +----+ mysql> UPDATE t1 SET c1 = 4 WHERE c1 = 1; mysql> SELECT c1 FROM t1; +----+ | c1 | +----+ | 2 | | 3 | | 4 | +----+ mysql> INSERT INTO t1 VALUES(0); mysql> SELECT c1 FROM t1; +----+ | c1 | +----+ | 2 | | 3 | | 4 | | 5 | +----+
Этот раздел описывает как InnoDB
инициализирует
счетчики AUTO_INCREMENT
.
Если Вы определяете столбец AUTO_INCREMENT
для
таблица, табличный объект в памяти содержит специальный счетчик, названный
счетчиком auto-increment, который используется, назначая новые
значения для столбца.
В MySQL 5.7 и ранее счетчик автоинкремента сохранен только в основной
памяти, не на диске. Инициализируя счетчик автоинкремента после
перезапуска сервера, InnoDB
выполнил бы эквивалент следующего
запроса о первой вставке в таблицу, содержащую столбец
AUTO_INCREMENT
.
SELECT MAX(ai_col) FROM table_name
FOR UPDATE;
В MySQL 8.0 это не так. Текущее максимальное значение счетчика написано в журнал redo каждый раз, когда это изменяется и сохранено в приватной системной таблице механизма на каждой контрольной точке. Эти изменения делают текущее максимальное значение счетчика постоянным через перезапуски сервера.
При перезапуске сервера после нормального завершения работы
InnoDB
инициализирует счетчик в памяти с использованием
текущего максимального значения, сохраненного в системной
таблице словаря данных.
При перезапуске во время восстановления катастрофического отказа
InnoDB
инициализирует счетчик в памяти с использованием
текущего максимального значения, сохраненного в системной таблице словаря
данных, и просматривает журнал redo для значений счетчика, записанных,
начиная с последней контрольной точки. Если зарегистрированное значение
больше, чем встречное значение в памяти, зарегистрированное значение
применено. Однако, в случае катастрофического отказа сервера, повторное
использование ранее выделенного значения не может быть гарантировано. Каждый
раз, когда текущее максимальное значение изменено из-за
INSERT
или
UPDATE
, новое значение записано в
журнал, но если катастрофический отказ происходит прежде, чем журнал
сброшен на диск, ранее выделенное значение могло быть снова использовано,
когда счетчик инициализирован после того, как сервер перезапущен.
Единственное обстоятельство, когда InnoDB
использует
эквивалент SELECT MAX(ai_col)
FROM
в MySQL 8.0, это
инициализируя счетчик, импортируя
табличное пространство без файла метаданных table_name
FOR UPDATE.cfg
.
Иначе текущее максимальное значение счетчика считано из
файла метаданных .cfg
.
В MySQL 5.7 и ранее, перезапуск сервера отменяет эффект опции
AUTO_INCREMENT = N
, которая может использоваться в
CREATE TABLE
или ALTER TABLE
, чтобы установить
начальное значение или изменить существующее значение, соответственно.
В MySQL 8.0 перезапуск сервера не отменяет эффект AUTO_INCREMENT=N
. Если Вы инициализируете автоинкремент в противоречии с определенным
значением, или если Вы изменяете счетчик к большему значению, новое значение
сохранено через перезапуски сервера.
ALTER TABLE ... AUTO_INCREMENT = N
может изменить счетчик только к
значению больше, чем текущий максимум.
В MySQL 5.7 и ранее перезапуск сервера немедленно после
a ROLLBACK
мог привести к повторному использованию значений автоинкремента, которые были
ранее выделены отмененной транзакции, эффективно понижая текущее максимальное
значение автоинкремента до прежнего уровня. В MySQL 8.0, текущее максимальное
значение сохранено, предотвращая повторное использование
ранее выделенных значений.
Если SHOW TABLE STATUS
исследует таблицу прежде, чем счетчик будет инициализирован,
InnoDB
открывает таблицу и инициализирует значение, используя
текущее максимальное значение автоинкремента, которое сохранено в системной
таблице словаря данных. Значение сохранено в памяти для использования позже.
Инициализация встречного значения использует нормальное исключительно
блокирующее чтение на таблице, которое длится до конца транзакции.
InnoDB
следует за той же самой процедурой, инициализируя счетчик
автоинкремента для недавно составленной таблицы, у которой есть определенное
пользователем значение, которое больше 0.
После того, как счетчик инициализирован, если Вы явно не определяете
значение автоинкремента, вставляя строку, InnoDB
неявно
постепенно увеличивает счетчик и назначает новое значение столбцу. Если Вы
вставляете строку, которая явно определяет значение столбца auto-increment,
и значение больше, чем текущее максимальное значение, счетчик
установлен в указанное значение.
InnoDB
использует счетчик auto-increment
в памяти пока выполняется сервер. Когда сервер остановлен и перезапущен,
InnoDB
повторно инициализирует счетчик, как описано ранее.
Опция
auto_increment_offset
определяет начальную точку для значения
AUTO_INCREMENT
. Настройка по умолчанию 1.
Опция
auto_increment_increment
управляет интервалом между
последовательными значениями столбцов. Настройка по умолчанию 1.
Этот раздел описывает различия в обработке механизма хранения InnoDB внешних ключей по сравнению с MySQL Server.
Для информации об использовании внешнего ключа и примеров см. раздел 14.1.15.3.
Определения внешнего ключа для InnoDB
таблицы
подвергаются следующим условиям:
InnoDB
разрешает внешнему ключу ссылаться на любой
индексный столбец или группу столбцов. Однако, в таблице, на которую
ссылаются, должно быть индексирование, где столбцы, на которые ссылаются,
перечислены как первые столбцы в том же самом порядке.
InnoDB
в настоящее время не
поддерживает внешние ключи для таблиц с определяемым пользователем
разделением. Это означает что не разделенная пользователем таблица
может содержать ссылки внешнего ключа или столбцы, на которые
ссылаются внешние ключи.InnoDB
позволяет ограничению внешнего ключа ссылаться на
групповой ключ. Это расширение InnoDB
стандартного SQL.Ссылочные действия для внешних ключей таблицы InnoDB
подвергаются следующим условиям:
В то время, как SET DEFAULT
позволен MySQL Server,
это отклонено как недопустимое InnoDB
.
CREATE TABLE
и
ALTER TABLE
,
использующие этот пункт, не позволены на таблицах InnoDB.
InnoDB
во внешнем ключе проверяет, как будто другие родительские строки с тем же
самым значением ключа не существуют. Например, если Вы определили ограничение
RESTRICT
и есть дочерняя строка с несколькими родительскими
строками, InnoDB
не разрешает удаление любой из
тех родительских строк.InnoDB
выполняет располагающиеся каскадом операции через
алгоритм depth-first, основанный на записях в индексах, соответствующих
ограничениям внешнего ключа.ON UPDATE CASCADE
или ON UPDATE SET NULL
рекурсивны, чтобы обновить ту же самую таблицу, которую
это ранее обновило во время каскада, это действует как RESTRICT
.
Это означает, что Вы не можете использовать самоссылочные операции
ON UPDATE CASCADE
или ON UPDATE SET NULL
.
Это должно предотвратить бесконечные петли, следующие из каскадных
обновлений. Самоссылочная ON DELETE SET NULL
,
с другой стороны, возможна, как самоссылочная ON DELETE CASCADE
.
Расположение каскадом операций не может быть вложено больше,
чем на 15 уровней.InnoDB
проверяет ограничения
UNIQUE
и FOREIGN KEY
построчно.
Выполняя проверки внешнего ключа, InnoDB
ставит
совместно используемые блокировки на уровне строки на дочерних или
родительских записях, на которые это должно смотреть. InnoDB
проверяет ограничения внешнего ключа немедленно, проверка не задержана до
закрытия транзакции. Согласно стандарту SQL, поведение значения по умолчанию
должно быть задержано, проверяя. Таким образом, ограничения проверены только
после того, как весь запрос SQL было обработан. Пока
InnoDB
задерживает проверку ограничения, некоторые вещи
невозможны, например, удаление записи, которая обращается к себе,
используя внешний ключ.Ограничение внешнего ключа на
произведенный сохраненный столбец не может использовать ON UPDATE
CASCADE
, ON DELETE SET NULL
, ON UPDATE SET
NULL
, ON DELETE SET DEFAULT
или
ON UPDATE SET DEFAULT
.
Вы можете получить общую информацию о внешних ключах и их использовании,
запрашивая таблицу
INFORMATION_SCHEMA.KEY_COLUMN_USAGE
,
больше информации, более определенной для таблиц InnoDB
,
может быть найдено в таблицах
INNODB_SYS_FOREIGN
и
INNODB_SYS_FOREIGN_COLS
базы
данных INFORMATION_SCHEMA
.
В дополнение к SHOW ERRORS
,
в случае ошибочного вовлечения внешнего ключа таблицами InnoDB
(обычно Error 150 в MySQL Server), Вы можете получить подробное объяснение
ошибки внешнего ключа, проверяя вывод
SHOW ENGINE INNODB STATUS
.
Это не хорошая идея сконфигурировать InnoDB
, чтобы
использовать файлы с данными или файлы системного журнала на томах NFS.
Файлы могли бы быть заблокированы другими процессами и становиться
недоступными к использованию MySQL.
Таблица может содержать максимум 1017 столбцов. Виртуальные произведенные столбцы включены в этот предел.
DYNAMIC
или
COMPRESSED
.
Предел длины префикса ключа 767 байт для таблиц с форматом строк
REDUNDANT
или COMPACT
.
Например, Вы могли бы упереться в этот лимит с
префиксом столбца индекса
больше, чем 191 символ на столбцах TEXT
или VARCHAR
, принимая набор символов utf8mb4
и максимум 4 байта для каждого символа.
Попытка использовать длину префикса ключа, которая превышает предел, возвращает ошибку.
Пределы, которые применяются, чтобы индексировать ключевые префиксы, также относятся к индексным ключам полного столбца.
innodb_page_size
, создавая сервер MySQL, максимальная длина
индексного ключа понижена пропорционально, основываясь на пределе 3072 байта
для размера страницы 16 КБ. Таким образом, максимум длины ключа 1536 байтов,
когда размер страницы составляет 8 КБ, и 768 байтов, когда размер
страницы составляет 4 КБ.ERROR 1070 (42000): Too many key parts specified; max 16 parts allowed
VARBINARY
,
VARCHAR
,
BLOB
и
TEXT
),
немного меньше, чем половина страницы для размеров страницы 4 КБ, 8 КБ,
16 КБ и 32 КБ. Например, максимальная длина строки для значения по умолчанию
innodb_page_size
16KB составляет около 8000 байт. Для размер страницы 64 КБ максимальная
длина строки составляет приблизительно 16000 байт. Столбцы
LONGBLOB
и
LONGTEXT
должны быть меньше 4 ГБ, и суммарная длина строки, включая столбцы
BLOB
и
TEXT
, должна быть меньше 4GB.
Если строка меньше чем половина страницы длиной, все это сохранено в местном масштабе в пределах страницы. Если это превышает половину страницы, столбцы переменной длины выбраны для внешнего хранения вне страницы, как описано в разделе 16.11.2.
InnoDB
допускает размеры строки больше 65535
байтов внутренне, сам MySQL налагает предел размера строки 65 535 для
объединенного размера всех столбцов:
mysql> CREATE TABLE t (a VARCHAR(8000), b VARCHAR(10000), -> c VARCHAR(10000), d VARCHAR(10000), e VARCHAR(10000), -> f VARCHAR(10000), g VARCHAR(10000)) ENGINE=InnoDB; ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs
См. раздел C.10.4.
InnoDB
непосредственно, но если Вы
требуете большого табличного пространства, конфигурируйте это, используя
несколько меньших файлов с данными, а не один большой.InnoDB
16 КБ. Вы можете
увеличить или уменьшить размер страницы, конфигурируя опцию
innodb_page_size
при установке MySQL.
Размеры страницы 32KB и 64KB поддержаны, но
ROW_FORMAT=COMPRESSED
не поддержан для размеров страницы больше
16 КБ. Для размеров страницы 32 КБ и 64 КБ максимальный размер записи
составляет 16 КБ. Для
innodb_page_size=32k
размер экстента 2MB. Для
innodb_page_size=64k
размер экстента 4MB.
MySQL, используя некий размер страницы не может использовать файлы с данными или файлы системного журнала от экземпляра, который использует иной размер страницы.
ANALYZE TABLE
определяет количество элементов индекса (как выведено на экран в столбце
Cardinality
вывода SHOW INDEX
), делая случайные
погружения к каждому из индексных деревьев и обновляя индексные оценки
количества элементов соответственно. Поскольку это только оценки, повторные
выполнения ANALYZE TABLE
могут произвести различные числа. Это делает
ANALYZE TABLE
быстрым на
InnoDB
, но не 100% точным, потому что это не принимает все
строки во внимание.
Вы можете сделать сбор
статистики
ANALYZE TABLE
более точным и устойчивым, включая опцию
innodb_stats_persistent
, как описано в
разделе 16.6.10.1.
Когда эта установка включена, важно выполнить
ANALYZE TABLE
после существенных изменений индексированных данных в столбце, потому что
статистические данные не вычисляются повторно периодически
(как после перезапуска сервера).
Вы можете изменить число случайных погружений, изменяя переменную
innodb_stats_persistent_sample_pages
(если постоянная установка статистики включена) или
innodb_stats_transient_sample_pages
(если постоянная установка статистики выключена).
MySQL использует оценки количества элементов только в оптимизации
соединения. Если некоторое соединение не оптимизировано правильным способом,
Вы можете попытаться использовать
ANALYZE TABLE
. В немногих случаях это
ANALYZE TABLE
не производит значения, достаточно хорошие для Ваших особых таблиц, Вы можете
использовать FORCE INDEX
с Вашими запросами, чтобы вызвать
использование индекса или установить
max_seeks_for_key
, чтобы гарантировать, что MySQL предпочитает, индексные поиски
сканированию таблицы. См. разделы
6.1.5 и
B.5.5.
ANALYZE TABLE
выполнен на той же самой таблице, сопровождаемый вторым
ANALYZE TABLE
, второй вызов
ANALYZE TABLE
заблокирован, пока запрос или транзакции не завершены. Это поведение
происходит потому, что ANALYZE
TABLE
отмечает в настоящее время загружаемое табличное определение
как устаревшее, когда ANALYZE TABLE
закончен. Новые запросы или транзакции (включая второй
ANALYZE TABLE
)
должен загрузить новое табличное определение в табличный кэш, что не может
произойти, пока в настоящее время рабочие запросы или транзакции не
завершены, и старое табличное определение не очищено.
Загрузка многократных параллельных табличных определений не поддержана.SHOW TABLE STATUS
не дает точную статистику по таблицам InnoDB
, за исключением
физического места, зарезервированного таблицей. Количество строки только
грубая оценка, используемая в оптимизации SQL.InnoDB
не проводит внутренний подсчет строк в таблице,
потому что параллельные транзакции могли бы
видеть различные числа строк в то же самое время.
Следовательно, SELECT COUNT(*) FROM t
считает только строки, видимые текущей транзакции.
Чтобы выполнить SELECT COUNT(*) FROM t
, InnoDB
кластерный индекс, что занимает время, если записи индекса не находятся
полностью в буферном пуле. Для более быстрого счета Вы можете составить
таблицу счетчиков и позволить Вашему приложению обновлять ее, согласно
вставкам и удалениям. Однако, этот метод, возможно, не масштабируется хорошо
в ситуациях, где тысячи параллельных транзакций начинают обновления той же
самой таблицы. Если приблизительное количество строки достаточно, может
использоваться SHOW TABLE STATUS
.
SELECT COUNT(*) FROM t
вызывает единственный вызов
обработчика механизма хранения, чтобы просмотреть кластеризируемый индекс
и возвращает количество строк. Эта оптимизация очевидна в выводе
EXPLAIN
для
SELECT COUNT(*) FROM t
, который сообщает
Select tables optimized away
:
mysql> EXPLAIN SELECT COUNT(*) FROM t1\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: NULL partitions: NULL type: NULL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Select tables optimized away
AUTO_INCREMENT
ai_col
должен быть определен как часть индексирования таким образом, что возможно
выполнить эквивалент индексного SELECT MAX(ai_col
)
поиска на таблице, чтобы получить максимальное значение
столбца. Как правило, это достигнуто, делая столбец первым столбцом
индекса некоторой таблицы.InnoDB
устанавливает исключительную блокировку на конце
индексирования, связанного со столбцом AUTO_INCREMENT
,
инициализируя ранее указанный столбец AUTO_INCREMENT
таблицы.
С
innodb_autoinc_lock_mode=0
InnoDB
использует
специальный режим блокировки таблицы AUTO-INC
, где блокировка
получена и проведена до конца текущего запроса SQL, получая доступ к счетчику
auto-increment. Другие клиенты не могут вставить в таблицу в то время, как
табличная блокировка AUTO-INC
проводится.
То же самое поведение происходит для bulk-вставок с
innodb_autoinc_lock_mode=1
. На уровне таблицы блокировки
AUTO-INC
не используются с
innodb_autoinc_lock_mode=2
. Подробности в
разделе 16.8.5.
AUTO_INCREMENT
исчерпывает значения, последующий INSERT
возвращает ошибку дубликата ключа. Это общее поведение
MySQL, подобное MyISAM
.DELETE FROM tbl_name
не восстанавливает таблицу, но вместо этого удаляет все строки поштучно.InnoDB
(включая
DB_ROW_ID
, DB_TRX_ID
, DB_ROLL_PTR
,
и DB_MIX_ID
). Это ограничение применяется к использованию
имен в любом регистре.
mysql> CREATE TABLE t1 (c1 INT, db_row_id INT) ENGINE=INNODB; ERROR 1166 (42000): Incorrect column name 'db_row_id'
LOCK TABLES
приобретает две блокировки на каждой таблице, если
innodb_table_locks=1
(значение по умолчанию). В дополнение к
табличному уровню MySQL, это также приобретает табличную блокировку
InnoDB
. MySQL до 4.1.2 не приобретал табличную блокировку
InnoDB
, старое поведение может быть выбрано, устанавливая
innodb_table_locks=0
. Если табличная блокировка
InnoDB
не приобретена,
LOCK TABLES
завершается, даже если некоторые записи таблиц
блокируются другими транзакциями.
В MySQL 8.0
innodb_table_locks=0
не имеет никакого эффекта для таблиц,
заблокированных явно с LOCK TABLES ...
WRITE
. Это действительно имеет эффект для таблиц, заблокированных
для чтения или записи через LOCK TABLES
... WRITE
неявно (например, через триггеры) или
LOCK TABLES ... READ
.
LOCK TABLES
на таблицах
InnoDB
в режиме
autocommit=1
потому что приобретенные табличные блокировки были
бы немедленно выпущены.LOCK TABLES
выполняет неявные COMMIT
и
UNLOCK TABLES
.У каждой таблицы InnoDB
есть специальный
кластеризируемый индекс,
где данные для строк хранятся. Как правило, кластеризируемый индекс
синонимичен с первичным ключом.
Чтобы получить лучшую работу от запросов, вставок и других операций базы
данных, Вы должны понять, как использовать кластеризируемый индекс, чтобы
оптимизировать наиболее распространенный поиск и операции DML
для каждой таблицы.
Когда Вы определяете PRIMARY KEY
на Вашей таблице, InnoDB
использует это как кластеризируемый
индекс. Определите первичный ключ для каждой таблицы, которую Вы составляете.
Если нет никакого логического уникального и ненулевого столбца или набора
столбцов, добавьте новый столбец
auto-increment, значения которого заполнены автоматически.
PRIMARY KEY
для Вашей таблицы MySQL определяет местонахождение первого индекса
UNIQUE
, где все ключевые столбцы NOT NULL
и
использует это как кластеризируемый индекс.PRIMARY KEY
или подходящий индекс
UNIQUE
, InnoDB
внутренне производит
кластеризируемый скрытый индекс на синтетическом столбце, содержащем значения
идентификаторов строки. Строки упорядочены по ID, которые InnoDB
назначает строкам в такой таблице. ID строки 6-байтовая область, которая
увеличивается монотонно, когда новые строки вставлены. Таким образом, строки,
упорядоченные ID строки, находятся физически в порядке вставки.Доступ к строке через кластеризируемый индекс быстр, потому что поиск
приводит непосредственно к странице со всеми данными о строке.
Если таблица является большой, кластеризируемый индекс
часто уменьшает дисковую нагрузку ввода/вывода по сравнению с организациями
хранения, которые хранят данные о строке, используя иную страницу для
индексной записи. Например, MyISAM
использует один файл для
строк данных и другой для индексных записей.
Все индексирует кроме кластеризируемого известны как
вторичные. В
InnoDB
каждая запись во вторичном индексе содержит столбцы
первичного ключа для строки, так же как столбцы, определенные для вторичного
индекса. InnoDB
применяет это значение первичного ключа, чтобы
искать строку в кластеризируемом индексе.
Если первичный ключ длинен, вторичные индексы используют больше пространства, таким образом, выгодно иметь короткий первичный ключ.
См. подробности в разделах 9.3.2, 9.3, 9.5 и 9.3.2.
Индексы FULLTEXT
создаются на основанных на тексте столбцах
(CHAR
,
VARCHAR
или
TEXT
), чтобы
ускорить запросы и операции DML на данных в пределах тех столбцов, опуская
любые слова, которые определены как stopword.
Индекс FULLTEXT
может быть определен как часть
CREATE TABLE
или добавлен позже с использованием
ALTER TABLE
или
CREATE INDEX
.
Полнотекстовый поиск выполнен, используя
MATCH() ... AGAINST
.
Подробности в разделе 13.9.
Индексы InnoDB
FULLTEXT
имеют проект
инвертированного индекса. Инвертированные индексы хранят список слов, и для
каждого слова, список документов, в которых появляется слово. Чтобы
поддержать поиск близости, информация о положении для каждого слова также
сохранена, как смещение байта.
Для каждого индекса FULLTEXT
ряд индексных таблиц создается,
как показано в следующем примере:
CREATE TABLE opening_lines (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, opening_line TEXT(500), author VARCHAR(200), title VARCHAR(200), FULLTEXT idx (opening_line)) ENGINE=InnoDB; mysql> SELECT table_id, name, space from INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE name LIKE 'test/%'; +----------+----------------------------------------------------+-------+ | table_id | name | space | +----------+----------------------------------------------------+-------+ | 333 | test/FTS_0000000000000147_00000000000001c9_INDEX_1 | 289 | | 334 | test/FTS_0000000000000147_00000000000001c9_INDEX_2 | 290 | | 335 | test/FTS_0000000000000147_00000000000001c9_INDEX_3 | 291 | | 336 | test/FTS_0000000000000147_00000000000001c9_INDEX_4 | 292 | | 337 | test/FTS_0000000000000147_00000000000001c9_INDEX_5 | 293 | | 338 | test/FTS_0000000000000147_00000000000001c9_INDEX_6 | 294 | | 330 | test/FTS_0000000000000147_BEING_DELETED | 286 | | 331 | test/FTS_0000000000000147_BEING_DELETED_CACHE | 287 | | 332 | test/FTS_0000000000000147_CONFIG | 288 | | 328 | test/FTS_0000000000000147_DELETED | 284 | | 329 | test/FTS_0000000000000147_DELETED_CACHE | 285 | | 327 | test/opening_lines | 283 | +----------+----------------------------------------------------+-------+
Первые шесть таблиц представляют инвертированный индекс и упоминаются,
как вспомогательные индексные таблицы. Когда поступающие документы размечены,
отдельные слова (также называемые токенами)
вставлены в индексные таблицы наряду с информацией о положении и связанным
Document ID (DOC_ID
). Слова полностью сортированы и разделены
среди этих шести индексных таблиц, основываясь на весе вида набора символов
первого символа слова.
Инвертированный индекс разделен на шесть вспомогательных
индексных таблицы, чтобы поддержать параллельное создание индексов.
По умолчанию два потока размечают, сортируют и вставляют слова и связанные
данные в таблицы. Число потоков конфигурируемое с использованием опции
innodb_ft_sort_pll_degree
. Создавая FULLTEXT
на
больших таблицах, рассмотрите увеличивание числа потоков.
Имена таблиц предварительно установлены с префиксом
FTS_
и постфиксом INDEX_*
.
Каждая таблица связана с индексированной таблицей значением
в имени индексной таблицы, которое соответствует table_id
индексированной таблицы. Например, table_id
из
test/opening_lines
327
для которого
шестнадцатеричное значение 0x147. Как показано в предыдущем примере,
147 появляется в названиях индексных таблиц,
которые связаны с test/opening_lines
.
Значение представляющее index_id
индекса
FULLTEXT
также появляется в именах вспомогательных индексных
таблиц. Например, во вспомогательном имени таблицы
test/FTS_0000000000000147_00000000000001c9_INDEX_1
это
1c9
, в десятичном виде 457. Индекс определен в таблице
opening_lines
(idx
) и может быть идентифицирован,
запрашивая из таблицы
INFORMATION_SCHEMA.INNODB_SYS_INDEXES
его значение (457).
mysql> SELECT index_id, name, table_id, space from INFORMATION_SCHEMA.INNODB_SYS_INDEXES WHERE index_id=457; +----------+------+----------+-------+ | index_id | name | table_id | space | +----------+------+----------+-------+ | 457 | idx | 327 | 283 | +----------+------+----------+-------+
Индексные таблицы сохранены в их собственном табличном пространстве, если основная таблица составлена в табличном пространстве file-per-table.
Другие индексные таблицы, показанные в предыдущем примере, используются
для обработки удаления и для того, чтобы сохранить внутреннее
состояние индекса FULLTEXT
.
FTS_*_DELETED
и FTS_*_DELETED_CACHE
:
Хранят ID (DOC_ID) для документов, которые удалены, но чьи данные еще не
удалены из полнотекстового индекса. FTS_*_DELETED_CACHE
версия в памяти для FTS_*_DELETED
.
FTS_*_BEING_DELETED
и FTS_*_BEING_DELETED_CACHE
: Хранят ID (DOC_ID) для документов, которые удалены, но чьи данные
в настоящее время находятся в процессе того, чтобы быть удаленными
из полнотекстового индекса. FTS_*_BEING_DELETED_CACHE
версия в памяти для FTS_*_BEING_DELETED
.FTS_*_CONFIG
: Хранит информацию о внутреннем состоянии
индекса FULLTEXT
. Что наиболее важно, это хранит
FTS_SYNCED_DOC_ID
, который идентифицирует документы, которые
были разобраны и сброшены на диск. В случае восстановления катастрофического
отказа значения FTS_SYNCED_DOC_ID
используются, чтобы
идентифицировать документы, которые не сброшены на диск, чтобы документы
могли быть повторно разобраны и добавлены назад к кэшу индекса
FULLTEXT
. Чтобы смотреть данные в этой таблице, запросите
таблицу
INFORMATION_SCHEMA.INNODB_FT_CONFIG
.Когда документ вставлен, он размечен, и отдельные слова и связанные данные
вставлены в таблицу, чтобы рассмотреть размеченные данные для
недавно вставленных строк. Этот процесс, даже для маленьких документов, мог
привести к многочисленным небольшим вставкам во вспомогательные
таблицы, делая параллельный доступ к этим таблицам предметом спора. Чтобы
избежать этой проблемы, InnoDB
использует кэш индекса
FULLTEXT
, чтобы временно кэшировать табличные вставки для
недавно вставленных строк. Эта структура в кэш-памяти содержит вставки, пока
кэш не заполнится, и затем пакетом сбрасывает их на диск (к вспомогательной
индексной таблице). Вы можете запросить таблицу
INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE
, чтобы смотреть
размеченные данные для недавно вставленных строк.
Поведение кэширования и пакета избегает частых обновлений вспомогательных таблиц, которые могли привести к параллельным проблемам доступа во время занятой вставки и обновления. Метод группирования также избегает многократных вставок для того же самого слова и минимизирует двойные записи. Вместо того, чтобы сбросить каждое слово индивидуально, вставки для того же самого слова слиты и сбрасываются на диск как единственная запись, улучшая эффективность вставки, в то время как размер индексных таблиц как можно меньше.
Переменная
innodb_ft_cache_size
используется, чтобы сконфигурировать размер
кэша (на основе таблицы), который затрагивает, как часто полнотекстовый
индексный кэш сбрасывается. Вы можете также определить глобальный предел
размера кэша для всех таблиц в приведенном примере, используя опцию
innodb_ft_total_cache_size
.
Полнотекстовый индексный кэш хранит ту же самую информацию, как и вспомогательные индексные таблицы. Однако, полнотекстовый индексный кэш кэширует только размеченные данные для недавно вставленных строк. Данные, которые уже сброшены на диск (к полнотекстовым вспомогательным таблицам) не возвращены в кэш когда запрошены. Данные во вспомогательных таблицах запрошены непосредственно, и результаты из вспомогательных таблиц слиты с результатами из кэша прежде, чем быть возвращенными.
InnoDB
использует уникальный идентификатор документа,
называемый Document ID (DOC_ID
),
чтобы отобразить слова в полнотекстовом индекс на записи, где слово
появляется. Отображение требует столбца FTS_DOC_ID
в
индексированной таблице. Если FTS_DOC_ID
не определен, InnoDB
автоматически добавляет скрытый столбец
FTS_DOC_ID
, когда полнотекстовый индекс создается. Следующий
пример демонстрирует это поведение.
Следующее табличное определение не включает FTS_DOC_ID
:
CREATE TABLE opening_lines (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, opening_line TEXT(500), author VARCHAR(200), title VARCHAR(200)) ENGINE=InnoDB;
Когда Вы создаете полнотекстовый индекс, используя
CREATE FULLTEXT INDEX
, предупреждение возвращено, которое
сообщает о том, что InnoDB
переделывает таблицу, чтобы
добавить столбец FTS_DOC_ID
.
mysql> CREATE FULLTEXT INDEX idx ON opening_lines(opening_line); Query OK, 0 rows affected, 1 warning (0.19 sec) Records: 0 Duplicates: 0 Warnings: 1 mysql> SHOW WARNINGS; +---------+------+--------------------------------------------------+ | Level | Code | Message | +---------+------+--------------------------------------------------+ | Warning | 124 | InnoDB rebuilding table to add column FTS_DOC_ID | +---------+------+--------------------------------------------------+
То же самое предупреждение возвращено, используя
ALTER TABLE
,
чтобы добавить полнотекстовый индекс к таблице, которая не имеет столбца
FTS_DOC_ID
. Если Вы создаете полнотекстовый индекс через
CREATE TABLE
и не определяете FTS_DOC_ID
, InnoDB
добавляет скрытый столбец FTS_DOC_ID
без предупреждения.
Определение FTS_DOC_ID
в
CREATE TABLE
уменьшает время, требуемое, чтобы создать полнотекстовый индекс на таблице,
которая уже загружена данными. Если столбец FTS_DOC_ID
определен на таблице до загрузки данных, таблица и индекс не должны быть
переделаны, чтобы добавить новый столбец. InnoDB
создает скрытый столбец FTS_DOC_ID
наряду с уникальным индексом
(FTS_DOC_ID_INDEX
) на столбце FTS_DOC_ID
.
Если Вы хотите создать свой собственный FTS_DOC_ID
,
столбец должен быть определен как BIGINT UNSIGNED NOT NULL
и
назван FTS_DOC_ID
(все буквы большие), как в следующем примере:
Столбец FTS_DOC_ID
не должен быть определен как
AUTO_INCREMENT
, но
AUTO_INCREMENT
мог сделать загрузку данных легче.
CREATE TABLE opening_lines ( FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, opening_line TEXT(500), author VARCHAR(200), title VARCHAR(200)) ENGINE=InnoDB;
Если Вы хотите определять FTS_DOC_ID
самостоятельно, Вы ответственны за управление столбцом, чтобы избежать пустых
или двойных значений. Значения FTS_DOC_ID
не могут быть снова использованы, что означает, что значения
FTS_DOC_ID
должны когда-либо увеличиваться.
Произвольно Вы можете создать необходимый уникальный
FTS_DOC_ID_INDEX
на столбце FTS_DOC_ID
.
CREATE UNIQUE INDEX FTS_DOC_ID_INDEX on opening_lines(FTS_DOC_ID);
Если Вы не создаете FTS_DOC_ID_INDEX
, InnoDB
создает это автоматически.
Разрешенный промежуток между используемым самым большим значением
FTS_DOC_ID
и новым значением FTS_DOC_ID
65535.
Удаление записи, у которой есть полнотекстовый индекс, может привести к
многочисленным маленьким удалениям во вспомогательных индексных таблицах,
делая параллельный доступ к этим таблицам предметом спора. Чтобы
избежать этой проблемы, Document ID (DOC_ID
)
из удаленного документа зарегистрирован в спецтаблице
FTS_*_DELETED
всякий раз, когда запись удалена из
индексированной таблицы, и запись остается в полнотекстовом индексе.
Перед возвращением результатов запроса, информация в
FTS_*_DELETED
используется, чтобы отфильтровать удаленные
Document ID. Выгода этого проекта то, что удаления быстры и недороги.
Недостаток состоит в том, что размер индекса не был немедленно уменьшен после
удаления записей. Чтобы удалить полнотекстовые индексные записи,
надо выполнить OPTIMIZE TABLE
на индексированной таблице с
innodb_optimize_fulltext_only=ON
, чтобы восстановить
полнотекстовый индекс.
Индексы FULLTEXT
имеют специальные операционные
характеристики управляемости, описывающие поведение кэширования и пакетной
обработки данных. Определенно, обновления и вставки на индексе
FULLTEXT
обработаны в момент закрытия транзакции, что означает,
что поиск FULLTEXT
может видеть только переданные данные.
Следующий пример демонстрирует это поведение. FULLTEXT
возвращает результат после того, как вставленные строки переданы.
mysql> CREATE TABLE opening_lines ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, opening_line TEXT(500), author VARCHAR(200), title VARCHAR(200), FULLTEXT idx (opening_line)) ENGINE=InnoDB; mysql> BEGIN; Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO opening_lines(opening_line,author,title) VALUES ('Call me Ishmael.','Herman Melville','Moby-Dick'), ('A screaming comes across the sky.','Thomas Pynchon','Gravity\'s Rainbow'), ('I am an invisible man.','Ralph Ellison','Invisible Man'), ('Where now? Who now? When now?','Samuel Beckett','The Unnamable'), ('It was love at first sight.','Joseph Heller','Catch-22'), ('All this happened, more or less.','Kurt Vonnegut','Slaughterhouse-Five'), ('Mrs. Dalloway said she would buy the flowers herself.','Virginia Woolf','Mrs. Dalloway'), ('It was a pleasure to burn.','Ray Bradbury','Fahrenheit 451'); Query OK, 8 rows affected (0.00 sec) Records: 8 Duplicates: 0 Warnings: 0 mysql> SELECT COUNT(*) FROM opening_lines WHERE MATCH(opening_line) AGAINST('Ishmael'); +----------+ | COUNT(*) | +----------+ | 0 | +----------+ mysql> COMMIT; Query OK, 0 rows affected (0.00 sec) mysql> SELECT COUNT(*) FROM opening_lines WHERE MATCH(opening_line) AGAINST('Ishmael'); +----------+ | COUNT(*) | +----------+ | 1 | +----------+
Вы можете контролировать и исследовать специальные относящиеся к обработке
текстов аспекты InnoDB
FULLTEXT
, запрашивая
следующие таблицы INFORMATION_SCHEMA
:
INNODB_FT_INDEX_TABLE
INNODB_FT_INDEX_CACHE
INNODB_FT_DEFAULT_STOPWORD
INNODB_FT_DELETED
INNODB_FT_BEING_DELETED
Вы можете также рассмотреть основную информацию для индексов
FULLTEXT
и таблиц, запрашивая
INNODB_SYS_INDEXES
и INNODB_SYS_TABLES
.
См. раздел 16.14.4.
За исключением пространственного индекса, индексы InnoDB
это структуры данных B-tree.
Пространственный индекс использует
R-tree, которые являются специализированными структурами данных для того,
чтобы индексировать многомерные данные. Индексные записи сохранены в
страницах листа их структуры данных B-tree или R-tree.
Размер по умолчанию индексной страницы составляет 16 КБ.
Когда новые записи вставлены в
кластеризируемый индекс,
InnoDB
попытается оставить 1/16 страницы свободной для будущих
вставок и обновлений. Если индексные записи вставлены в последовательном
порядке (возрастание или убывание), получающиеся индексные страницы полны на
15/16. Если записи вставлены в случайном порядке, страницы полны от 1/2 до
15/16.
InnoDB
выполняет оптовую загрузку, когда создает B-tree
индексов. Этот метод создания индекса известен как сортированный индекс.
innodb_fill_factor
определяет процент пространства на каждой странице B-дерева,
который заполнен во время создания сортированного индекса с остающимся
пространством, сохраненным для будущего роста. Создание сортированного
индекса не поддержанр для пространственного индекса. Для получения
дополнительной информации см.
раздел 16.8.11.
innodb_fill_factor
устанавливает 1/16 пространства в кластеризируемых индексных
страницах свободным для будущего роста.
Если коэффициент заполнения индексной страницы понижается ниже
MERGE_THRESHOLD
, который составляет 50% по умолчанию, если не
определен InnoDB
пробует сократить индексное дерево, чтобы
освободить страницу. MERGE_THRESHOLD
относится к B-tree и
R-tree. Подробности в разделе
16.6.11.
Вы можете сконфигурировать размер
страницы для всех табличных пространств InnoDB
, задав опцию
innodb_page_size
прежде, чем создать экземпляр. Как только размер страницы установлен, Вы
не можете изменить его. Поддержанные размеры составляют 64KB, 32KB, 16KB
(значение по умолчанию), 8KB и 4KB, соответствуя значениям опции
64k
, 32k
, 16k
, 8k
и
4k
.
InnoDB
выполняет оптовую загрузку вместо того, чтобы вставить
каждую запись в то время, когда создает индекс. Этот метод известен как
создание сортированного индекса. Сортированный индекс не поддержан
для пространственного индекса.
Есть три фазы создания индекса. В первой фазе кластеризируемый индекс просмотрен, и индексные записи произведены и добавлены к буферу. Когда буфер сортировки становится полным, записи сортированы и записаны во временный промежуточный файл. Этот процесс также известен как run. Во второй фазе, с одним или более выполнениями, записанными во временный промежуточный файл, сортировка слиянием выполнена на всех записях в файле. В третьей и заключительной фазе сортированные записи вставлены в B-tree.
До введения сортированных индексов записи были вставлены в B-tree поштучно, используя insert API. Этот метод вовлекал открытие B-tree курсора, чтобы найти позицию вставки, а затем вставку записей в страницу B-tree, используя оптимистическуювставку. Если бы вставка потерпела неудачу из-за полной страницы, то пессимистическая вставка была бы выполнена, которая вовлекает открытие курсора B-tree, разделение и слияние узлов B-tree по мере необходимости, чтобы найти пространство для входа. Недостатки этого метод создания индексирования являются стоимостью поиска позиции вставки и постоянного разделения и слияния узлов B-tree.
Сортированный индекс использует восходящий подход к созданию индекса. С этим подходом ссылка на самую правую страницу листа проводится на всех уровнях B-tree. Самая правая страница листа в необходимой глубине B-tree выделена, и записи вставлены согласно их сортированному порядку. Как только страница листа полна, указатель узла приложен к родительской странице, и страница листа выделена для следующей вставки. Этот процесс продолжается, пока все записи не вставлены, что может привести к вставкам до уровня корня. Когда страница выделена, ссылка на ранее прикрепленную страницу листа выпущена, и недавно выделенная страница листа становится самой правой страницей листа (и новым значением по умолчанию места для вставки).
Чтобы отложить пространство для будущего индексного роста, Вы можете
использовать опцию
innodb_fill_factor
, чтобы зарезервировать процент пространства
страницы B-tree. Например, установка
innodb_fill_factor
в 80 резервирует 20 процентов пространства в страницах B-tree
во время создания сортированного индекса. Эта установка относится к страницам
листа и не к страницам листа B-tree. Это не относится к внешним страницам,
используемым для TEXT
или
BLOB
.
Количество пространства, которое сохранено, не может быть точно
сконфигурировано, поскольку
innodb_fill_factor
интерпретируется как подсказка, а
не жесткий предел.
Создание сортированного индекса поддерживается для индексов fulltext. Ранее SQL использовался, чтобы вставить записи в индексы fulltext.
Для сжатых таблиц предыдущие метод создания индекса добавляет записи в сжатые и в несжатые страницы. Когда журнал модификации (представляющий свободное пространство на сжатой странице) станет полным, сжатая страница будет пересжата. Если бы сжатие потерпело неудачу из-за недостатка места, то страница была бы разделена. С сортированным индексом записи добавлены только к несжатым страницам. Когда несжатая страница становится полной, она сжата. Адаптивное дополнение используется, чтобы гарантировать, что сжатие преуспевает в большинстве случаев, но если сжатие терпит неудачу, страница разделена, и сжатие предпринято снова. Этот процесс продолжается, пока сжатие не пройдет успешно. Для дополнительной информации о сжатии страниц B-Tree см. раздел 16.9.1.5.
Журнал Redo выключен во время создания сортированного индекса. Вместо этого есть контрольная точка, чтобы гарантировать, что индексирование может противостоять катастрофическому отказу. Контрольная точка вызывает запись всех грязных страниц на диск. Во время создания сортированного индекса поток уборщика страницы вызван периодически, чтобы сбросить грязные страницы, чтобы гарантировать, что работа контрольной точки может быть обработана быстро. Обычно поток уборщика сбрасывает грязные страницы, когда число чистых страниц падает ниже порога набора. При создании сортированного индекса грязные страницы сбрасываются быстро, чтобы уменьшить издержки контрольной точки.
Создание сортированного индекса может привести к статистическим данным, которые отличаются от произведенных предыдущим методом создания индекса, используемым в более ранних выпусках MySQL. Различие в статистике, которое, как ожидают, не затронет рабочую нагрузку, происходит из-за различного алгоритма, который используется, чтобы заполнить индекс.
Этот раздел предоставляет информацию о табличном сжатии и особенности сжатия страницы. Особенность сжатия страницы также упоминается как прозрачное сжатие страницы.
Используя функции сжатия InnoDB
, Вы можете составить таблицы,
где данные хранятся в сжатой форме. Сжатие может помочь улучшить сырую работу
и масштабируемость. Сжатие означает, что меньше данных передано между диском
и памятью, и занимает меньше места на диске и в памяти. Выгода усилена для
таблиц с вторичными индексами
, потому что индексные данные сжаты также. Сжатие может быть особенно
важным для устройств хранения данных SSD
из-за их низкой емкости.
Этот раздел описывает табличное сжатие, которое поддержано
таблицами, которые находятся в табличных пространствах
file_per_table или
общих табличных пространствах
. Табличное сжатие включено, используя атрибут
ROW_FORMAT=COMPRESSED
с
CREATE TABLE
или
ALTER TABLE
.
Поскольку процессоры и кэш-память увеличили в скорости больше, чем дисковые устройства хранения данных, много рабочих нагрузок являются зависящими от диска. Сжатие данных приводит к меньшему размеру базы данных, уменьшенному вводу/выводу и улучшенной пропускной способности, при маленькой стоимости увеличенного использования центрального процессора. Сжатие особенно ценно для интенсивных чтением приложений, на системах с достаточным количеством RAM, чтобы сохранить часто используемые данные в памяти.
Таблица, составленная с ROW_FORMAT=COMPRESSED
может
использовать меньший размер страницы
на диске, чем сконфигурировано
innodb_page_size
. Меньшие страницы требуют меньше ввода/вывода, который особенно ценен
для устройств SSD.
Сжатый размер страницы определен через параметр
KEY_BLOCK_SIZE
в CREATE
TABLE
или ALTER TABLE
. Различный размер страницы требует, чтобы таблица была помещена в
табличное пространство
file-per-table или в
общее табличное пространство, а не в
системное табличное
пространство, поскольку системное табличное пространство не может
сохранить сжатые таблицы. Для получения дополнительной информации см. разделы
16.7.4 и
16.7.9.
Уровень сжатия не зависит от KEY_BLOCK_SIZE
.
Поскольку Вы определяете меньшие значения для KEY_BLOCK_SIZE
,
Вы извлекаете пользу ввода/вывода из все более и более меньших страниц. Но
если Вы определяете значение, которое является слишком маленьким, будут
лишние накладные расходы, чтобы реорганизовать страницы, когда значения
данных не могут быть сжаты достаточно, чтобы разместить много строк в каждой
странице. Есть жесткий предел нижнего размера KEY_BLOCK_SIZE
,
который может быть для таблицы, основанный на длинах ключевых столбцов для
каждого из индексов. Определите значение, которое является слишком маленьким,
и CREATE TABLE
или
ALTER TABLE
не сработают.
В буферном пуле сжатые данные проводятся в маленьких страницах, с размером
страницы, основанным на KEY_BLOCK_SIZE
.
Для извлечения или обновления значений столбцов MySQL также создает несжатую
страницу в буферном пуле с несжатыми данными. В буферном пуле любые
обновления несжатой страницы также переписаны назад к эквивалентной сжатой
странице. Вы, возможно, должны были бы измерить свой буферный пул, чтобы
приспособить дополнительные данные и сжатых и несжатых страниц,
хотя несжатые страницы вычеркиваются
из буферного пула, когда пространство необходимо, и затем разсжаты снова
при следующем доступе.
Сжатые таблицы могут быть составлены в табличных пространствах file-per-table или в общих табличных пространствах . Табличное сжатие недоступно для системного табличного пространства. Системное табличное пространство (файлы .ibdata) может содержать создаваемые пользователем таблицы, но оно также содержит внутренние системные данные, которые никогда не сжимаются. Таким образом, сжатие применяется только к таблицам и индексам, сохраненным в file-per-table или общих табличных пространствах.
Чтобы создать сжатую таблицу в табличном пространстве file-per-table,
innodb_file_per_table
должен быть включен (значение по умолчанию). Вы можете установить
эти параметры в конфигурационном файле MySQL (my.cnf
или
my.ini
) или динамически с использованием
SET
.
После настройки опции
innodb_file_per_table
определите параметр
ROW_FORMAT=COMPRESSED
, KEY_BLOCK_SIZE
или оба
в CREATE TABLE
или
ALTER TABLE
,
чтобы составить сжатую таблицу в табличном пространстве file-per-table.
Например, Вы могли бы использовать следующие запросы:
SET GLOBAL innodb_file_per_table=1; CREATE TABLE t1 (c1 INT PRIMARY KEY) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
Чтобы создать сжатую таблицу в общем табличном пространстве,
FILE_BLOCK_SIZE
должен быть определен для общего табличного
пространства, которое определено, когда табличное пространство создается.
FILE_BLOCK_SIZE
должно быть допустимым сжатым размером страницы
относительно
innodb_page_size
, размер страницы сжатой таблицы, определенной
параметром KEY_BLOCK_SIZE
в
CREATE TABLE
или ALTER
TABLE
должен быть равным FILE_BLOCK_SIZE/1024
.
Например, если
innodb_page_size=16384
и FILE_BLOCK_SIZE=8192
,
KEY_BLOCK_SIZE
должен быть 8. Для получения дополнительной
информации см. раздел 16.7.9.
Следующий пример демонстрирует создание общего табличного пространства и
добавление сжатой таблицы. Пример принимает значение по умолчанию
innodb_page_size
16K. FILE_BLOCK_SIZE
= 8192 требует, чтобы у сжатой таблицы
был KEY_BLOCK_SIZE
= 8.
mysql> CREATE TABLESPACE `ts2` ADD DATAFILE 'ts2.ibd' FILE_BLOCK_SIZE = 8192 Engine=InnoDB; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE t4 (c1 INT PRIMARY KEY) TABLESPACE ts2 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; Query OK, 0 rows affected (0.00 sec)
Если Вы определяете ROW_FORMAT=COMPRESSED
,
Вы можете опустить KEY_BLOCK_SIZE
, KEY_BLOCK_SIZE
по умолчанию установится к половине
innodb_page_size
.
KEY_BLOCK_SIZE
, Вы
можете опустить ROW_FORMAT=COMPRESSED
,
сжатие включено автоматически.KEY_BLOCK_SIZE
,
как правило, Вы создаете несколько копий той же самой таблицы с различными
значениями для этого параметра, затем измеряете размер получающегося файла
.ibd
. Для общих табличных пространств имейте в виду, что
понижение таблицы не уменьшает размер файла .ibd
общего
табличного пространства и при этом не возвращает дисковое пространство к
операционной системе. Для получения дополнительной информации см.
раздел 16.7.9.KEY_BLOCK_SIZE
обработано как подсказка,
иной размер может использоваться InnoDB
в случае необходимости.
Для табличных пространств file-per-table KEY_BLOCK_SIZE
может быть только меньше или равным
innodb_page_size
. Если Вы определяете значение больше, чем
innodb_page_size
, указанное значение проигнорировано, предупреждение выпущено и
KEY_BLOCK_SIZE
установлен в половину
innodb_page_size
. Если innodb_strict_mode=ON
, определение недопустимого
KEY_BLOCK_SIZE
возвращает ошибку. Для общих табличных
пространств допустимые значения KEY_BLOCK_SIZE
зависят от FILE_BLOCK_SIZE
. Подробности в
разделе 16.7.9.InnoDB
поддерживает размеры страницы 32 k и 64 k, но эти
размеры страницы не поддерживают сжатие. Для получения дополнительной
информации обратитесь к описанию
innodb_page_size
..ibd
). Фактический алгоритм сжатия не затронут
KEY_BLOCK_SIZE
, значение определяет, насколько большой каждый
сжатый кусок, что в свою очередь затрагивает, сколько строк может быть
упаковано в каждую сжатую страницу.KEY_BLOCK_SIZE
равным
размеру страницы,
как правило, не приводит к большому сжатию. Например, установка
KEY_BLOCK_SIZE=16
обычно не приводила бы к большому сжатию,
начиная с нормального размера страницы 16KB. Эта установка может все еще быть
полезной для таблиц с многими большими столбцами
BLOB
,
VARCHAR
или
TEXT
, потому что такие значения
часто сжимаются хорошо, и могли бы поэтому потребовать меньшего количества
страниц переполнения,
как описано в разделе
16.9.1.5. Для общих табличных пространств KEY_BLOCK_SIZE
равный размеру страницы не разрешен. Для получения дополнительной информации
см. раздел 16.7.9.CREATE TABLE
или ALTER TABLE
. Табличные признаки
ROW_FORMAT
и KEY_BLOCK_SIZE
не часть синтаксиса
CREATE INDEX
для таблиц InnoDB
и проигнорированы, если они определены (хотя если определены, они появятся в
выводе SHOW CREATE TABLE
).Сжатые таблицы не могут быть сохранены в системное табличное пространство.
ROW_FORMAT
.InnoDB
не поддерживает сжатые временные таблицы. Когда
innodb_strict_mode
включен (значение по умолчанию),
CREATE TEMPORARY TABLE
возвращает ошибку, если указан ROW_FORMAT=COMPRESSED
или
KEY_BLOCK_SIZE
. Если
innodb_strict_mode
отключен, предупреждения выпущены, и временная таблица
составлена, используя несжатый формат строки. Те же самые ограничения
относятся к ALTER TABLE
на временных таблицах.Потому что эффективность сжатия зависит от природы Ваших данных, Вы можете принять решения, которые затрагивают исполнение сжатых таблиц:
Какие таблицы сжать.
Когда Вы готовы провести долгосрочное тестирование и поместить сжатые таблицы в производство см. раздел 16.9.1.4 для способов проверить эффективность выбора в условиях реального мира.
Вообще, сжатие работает лучше всего с таблицами, которые включают разумное число столбцов символьных строк и где данные считаны намного чаще, чем записаны. Поскольку нет никаких гарантируемых способов предсказать, приносит ли сжатие пользу в особой ситуации, всегда проверяйте с определенной рабочей нагрузкой и набором данных, работающим на представительной конфигурации. Рассмотрите следующие факторы, решая которые таблицы сжать.
Ключевой детерминант эффективности сжатия в сокращении размера файлов
с данными является природой данных. Вспомните, что сжатие работает,
идентифицируя повторные строки байтов в блоке данных. Полностью
рандомизированные данные худший случай. Типичные данные часто повторяют
значения, там сжатие эффективно. Строки символов часто сжимаются хорошо,
независимо от типа столбца CHAR
, VARCHAR
,
TEXT
или BLOB
. С другой стороны, таблицы,
содержащие главным образом двоичные данные (целые числа или числа с плавающей
запятой) или данные, которые ранее сжаты (например, изображения
JPEG или
PNG), возможно, не сжимаются хорошо,
значительно или вообще.
Вы выбираете, включить ли сжатие для каждой таблицы InnoDB. Таблица и весь индекс используют тот же самый (сжатый) размер страницы. Могло бы случиться так, что that the первичный ключ (кластеризируемый) индекс, который содержит данные для всех столбцов таблицы, сжимается эффективнее, чем вторичный индекс. Для тех случаев, где есть длинные строки, использование сжатия могло бы привести к длинным значениям столбцов, сохраненным вне страницы, как обсуждает раздел 16.10.3. Те страницы переполнения можно сжать хорошо. Для многих приложений некоторые таблицы сжимаются эффективнее, чем другие, и Вы могли бы найти, что Ваша рабочая нагрузка выступает лучше всего только с подмножеством сжатых таблиц.
Чтобы определить, сжать ли особую таблицу, проведите эксперименты.
Вы можете получить грубую оценку того, как эффективно Ваши данные могут быть
сжаты при использовании утилиты, которая осуществляет сжатие LZ77 (такой, как
gzip
или WinZip) на копии
файла .ibd
для несжатой таблицы. Вы можете ожидать, что будет меньше сжатия от MySQL для
таблицы, чем от основанных на файле инструментов сжатия, потому что MySQL
сжимает данные в кусках, основанных на
размере страницы, 16KB
по умолчанию. В дополнение к пользовательским данным формат страницы включает
некоторые внутренние системные данные, которые не сжаты. Основанные на файле
утилиты сжатия могут исследовать намного большие куски данных, и так найти
повторные строки в огромном файле, чем MySQL может
найти в отдельной странице.
Другой способ проверить сжатие на определенной таблице состоит в том,
чтобы скопировать некоторые данные от Вашей несжатой таблицы в подобную
сжатую таблицу (имеющую все те же индексы) в табличном пространстве
file-per-table
и смотреть на размер получающегося файла .ibd
:
use test; set global innodb_file_per_table=1; set global autocommit=0; -- Create an uncompressed table with a million or two rows. create table big_table as select * from information_schema.columns; insert into big_table select * from big_table; insert into big_table select * from big_table; insert into big_table select * from big_table; insert into big_table select * from big_table; insert into big_table select * from big_table; insert into big_table select * from big_table; insert into big_table select * from big_table; insert into big_table select * from big_table; insert into big_table select * from big_table; insert into big_table select * from big_table; commit; alter table big_table add id int unsigned not null primary key auto_increment; show create table big_table\G select count(id) from big_table; -- Check how much space is needed for the uncompressed table. \! ls -l data/test/big_table.ibd create table key_block_size_4 like big_table; alter table key_block_size_4 key_block_size=4 row_format=compressed; insert into key_block_size_4 select * from big_table; commit; -- Check how much space is needed for a compressed table -- with particular compression settings. \! ls -l data/test/key_block_size_4.ibd
Этот эксперимент произвел следующие числа, которые, конечно, могли значительно измениться в зависимости от Вашей структуры таблицы и данных:
-rw-rw---- 1 cirrus staff 310378496 Jan 9 13:44 data/test/big_table.ibd -rw-rw---- 1 cirrus staff 83886080 Jan 9 15:10 data/test/key_block_size_4.ibd
Чтобы понять, эффективно ли сжатие для Вашей особой рабочей нагрузки:
Для простых тестов, используйте
MySQL без других сжатых таблиц и выполните запросы для таблицы
INFORMATION_SCHEMA.INNODB_CMP
.
INFORMATION_SCHEMA.INNODB_CMP_PER_INDEX
.
Поскольку статистика в INNODB_CMP_PER_INDEX
дорого собирается,
Вы должны включить параметру конфигурации
innodb_cmp_per_index_enabled
прежде, чем запросить ту таблицу, и
Вы могли бы ограничить такое тестирование сервером развития или некритическим
ведомым сервером.
INFORMATION_SCHEMA.INNODB_CMP
или
INFORMATION_SCHEMA.INNODB_CMP_PER_INDEX
и сравнивая
COMPRESS_OPS
с COMPRESS_OPS_OK
.
innodb_compression_level
,
innodb_compression_failure_threshold_pct
и
innodb_compression_pad_pct_max
как описано в
разделе 16.9.1.6
и пробовать дальнейшие тесты.Решите, сжать ли данные в Вашем приложении или в таблице, не используйте оба типа сжатия для тех же самых данных. Когда Вы сжимаете данные в приложении и храните результаты в сжатой таблице, дополнительная экономия пространства крайне маловероятна, и двойное сжатие только тратит впустую циклы центрального процессора.
Когда включено, табличное сжатие MySQL является автоматическим и относится
ко всем столбцам. Столбцы могут все еще быть проверены с такими операторами,
как LIKE
, и операции сортировки могут все еще использовать
индекс, даже когда индексированные значения сжаты. Поскольку индекс часто
существенная фракция полного размера базы данных, сжатие могло привести к
существенной экономии в хранении, вводе/выводе или времени процессора.
Операции сжатия и декомпрессии происходят на сервере базы данных, который,
вероятно, является сильной системой, которая измерена, чтобы
обработать ожидаемую загрузку.
Если Вы сжимаете данные, такие как текст в Вашем приложении, прежде, чем это будет вставлено в базу данных, Вы могли бы сохранить заголовок для данных, которые не сжимаются хорошо, сжимая некоторые столбцы. Этот подход использует циклы центрального процессора для сжатия на машине клиента, а не сервере базы данных, который мог бы быть подходящим для распределенного приложения со многими клиентами, или где у машины клиента есть запасные циклы центрального процессора.
Конечно, возможно объединить эти подходы. Для некоторых приложений может быть уместно использовать некоторые сжатые таблицы и некоторые несжатые таблицы. Может быть лучшим внешне сжать некоторые данные (и сохранить в несжатых таблицах) и позволить MySQL сжимать другие таблицы приложения. Как всегда, грамотный проект и реальное тестирование ценны в достижении правильного решения.
В дополнение к выбору, какие таблицы сжать (и размер страницы),
рабочая нагрузка это другой ключевой детерминант работы. Если приложение
в основном читает, а не обновлено, меньше страниц должно быть реорганизовано
и повторно сжато после того, как индексная страница исчерпывает место для
страницы в журнале модификаций, который MySQL
поддерживает для сжатых данных. Если обновления преобладающе изменяют
неиндексированные столбцы или те, которые содержат BLOB
или
большие строки, которые сохранены вне страницы,
издержки сжатия могут быть приемлемыми. Если единственные изменения таблицы
INSERT
, которые используют монотонно увеличивающийся первичный
ключ, и есть немногие вторичные индексы, есть небольшая потребность
реорганизовать и повторно сжать индексные страницы. Так как MySQL может
помечать как удаленные и удалять строки на сжатых
страницах на месте, изменяя несжатые данные,
операцииDELETE
на таблице относительно эффективны.
Для некоторой окружающей среды время, чтобы загрузить данные, может быть столь же важным, как извлечение во время выполнения. Особенно в окружающей среде хранилища данных много таблиц могут быть только для чтения или чтения главным образом. В тех случаях это могло бы или не могло бы быть приемлемым заплатить цену сжатия с точки зрения увеличенного времени загрузки, если получающиеся сбережения в меньшем количестве дисковых чтений или в стоимости хранения не являются существенными.
Сжатие работает лучше всего, когда время центрального процессора доступно для сжатия и разсжатия данных. Таким образом, если Ваша рабочая нагрузка ввод/вывод, а не центральный процессор, сжатие может улучшить эффективность работы. Когда Вы проверяете потребительские свойства с различными конфигурациями сжатия, проверяйте на платформе, подобной запланированной конфигурации производственной системы.
Чтение и запись страниц базы данных с диска являются самым медленным аспектом работы. Сжатие пытается уменьшить ввод/вывод при использовании времени центрального процессора, чтобы сжать данные, и является самым эффективным, когда ввод/вывод относительно недостаточный ресурс по сравнению с циклами процессора.
Когда страница сжатой таблицы находится в памяти, MySQL часто использует дополнительную память, как правило 16 КБ, в буферном пуле для несжатой копии страницы. Адаптивный алгоритм LRU пытается сбалансировать использование памяти между сжатыми и несжатыми страницами, чтобы принять во внимание, работает ли рабочая нагрузка в манере I/O или CPU. Однако, конфигурация с большей памятью, посвященной буферному пулу, имеет тенденцию работать лучше, когда используется сжатие таблицы, чем конфигурация, где память чрезвычайно ограничена.
Оптимальная установка сжатого размера страницы зависит от типа и распределения данных, которые содержат индекс и таблица. Сжатый размер страницы должен всегда быть больше, чем максимальный размер записи, или операции могут потерпеть неудачу.
Устанавливая сжатый размер страницы слишком большим, затратите некоторое пространство, но страницы не должны быть сжаты часто. Если сжатый размер страницы установлен слишком маленьким, вставки или обновления могут потребовать отнимающего много времени пересжатия, и узлы B-tree, вероятно, придется разделять чаще, приводя к большим файлам с данными и менее эффективной индексации.
Как правило, Вы устанавливаете сжатый размер страницы в 8K или 4K.
Учитывая, что максимальный размер строки для таблицы InnoDB составляет
приблизительно 8K, KEY_BLOCK_SIZE=8
обычно безопасный выбор.
Полные потребительские свойства, центральный процессор и использование ввода/вывода и размер дисковых файлов это хорошие индикаторы того, как эффективно сжатие для Вашего приложения. Этот раздел основывается на совете из раздела 16.9.1.3 и показывает, как найти проблемы, которые не могли бы проявиться во время начального тестирования.
Вы можете контролировать работу сжатия во время выполнения, используя таблицы Information Schema , описанные в примере 16.10. Эти таблицы отражают внутреннее пользование памяти и уровни сжатия, используемого повсюду.
Таблица INNODB_CMP
сообщает о информацию о деятельности сжатия для каждого сжатого размера
страницы (KEY_BLOCK_SIZE
). Информация в этих таблицах в масштабе
всей системы: это суммирует статистику сжатия через все сжатые таблицы в
Вашей базе данных. Вы можете использовать эти данные, чтобы помочь решить,
сжать ли таблицу, исследуя эти таблицы, когда ни к каким другим сжатым
таблицам не получают доступ. Это вовлекает относительно низкие издержки
на сервере, таким образом, Вы могли бы периодически запрашивать это на
производственном сервере, чтобы проверить полную эффективность сжатия.
Таблица
INNODB_CMP_PER_INDEX
сообщает о информацию о деятельности сжатия
для отдельных таблиц и индексов. Эта информация предназначена и более полезна
для того, чтобы оценить эффективность сжатия и диагностировать исполнительные
проблемы одной таблицы или индекса за один раз.
Поскольку каждая таблица представлена как кластеризируемый индекс, MySQL
не делает большое различие между таблицами и индексами в этом контексте.
Таблица
INNODB_CMP_PER_INDEX
действительно вовлекает существенные
издержки, таким образом, это является более подходящим для серверов развития,
где Вы можете сравнить эффекты различных
рабочих нагрузок,
данных и настроек сжатия в изоляции. Чтобы принять меры против наложения
этого контроля на издержки, Вы должны включить опцию
innodb_cmp_per_index_enabled
прежде, чем Вы сможете запросить
таблицу
INNODB_CMP_PER_INDEX
.
Ключевые статистические данные являются числом, и количеством времени
на выполнение сжатия. Так как MySQL разделяет узлы
B-tree, когда они слишком полны,
чтобы содержать сжатые данные после модификации, сравните число
успешных операций сжатия с числом таких операций
вообще. Основываясь на информации в таблицах
INNODB_CMP
и
INNODB_CMP_PER_INDEX
, Вы могли бы произвести изменения в своей конфигурации аппаратных
средств, скорректировать размер буферного пула, выбрать иной размер страницы
или выбрать набор таблиц, чтобы сжать.
Если количество времени центрального процессора, требуемого для сжатия высоко, изменение на быстрый центральный процессор может помочь улучшить работу с теми же самыми данными, рабочую нагрузку приложения и набор сжатых таблиц. Увеличение размера буферного пула могло бы также помочь работе, так, чтобы несжатые страницы могли остаться в памяти, уменьшая потребность разсжимать страницы, которые существуют в памяти только в сжатой форме.
Большое количество операций сжатия (по сравнению с числом
INSERT
, UPDATE
и DELETE
в Вашем приложении и размером базы данных), может указать, что некоторые из
Ваших сжатых таблиц обновляются слишком сильно для эффективного сжатия.
Если это так, выберите больший размер страницы или разберитесь,
которые таблицы Вы сжимаете.
Если число успешных операций сжатия
(COMPRESS_OPS_OK
) выше процента общего количества операций
сжатия (COMPRESS_OPS
), тогда система, вероятно, работает хорошо.
Если отношение низко, то MySQL реорганизует, пересжимает и разделяет узлы
B-tree чаще, чем желательно. В этом случае избегайте сжимать некоторые
таблицы или увеличьте KEY_BLOCK_SIZE
для некоторых из сжатых
таблиц. Вы могли бы выключить сжатие для таблиц, которые заставляют число
неудачных сжатий в Вашем приложении составлять
больше 1%-2%. Такое отношение отказа могло бы быть приемлемым во время
временной работы, такой как загрузка данных.
Этот раздел описывает некоторые внутренние детали выполнения сжатия для таблиц InnoDB. Информация, представленная здесь, может быть полезной в настройке для работы, но не необходима, чтобы знать для основного использования сжатия.
Некоторые операционные системы осуществляют сжатие на уровне файловой системы. Файлы, как правило, делятся на блоки фиксированного размера, которые сжаты в блоки переменного размера, который легко приводит к фрагментации. Каждый раз, когда что-то в блоке изменено, целый блок повторно сжат прежде, чем он будет записан на диск. Эти свойства делают этот метод сжатия неподходящим для использования в интенсивной обновляемой системе базы данных.
MySQL осуществляет сжатие с помощью известной библиотеки zlib, которая осуществляет алгоритм сжатия LZ77. Этот алгоритм сжатия является зрелым, здравым и эффективным в использовании центрального процессора и в сокращении размера данных. Алгоритм без потерь, чтобы оригинальные несжатые данные могли всегда быть восстановлены от сжатой формы. Сжатие LZ77 работает, находя последовательности данных, которые повторены в пределах данных, которые будут сжаты. Образцы значений в Ваших данных определяют, как хорошо они сжимаются, но типичные пользовательские данные часто сжимаются на 50% или даже лучше.
В отличие от сжатия, выполненного приложением или особенностями сжатия
некоторых других систем управления базой данных, сжатие InnoDB применяется к
пользовательским данным и индексам. Во многих случаях индекс
может составить 40-50% полного размера базы данных, таким образом, это
различие является существенным. Когда сжатие работает хорошо на наборе
данных, размер файлов с данными InnoDB (табличное пространство
file-per-table
общее табличное пространство
файлы .idb
) ужимает на 25%-50%. В зависимости от
рабочей нагрузки,
эта меньшая база данных может в свою очередь привести к сокращению
ввода/вывода и увеличению пропускной способности по скромной стоимости с
точки зрения увеличенного использования центрального процессора.
Вы можете скорректировать баланс между уровнем сжатия и нагрузкой на
центральный процессор, изменяя параметр
innodb_compression_level
.
Все пользовательские данные в таблицах InnoDB хранятся в страницах, включающих индекс B-tree (кластеризируемый индекс). В некоторых других системах базы данных этот тип индекса назван index-organized table. Каждая строка в индексном узле содержит значение (определенное пользователем или произведенное системой) первичного ключа и все другие столбцы таблицы.
Вторичные индексы в InnoDB также B-tree, содержащие пары значений: ключ индекса и указатель на строку в кластеризируемом индексе. Указатель фактически значение первичного ключа таблицы, который используется, чтобы получить доступ к кластеризируемому индексу, если столбцы кроме индексного ключа и первичного ключа требуются. Вторичный индекс должен всегда соответствовать на единственной странице B-дерева.
Сжатие узлов B-дерева (кластеризируемого и вторичного индексов)
обработано отлично от сжатия
страниц переполнения,
используемых, чтобы хранить столбцы VARCHAR
, BLOB
или TEXT
, как объяснено в следующих разделах.
Поскольку они часто обновляются, страницы B-дерева требуют специального режима. Важно минимизировать число раз разделения узлов B-дерева, так же как минимизировать потребность разсжать и повторно сжать их контент.
Один метод, который использует MySQL, должен поддержать некоторую информацию о системе в узле B-дерева в несжатой форме, таким образом облегчая определенные оперативные обновления. Например, это позволяет строкам быть отмеченными для удаления и удаленными без любой работы подсистемы сжатия.
Кроме того, MySQL пытается избежать ненужного и пересжатия индексных страниц, когда они изменены. В пределах каждой страницы B-дерева система сохраняет несжатый журнал изменений, чтобы сделать запись изменений, произведенных в странице. Обновления и вставки небольших записей могут быть записаны в этот журнал модификации не требуя, чтобы вся страница была полностью восстановлена.
Когда пространство для журнала модификации заканчивается, InnoDB разжимает страницу, применяет изменения и повторно сжимает страницу. Если пересжатие терпит неудачу (ситуация, известная как отказ сжатия), узлы B-дерева разделены, и процесс повторен до успеха.
Чтобы избежать частых отказов сжатия в интенсивных по записи
рабочих нагрузках, что касается приложений
OLTP, MySQL иногда резервирует некоторое пустое место (дополнение) в
странице, чтобы журнал модификации заполнился скорее, и страница повторно
сжата, в то время как есть все еще достаточно места, чтобы избежать
разделения. Количество дополнения пространства, оставленного в каждой
странице, изменяется, поскольку система отслеживает частоту разделений
страницы. На занятом сервере, делающем частые записи
сжатых таблиц, Вы можете корректировать опции
innodb_compression_failure_threshold_pct
и
innodb_compression_pad_pct_max
и точно настроить этот механизм.
Вообще, MySQL требует, чтобы каждая страница B-дерева в таблице InnoDB
могла вместить по крайней мере две записи. Для сжатых таблиц было смягчено
это требование. Страницы листа узлов B-дерева
(из первичного ключа или вторичного) должны вмещать только одну запись, но
что она должна заполниться, в несжатой форме, в журнале модификации для
страницы. Если
innodb_strict_mode
ON
, MySQL
проверяет максимальный размер строки во время
CREATE TABLE
или
CREATE INDEX
.
Если строка не соответствует, следующее сообщение об ошибке выпущено:
ERROR HY000: Too big row
.
Если Вы составляете таблицу, когда
innodb_strict_mode
OFF, и последующий INSERT
или UPDATE
пытается создать индексную запись, которая не помещается в размер сжатой
страницы, работа терпит неудачу с ERROR 42000: Row size too large
. Это сообщение об ошибке не называет индекс, для которого запись
является слишком большой, или упоминает длину индексной записи или
максимального размера записи на этой индексной странице.
Чтобы решить эту проблему, пересоздайте таблицу с помощью
ALTER TABLE
и выберите больший сжатый размер страницы (KEY_BLOCK_SIZE
),
сократите префикс столбца индекса или отключите сжатие полностью с
ROW_FORMAT=DYNAMIC
или ROW_FORMAT=COMPACT
.
innodb_strict_mode
не применимо к общим табличным пространствам, которые также
поддерживают сжатые таблицы. Управленческие правила табличного пространства
для общих табличных пространств строго проведены в жизнь, независимо от
innodb_strict_mode
. Подробности в разделе
14.1.16.
В таблице столбцы BLOB
,
VARCHAR
и
TEXT
, которые не являются частью
первичного ключа, могут быть сохранены на отдельно выделенных
страницах переполнения.
Мы именуем эти столбцы
столбцы вне страницы. Их
значения сохранены в отдельно-связанных списках страниц переполнения.
Для таблиц, составленных с ROW_FORMAT=DYNAMIC
или
ROW_FORMAT=COMPRESSED
, значения
BLOB
,
TEXT
или
VARCHAR
могут быть сохранены
полностью вне страницы, в зависимости от их длины и длины всей строки. Для
столбцов, которые сохранены вне страницы, кластеризируемые индексные записи
содержит только 20-байтовые указатели на страницы переполнения, один на
столбец. Сохранены ли какие-либо столбцы вне страницы, зависит от размера
страницы и полного размера строки. Когда строка является слишком длинной,
чтобы поместиться полностью в пределах страницы кластеризируемого индекса,
MySQL выбирает самые длинные столбцы для хранения вне страницы на
кластеризируемой индексной странице. Как отмечено выше, если строка не
помещается отдельно на сжатой странице, происходит ошибка.
Для таблиц, составленных в ROW_FORMAT=DYNAMIC
или
ROW_FORMAT=COMPRESSED
, столбцы
TEXT
и
BLOB
, которые меньше или равны 40
байтам, всегда сохранены местно.
Таблицы с ROW_FORMAT=REDUNDANT
и
ROW_FORMAT=COMPACT
сохраняют первые 768 байтов
столбцов BLOB
,
VARCHAR
и
TEXT
в кластеризируемой индексной
записи наряду с первичным ключом. 768-байтовая приставка сопровождается
20-байтовым указателем на страницы переполнения, которые содержат остальную
часть значения столбца.
Когда таблица находится в формате COMPRESSED
,
все данные, написанные на страницу переполнения, сжаты как есть
, то есть, MySQL применяет алгоритм сжатия zlib ко всему
элементу данных. Кроме данных, сжатые страницы переполнения содержат несжатый
заголовок и метку конца, включающую контрольную сумму страницы и ссылку на
следующую страницу переполнения. Поэтому, очень существенная экономия
хранения может быть получена для больших BLOB
, TEXT
или VARCHAR
, если данные очень сжимаемы, как это часто бывает с
текстовыми данными. Данные изображений (к примеру, JPEG
),
как правило, уже сжаты и не извлекают выгоду из сохранения в сжатой таблице,
двойное сжатие может потратить впустую циклы центрального процессора для
небольшой или никакой экономии пространства.
Страницы переполнения имеют тот же самый размер, как другие страницы. Строка, содержащая десять столбцов, сохраненная вне страницы, занимает десять страниц переполнения, даже если полная длина столбцов составляет только 8K. В несжатой таблице десять несжатых страниц переполнения занимают 160K. В сжатой таблице с размером страницы 8K они занимают только 80K. Таким образом, часто более эффективно использовать сжатый формат таблицы для таблиц с длинными значениями столбцов.
Для табличных пространств
file-per-table, используя размера сжатой страницы 16K,
можно уменьшить затраты ввода/вывода для
BLOB
,
VARCHAR
или
TEXT
, потому что такие данные часто
сжимаются хорошо, и могли бы поэтому потребовать меньшего количества страниц
переполнения, даже при том, что узлы самого B-дерева берут так много страниц
в несжатой форме. Общие табличные пространства не поддерживают
размер сжатой страницы 16K (KEY_BLOCK_SIZE
). Подробности в
разделе 16.7.9.
В сжатой таблице каждая сжатая страница соответствует несжатой странице
16K (или меньшего размера, если
innodb_page_size
задана). Чтобы получить доступ к данным в
странице, MySQL читает сжатую страницу с диска, если это еще не находится в
буферном пуле,
затем разсжимает страницу к оригинальной форме. Этот раздел описывает, как
InnoDB
управляет буферным пулом относительно
страниц сжатых таблиц.
Чтобы минимизировать ввод/вывод и уменьшить потребность расжимать страницу, буферный пул содержит сжатую и несжатую форму страницы базы данных. Чтобы создать место для других необходимых страниц базы данных, MySQL может вычеркнуть из буферного пула несжатую страницу, оставляя сжатую страницу в памяти. Или, если к странице не получили доступ некоторое время, сжатая форма страницы могла бы быть записана на диск, освобождая пространство для других данных. Таким образом, в любой момент времени буферный пул мог бы содержать сжатые и несжатые формы страницы, только сжатую форму страницы, или ни одной.
MySQL отслеживает, какие страницы хранятся в памяти, а какие можно вычеркнуть с применением алгоритма (LRU), чтобы горячие (часто используемые) данные имели тенденцию оставаться в памяти. Когда к сжатым таблицам получают доступ, MySQL использует адаптивный алгоритм LRU, чтобы достигнуть соответствующего баланса сжатых и несжатых страниц в памяти. Этот адаптивный алгоритм чувствителен к тому, работает ли система в нагрузке I/O-bound или CPU-bound. Цель состоит в том, чтобы избежать тратить слишком много времени обработки на распаковку страниц, когда центральный процессор занят, и избегать делать лишний ввод/вывод, когда у центрального процессора есть запасные циклы, которые могут использоваться для того, чтобы разсжать сжатые страницы (которые могут уже быть в памяти). Когда система I/O-bound, алгоритм предпочитает вычеркивать несжатую копию страницы, а не обе копии, делать больше места для других дисковых страниц. Когда система лимитирована центральным процессором, MySQL предпочитает вычеркивать сжатую и несжатую страницу, чтобы больше памяти могло использоваться для горячих страниц.
Прежде, чем сжатая страница записана в
файл с данными, MySQL пишет
копию страницы в redo-журнал (если это было повторно сжато с прошлого раза,
это было записано в базе данных). Это сделано, чтобы гарантировать, что
журналы, применимы для
восстановления катастрофического отказа, даже в маловероятном случае что
библиотека zlib
обновлена, и это изменение начинает проблему
совместимости со сжатием данных. Поэтому, некоторое увеличение размера
файлов системного журнала
или потребность в более частых
контрольных точках может ожидаться, используя сжатие. Количество
увеличения размера файла системного журнала или частоты контрольной точки
зависит от числа изменений сжатых страниц.
Чтобы создать сжатую таблицу в табличном пространстве
innodb_file_per_table
должен быть включен. Нет никакой зависимости
от
innodb_file_per_table
, составляя сжатую таблицу в общем табличном
пространстве. Для получения дополнительной информации см.
раздел 16.7.9.
Традиционно сжатие
рекомендовалась прежде всего для рабочих нагрузок только для чтения,
например, для хранилища данных
. Распространение устройств хранения данных
SSD, которые являются быстрыми, но
относительно маленькими и дорогими, делает сжатие привлекательным также для
OLTP
: высокий трафик, интерактивные веб-сайты могут уменьшить
свои требования хранения и свои операции в секунду ввода/вывода
(IOPS) при использовании сжатых таблиц
с приложениями, которые действительно часто используют
INSERT
,
UPDATE
и
DELETE
.
Эти параметры конфигурации позволяют Вам корректировать способ, которым сжатие работает с акцентом на работу и масштабируемость для разных действий:
innodb_compression_level
позволяет Вам менять степень сжатия или вниз. Более высокое значение
позволяет Вам вместить большее количество данных на устройство хранения,
за счет большего количества времени центрального процессора во время сжатия.
Нижнее значение позволяет Вам уменьшать загрузку центрального процессора,
когда место для хранения не будет важно, или Вы ожидаете, что данные
не особенно сжимаемы.
innodb_compression_failure_threshold_pct
определяет предел
для отказов сжатия
во время обновлений сжатой таблицы. Когда этот порог превышен, MySQL
начинает оставлять дополнительное свободное пространство в пределах каждой
новой сжатой страницы, динамически корректируя количество свободного
пространства до процента размера страницы, определенного
innodb_compression_pad_pct_max
.
innodb_compression_pad_pct_max
позволяет Вам корректировать максимальное количество пространства,
сохраненного в пределах каждой страницы
, чтобы сделать запись изменений сжатых строк, не пережимая всю страницу
снова. Чем выше значение, тем больше изменений может быть зарегистрировано,
не сжимая повторно страницу. MySQL использует переменное количество
свободного пространства для страниц в пределах каждой сжатой таблицы, только
когда определяемый процент операций сжатия сбоит во время выполнения, требуя,
разделить сжатую страницу.
innodb_log_compressed_pages
позволяет Вам отключать запись образов
пересжатых страниц
журнал redo.
Пересжатие может произойти, когда изменения произведены в сжатых данных. Эта
опция включена по умолчанию, чтобы предотвратить повреждение, которое могло
произойти, если иная версия zlib
используется во время
восстановления. Если Вы уверены, что версия zlib
не будет изменяться, отключите
innodb_log_compressed_pages
, чтобы уменьшить журнал
redo для рабочих нагрузок, которые изменяют сжатые данные.Поскольку работа со сжатыми данными иногда вовлекает хранение сжатых и
несжатых версий страницы в памяти в то же самое время, используя сжатие с
рабочей нагрузкой OLTP-стиля, будьте готовы увеличить значение опции
innodb_buffer_pool_size
.
Этот раздел описывает предупреждения и ошибки, с которыми Вы можете столкнуться, используя табличную функцию сжатия с табличными пространствами file-per-table и общими табличными пространствами.
Когда
innodb_strict_mode
включен (значение по умолчанию), определение
ROW_FORMAT=COMPRESSED
или
KEY_BLOCK_SIZE
в CREATE
TABLE
или ALTER TABLE
производит следующую ошибку, если
innodb_file_per_table
отключен.
ERROR 1031 (HY000): Table storage engine for 't1' doesn't have this option
Таблица не составлена, если текущая конфигурация не разрешает использовать сжатые таблицы.
Когда
innodb_strict_mode
отключен, определение
ROW_FORMAT=COMPRESSED
или
KEY_BLOCK_SIZE
в CREATE
TABLE
или ALTER TABLE
производят следующие предупреждения, если
innodb_file_per_table
отключен.
mysql> SHOW WARNINGS; +---------+------+---------------------------------------------------------------+ | Level | Code | Message | +---------+------+---------------------------------------------------------------+ | Warning | 1478 | InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. | | Warning | 1478 | InnoDB: ignoring KEY_BLOCK_SIZE=4. | | Warning | 1478 | InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. | | Warning | 1478 | InnoDB: assuming ROW_FORMAT=DYNAMIC. | +---------+------+---------------------------------------------------------------+
Эти сообщения только предупреждения, не ошибки, и таблица составлена без сжатия, как будто опции не были определены.
Поведение non-strict
позволяет Вам импортировать файл mysqldump
в базу данных, которая не поддерживает сжатые таблицы, даже если исходная
база данных содержала сжатые таблицы. В этом случае MySQL составляет таблицу
в ROW_FORMAT=DYNAMIC
.
Чтобы импортировать файл дампа в новую базу данных и обновить таблицы,
поскольку они существуют в оригинальной базе данных, гарантируюйте, что у
сервера есть надлежащая установка для
innodb_file_per_table
.
Признак KEY_BLOCK_SIZE
разрешен только, когда
ROW_FORMAT
определен как COMPRESSED
или опущен. Определение KEY_BLOCK_SIZE
с любым другим
ROW_FORMAT
производит предупреждение, которое Вы можете
рассмотреть с SHOW WARNINGS
. Однако, таблица несжата: указанное
KEY_BLOCK_SIZE
проигнорировано).
Уровень | Code | Сообщение |
---|---|---|
Предупреждение | 1478 | InnoDB: ignoring KEY_BLOCK_SIZE= |
Если Вы работаете с
innodb_strict_mode
, комбинация KEY_BLOCK_SIZE
с любым ROW_FORMAT
, кроме COMPRESSED
,
производит ошибку, а не предупреждение, и таблица не составлена.
Таблица 16.6 обеспечивает краткий обзор опций ROW_FORMAT
и
KEY_BLOCK_SIZE
, которые используются с
CREATE TABLE
или
ALTER TABLE
.
Table 16.6. Опции ROW_FORMAT и KEY_BLOCK_SIZE
Опция | Как использовать | Описание |
---|---|---|
ROW_FORMAT=REDUNDANT | Формат хранения, используемый до MySQL 5.0.3 | Менее эффективный, чем
ROW_FORMAT=COMPACT , для обратной совместимости. |
ROW_FORMAT=COMPACT | Формат хранения по умолчанию, начиная с MySQL 5.0.3 | Хранит префикс 768 байтов длинных значений столбцов в кластеризируемой индексной странице, с остающимися байтами, сохраненными в странице переполнения. |
ROW_FORMAT=DYNAMIC | Храните значения в пределах кластеризируемой индексной страницы, если они там поместятся, в противном случае хранит только 20-байтовый указатель на страницу переполнения (никакого префикса). | |
ROW_FORMAT=COMPRESSED | Сжимает таблицу и индексы с использованием zlib. | |
KEY_BLOCK_SIZE= | Определяет сжатый размер страницы 1, 2, 4, 8 или 16 килобайтов,
подразумевает ROW_FORMAT=COMPRESSED . Для общих табличных
пространств KEY_BLOCK_SIZE равный размеру страницы не разрешен.
|
Таблица 16.7 суммирует состояния ошибки, которые происходят с
определенными комбинациями параметров конфигурации и опций в
CREATE TABLE
или
ALTER TABLE
и то, как опции появляются в выводе SHOW TABLE STATUS
.
Когда
innodb_strict_mode
OFF
, MySQL
создает или изменяет таблицу, но игнорирует определенные настройки как
показано ниже. Вы можете видеть предупреждающие сообщения в журнале ошибок
MySQL. Когда
innodb_strict_mode
ON
, эти указанные комбинации опций
производят ошибки, и таблица не составлена или изменена. Чтобы видеть полное
описание состояния ошибки, скомандуйте SHOW ERRORS
:
mysql> CREATE TABLE x (id INT PRIMARY KEY, c INT) -> ENGINE=INNODB KEY_BLOCK_SIZE=33333; ERROR 1005 (HY000): Can't create table 'test.x' (errno: 1478) mysql> SHOW ERRORS; +-------+------+-------------------------------------------+ | Level | Code | Message | +-------+------+-------------------------------------------+ | Error | 1478 | InnoDB: invalid KEY_BLOCK_SIZE=33333. | | Error | 1005 | Can't create table 'test.x' (errno: 1478) | +-------+------+-------------------------------------------+
Таблица 16.7. Предупреждения и ошибки CREATE/ALTER TABLE, когда InnoDB Strict Mode OFF
Синтаксис | Предупреждение или состояние ошибки | Результирующий ROW_FORMAT , как показано в
SHOW TABLE STATUS |
---|---|---|
ROW_FORMAT=REDUNDANT | Нет | REDUNDANT |
ROW_FORMAT=COMPACT | Нет | COMPACT
|
ROW_FORMAT=COMPRESSED , ROW_FORMAT=DYNAMIC
или KEY_BLOCK_SIZE указан | Проигнорирован для табличных
пространств file-per-table, если включена
innodb_file_per_table
. Общие табличные пространства поддерживают все форматы строки.
См. раздел 16.7.9. |
Формат строки по умолчанию для file-per-table, указанный формат
строки для общего табличного пространства |
Неправильный KEY_BLOCK_SIZE (не 1, 2, 4, 8 или 16) |
KEY_BLOCK_SIZE пропущен | Указанный формат строки или формат строки по умолчанию |
ROW_FORMAT=COMPRESSED и допустимый
KEY_BLOCK_SIZE определены | Нет, используется определенный
KEY_BLOCK_SIZE | COMPRESSED |
KEY_BLOCK_SIZE определен с форматом строки
REDUNDANT , COMPACT или DYNAMIC |
KEY_BLOCK_SIZE пропущен | REDUNDANT ,
COMPACT или DYNAMIC |
ROW_FORMAT не REDUNDANT ,
COMPACT , DYNAMIC или COMPRESSED |
Проигнорирован, если признан анализатором MySQL. Иначе ошибка. | Формат строки значения по умолчанию или N/A |
Когда innodb_strict_mode
ON
, MySQL
отклоняет недопустимый ROW_FORMAT
или
KEY_BLOCK_SIZE
и выдает ошибку. Строгий режим
ON
по умолчанию. Когда innodb_strict_mode
OFF
, MySQL выдает предупреждения вместо ошибок для
проигнорированных недопустимых параметров.
Невозможно видеть выбранный KEY_BLOCK_SIZE
через
SHOW TABLE STATUS
. SHOW CREATE TABLE
покажет
KEY_BLOCK_SIZE
(даже если это было проигнорировано, составляя
таблицу). Реальный сжатый размер страницы таблицы не может быть выведен
на экран MySQL.
Если FILE_BLOCK_SIZE
не был определен для общего
табличного пространства, когда табличное пространство создавалось, табличное
пространство не может содержать сжатые таблицы. Если Вы пытаетесь добавить
сжатую таблицу, ошибка возвращена, как показано в следующем примере:
mysql> CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; ERROR 1478 (HY000): InnoDB: Tablespace `ts1` cannot contain a COMPRESSED table
KEY_BLOCK_SIZE
к общему табличному пространству возвращает ошибку, как
показано в следующем примере:
mysql> CREATE TABLESPACE `ts2` ADD DATAFILE 'ts2.ibd' FILE_BLOCK_SIZE = 8192 Engine=InnoDB; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE t2 (c1 INT PRIMARY KEY) TABLESPACE ts2 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; ERROR 1478 (HY000): InnoDB: Tablespace `ts2` uses block size 8192 and cannot contain a table with physical page size 4096
Для общих табличных пространств KEY_BLOCK_SIZE
из таблицы должно быть равным FILE_BLOCK_SIZE
из табличного пространства, разделенного на 1024. Например, если
FILE_BLOCK_SIZE
8192, то KEY_BLOCK_SIZE
8.
mysql> CREATE TABLESPACE `ts3` ADD DATAFILE 'ts3.ibd' FILE_BLOCK_SIZE = 8192 Engine=InnoDB; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE t3 (c1 INT PRIMARY KEY) TABLESPACE ts3 ROW_FORMAT=COMPACT; ERROR 1478 (HY000): InnoDB: Tablespace `ts3` uses block size 8192 and cannot contain a table with physical page size 16384
innodb_strict_mode
не применимо к общим табличным пространствам. Управленческие
правила табличного пространства для общих табличных пространств строго
проведены в жизнь независимо от
innodb_strict_mode
. Подробности в разделе
14.1.16.
InnoDB
поддерживает сжатие на уровне страницы для таблиц,
которые находятся в табличных пространствах
file-per-table. Эта
особенность упоминается как Прозрачное сжатие страницы.
Сжатие страницы включено, определяя COMPRESSION
в
CREATE TABLE
или
ALTER TABLE
. Поддержанные
алгоритмы сжатия включают Zlib
и LZ4
.
Сжатие страницы поддержано на Windows с NTFS, и на следующем подмножестве MySQL-поддержанных платформ Linux, где уровень ядра оказывает поддержку hole punching:
RHEL 7 и полученные дистрибутивы, которые используют версию ядра 3.10.0-123 или выше.
Все доступные файловые системы для данного дистрибутива Linux, возможно, не поддерживают hole punching.
Когда страница написана, она сжата, используя указанный алгоритм сжатия. Если сжатие терпит неудачу, данные записаны как есть.
В Linux размер блока файловой системы это
размер модуля, используемый для hole punching. Поэтому сжатие страницы
работает только, если данные о странице могут быть сжаты к размеру, который
меньше или равен размеру страницы минус размер блока файловой системы.
Например, если
innodb_page_size=16K
и размер блока файловой системы составляет
4K, данные о странице должны в сжатом виде быть меньше или равны 12K.
В Windows основная инфраструктура для sparse-файлов основана на сжатии NTFS. Размер Hole punching это модуль сжатия NTFS, который в 16 раз больше размером кластера NTFS. Размеры кластера и их модули сжатия показаны в следующей таблице:
Таблица 16.8. Размер кластера и модули сжатия NTFS
Размер кластера | Модуль сжатия |
---|---|
512 байт | 8 KB |
1 KB | 16 KB |
2 KB | 32 KB |
4 KB | 64 KB |
Сжатие страницы на системах Windows работает, если данные о странице могут быть сжаты к размеру, который меньше или равен размеру страницы минус размер модуля сжатия.
Размер кластера NTFS по умолчанию составляет 4K,
для которого размер модуля сжатия составляет 64K.
Это означает, что сжатие страницы не обладает никаким преимуществом для
Windows NTFS, поскольку максимум
innodb_page_size
64K.
Для сжатия страницы под Windows файловая система должна быть создана с
размером кластера меньше 4K, и
innodb_page_size
должен быть, по крайней мере, двойным размером модуля сжатия. Например,
для сжатия страницы в Windows Вы могли создать файловую систему с размером
кластера 512 байтов (у которого есть модуль сжатия 8 КБ) и инициализировать
InnoDB
с
innodb_page_size
16K или больше.
Чтобы включить сжатие страницы, определите атрибут
COMPRESSION
в CREATE TABLE
:
CREATE TABLE t1 (c1 INT) COMPRESSION="zlib";
Вы можете также включить сжатие страницы в
ALTER TABLE
. Но
ALTER TABLE ... COMPRESSION
только обновляет признак сжатия табличного пространства.
Записи в табличное пространство, которые происходят после установки нового
алгоритма сжатия, используют новую установку, но чтобы применять новый
алгоритм сжатия к существующим страницам, Вы должны пересоздать таблицу с
использованием OPTIMIZE TABLE
.
ALTER TABLE t1 COMPRESSION="zlib"; OPTIMIZE TABLE t1;
Чтобы отключить сжатие страницы, установите COMPRESSION=None
через ALTER TABLE
.
Записи в табличное пространство, которые происходят после установки
COMPRESSION=None
, больше не используют сжатие страницы. Чтобы
распаковать существующие страницы, Вы должны пересоздать таблицу с
использованием OPTIMIZE TABLE
после установки COMPRESSION=None
.
ALTER TABLE t1 COMPRESSION="None"; OPTIMIZE TABLE t1;
Метаданные о сжатии страницы найдены в таблице
INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES
в следующих столбцах:
FS_BLOCK_SIZE
: Размер блока файловой системы, который
является размером модуля, используемым для hole punching.
FILE_SIZE
: Размер файла, который представляет максимальный
размер несжатого файла.ALLOCATED_SIZE
: Фактический размер файла, который является
количеством места, выделенного на диске.Примените SHOW CREATE TABLE
, чтобы смотреть текущую установку сжатия страницы
(Zlib
, Lz4
или None
). Таблица может
содержать соединение страниц с различными настройками сжатия.
В следующем примере метаданные о сжатии страницы для таблицы служащих
получены от
INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES
.
# Create the employees table with Zlib page compression CREATE TABLE employees (emp_no INT NOT NULL, birth_date DATE NOT NULL, first_name VARCHAR(14) NOT NULL, last_name VARCHAR(16) NOT NULL, gender ENUM ('M','F') NOT NULL, hire_date DATE NOT NULL, PRIMARY KEY (emp_no)) COMPRESSION="zlib"; # Insert data (not shown) # Query page compression metadata in INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES mysql> SELECT SPACE, NAME, FS_BLOCK_SIZE, FILE_SIZE, ALLOCATED_SIZE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE NAME='employees/employees'\G *************************** 1. row *************************** SPACE: 45 NAME: employees/employees FS_BLOCK_SIZE: 4096 FILE_SIZE: 23068672 ALLOCATED_SIZE: 19415040
Метаданные о сжатии страницы для таблицы служащих показывают, что очевидный размер файла составляет 23068672 байта, в то время как фактический размер файла (со сжатием страницы) составляет 19415040 байт. Размер блока файловой системы составляет 4096 байтов, что является размером блока, используемым для hole punching.
Сжатие страницы отключено, если размер блока файловой системы (или
размер модуля сжатия в Windows) * 2 >
innodb_page_size
.
ROW_FORMAT=COMPRESSED
) оставлены как есть.ALTER TABLE ... COMPRESSION=None
и OPTIMIZE TABLE
.InnoDB
64 КБ с размером блока файловой системы 4 КБ может
улучшить сжатие, но может также увеличить требование к буферному пулу,
приводя к увеличенному вводу/выводу.Этот раздел обсуждает InnoDB, такие как табличное
сжатие, хранение вне страницы
длинных значений столбцов переменной длины и большой индексный ключевой
префикс, контролируемые форматом строки таблицы InnoDB
.
Это также обсуждает соображения о том, как выбрать правильный формат строки
и совместимость форматов строки между выпусками MySQL.
Хранение для строк и связанных столбцов затрагивает работу для запросов и операций DML. Поскольку больше строк вписывается в единственную дисковую disk страницу, запросы и индексные поиски могут работать быстрее, меньше кэш-памяти требуется в буферном пуле InnoDB и меньше ввода/вывода нужно, чтобы записывать обновленные значения для числовых и коротких строковых столбцов.
Данные в каждой таблице InnoDB разделены на страницы. Страницы, которые составляют каждую таблицу, расположены в структуре данных дерева, названной индекс B-tree. Табличные данные и вторичные индексы применяют этот тип структуры. Индекс B-tree, который представляет всю таблицу, известен как кластеризируемый индекс, который организован согласно столбцам первичного ключа. Узлы индексной структуры данных содержат значения всех столбцов в той строке (для кластеризируемого индекса) или индексные столбцы и столбцы первичного ключа (для вторичного индекса).
Столбцы переменной длины исключение из этого правила. Столбцы
BLOB
и VARCHAR
слишком длинные, чтобы поместиться
на странице B-дерева, сохранены на отдельно выделенных дисковых страницах,
названных страницами переполнения
. Мы называем такие столбцы
столбцами вне страницы. Значения этих столбцов сохранены в
отдельно-связанных списках страниц переполнения, и у каждого такого столбца
есть свой собственный список из одной или более страниц переполнения. В
некоторых случаях префикс длинного значения столбца сохранен в B-дереве,
чтобы избежать тратить впустую место и избавиться от необходимости
читать отдельную страницу.
Следующие разделы описывают, как сконфигурировать формат строки таблицы, чтобы управлять, как сохранены значения столбцов переменной длины. Конфигурация формата строки также решает доступность табличного сжатия и поддержки больших префиксов индексных ключей.
Формат строки по умолчанию определен параметром
innodb_default_row_format
, у которого есть значение по умолчанию
DYNAMIC
. Формат строки по умолчанию используется, когда
табличная опция ROW_FORMAT
не определена явно, или когда
определено ROW_FORMAT=DEFAULT
.
Формат строки таблицы может быть определен явно, используя
табличную опцию ROW_FORMAT
в
CREATE TABLE
или
ALTER TABLE
:
CREATE TABLE t1 (c1 INT) ROW_FORMAT=DYNAMIC;
Явно определенный ROW_FORMAT
переопределяет неявное значение по умолчанию. Определение
ROW_FORMAT=DEFAULT
эквивалентно использованию неявного
значения по умолчанию.
Опция
innodb_default_row_format
может быть установлена динамически:
mysql> SET GLOBAL innodb_default_row_format=DYNAMIC;
Допустимые значения
innodb_default_row_format
включают DYNAMIC
,
COMPACT
и REDUNDANT
. Формат строки
COMPRESSED
, который не поддержан для использования в системном
табличном пространстве, не может быть определен как значение по умолчанию.
Это может быть определено только явно в
CREATE TABLE
или
ALTER TABLE
. Попытка
установить
innodb_default_row_format
в COMPRESSED
возвращает эту ошибку:
mysql> SET GLOBAL innodb_default_row_format=COMPRESSED; ERROR 1231 (42000): Variable 'innodb_default_row_format' can't be set to the value of 'COMPRESSED'
Недавно составленные таблицы используют формат строки, определенный
innodb_default_row_format
, когда ROW_FORMAT
не определена явно или когда ROW_FORMAT=DEFAULT
.
Например, следующие CREATE TABLE
используют формат строки, определенный
innodb_default_row_format
.
CREATE TABLE t1 (c1 INT); CREATE TABLE t2 (c1 INT) ROW_FORMAT=DEFAULT;
Когда опция ROW_FORMAT
не определена явно, или когда
ROW_FORMAT=DEFAULT
, любая операция, которая пересоздает таблицу,
также тихо изменяет формат строки таблицы к формату, определенному
innodb_default_row_format
.
Пересоздающие таблицу операции включают
ALTER TABLE
с использованием
ALGORITHM=COPY
или ALTER
TABLE
с использованием ALGORITM=INPLACE
,
где табличное восстановление требуется. См.
таблицу 16.9
для краткого обзора состояния операций DDL.
OPTIMIZE TABLE
тоже пересоздает таблицу.
Следующий пример демонстрирует восстанавливающую таблицу работу, которая тихо изменяет формат строки таблицы, составленной без явно определенного формата строки.
mysql> SELECT @@innodb_default_row_format; +-----------------------------+ | @@innodb_default_row_format | +-----------------------------+ | dynamic | +-----------------------------+ mysql> CREATE TABLE t1 (c1 INT); mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1' \G *************************** 1. row *************************** TABLE_ID: 54 NAME: test/t1 FLAG: 33 N_COLS: 4 SPACE: 35 ROW_FORMAT: Dynamic ZIP_PAGE_SIZE: 0 SPACE_TYPE: Single mysql> SET GLOBAL innodb_default_row_format=COMPACT; mysql> ALTER TABLE t1 ADD COLUMN (c2 INT); mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1' \G *************************** 1. row *************************** TABLE_ID: 55 NAME: test/t1 FLAG: 1 N_COLS: 5 SPACE: 36 ROW_FORMAT: Compact ZIP_PAGE_SIZE: 0 SPACE_TYPE: Single
Рассмотрите следующие потенциальные проблемы прежде, чем изменить формат
строки существующих таблиц с REDUNDANT
или
COMPACT
на DYNAMIC
.
REDUNDANT
и COMPACT
поддерживают префикс индексного ключа максимум в 767 байт, тогда как
DYNAMIC
и COMPRESSED
допускают префикс индексного
ключа в 3072 байт. В среде репликации, если
innodb_default_row_format
установлен в DYNAMIC
на ведущем устройстве и в COMPACT
на ведомом устройстве,
следующий запрос DDL, который явно не определяет формат строки, работает на
ведущем устройстве, но терпит неудачу на ведомом устройстве:
CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 VARCHAR(5000), KEY i1(c2(3070)));
Подробности в разделе 16.8.7.
innodb_default_row_format
на исходном сервере отличается от
установки на целевом сервере. Для получения дополнительной информации,
обратитесь к ограничениям, обрисованным в общих чертах в
разделе 16.7.6.Чтобы смотреть формат строки таблицы, скомандуйте
SHOW TABLE STATUS
или
запросите INFORMATION_SCHEMA.TABLES
.
SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1' \G
Формат строки определяет физическую структуру строки. См. раздел 16.8.2.
Когда таблица составлена с ROW_FORMAT=DYNAMIC
или
ROW_FORMAT=COMPRESSED
, InnoDB
может сохранить длинные значения столбцов переменной длины (для типов
VARCHAR
,
VARBINARY
,
BLOB
и
TEXT
)
полностью вне страницы, с кластеризируемой индексной записью, содержащий
только 20-байтовый указатель на страницу переполнения. InnoDB
может также сохранить значения столбцов CHAR
вне страницы, если значение столбца больше или равно 768 байтам,
что может произойти, если максимальная длина байта набора символов больше 3,
как это с набором utf8mb4
.
Сохранены ли какие-либо столбцы вне страницы, зависит от размера страницы
и полного размера строки. Когда строка является слишком длинной,
InnoDB
выбирает самые длинные столбцы для хранения вне страницы,
пока записи кластеризируемого индекса помещаются на странице
B-tree. Столбцы
TEXT
и
BLOB
, которые меньше или равны 40
байтам, всегда сохранены на месте.
Формат строки DYNAMIC
поддерживает эффективность хранения
всей строки в индексном узле, если она там помещается (так же, как и форматы
COMPACT
и REDUNDANT
), но DYNAMIC
избегает проблемы заполняющихся узлов B-дерева с большим количеством байтов
данных длинных столбцов. DYNAMIC
основан на идее, что если часть
большого значения данных сохранена вне страницы, обычно самым эффективным
будет сохранить все значение вне страницы. С форматом DYNAMIC
более короткие столбцы, вероятно, останутся в узле B-дерева, минимизируя
число страниц переполнения, необходимых для любой данной строки.
Формат строки COMPRESSED
использует подобные внутренние детали для хранения вне страницы, как
DYNAMIC
с дополнительными соображениями в плане
сжатых данных таблицы и индекса и использования меньших размеров страницы. С
COMPRESSED
опция KEY_BLOCK_SIZE
управляет, сколько данных столбца хранится в кластеризируемом индексе, а
сколько помещено на страницах переполнения. Для полного изложения
формата COMPRESSED
см.
раздел 16.9.
DYNAMIC
и COMPRESSED
поддерживают префикс
индексного ключа в 3072 байт.
Таблицы, которые используют COMPRESSED
могут быть создан в табличных пространствах
file-per-table или
общих табличных пространствах
. Системное табличное пространство не поддерживает формат строки
COMPRESSED
. Чтобы сохранить таблицу COMPRESSED
в табличном пространстве file-per-table, параметр
innodb_file_per_table
должен быть включен. Опция
innodb_file_per_table
не применима к общим табличным пространствам.
Общие табличные пространства поддерживают все форматы строки, но сжатые
и несжатые таблицы не могут сосуществовать в том же самом общем табличном
пространстве из-за различных физических размеров страницы. Для получения
дополнительной информации об общих табличных пространствах см.
раздел 16.7.9.
Таблицы DYNAMIC
могут быть сохранены в табличных
пространствах file-per-table, общих табличных пространствах и системном
табличном пространстве. Чтобы сохранить DYNAMIC
в системном табличном пространстве, Вы можете отключить
innodb_file_per_table
и использовать CREATE TABLE
или ALTER TABLE
или Вы можете использовать табличную опцию TABLESPACE
[=] innodb_system
с CREATE TABLE
или ALTER TABLE
не имея необходимость изменять
innodb_file_per_table
. Опция
innodb_file_per_table
неприменима к общим табличным пространствам,
и при этом они неприменимы, используя опцию TABLESPACE [=]
innodb_system
, чтобы сохранить таблицы DYNAMIC
в системном табличном пространстве.
InnoDB
не поддерживает сжатые временные таблицы. Когда
innodb_strict_mode
включен (значение по умолчанию),
CREATE TEMPORARY TABLE
возвращает ошибку, если задан ROW_FORMAT=COMPRESSED
или
KEY_BLOCK_SIZE
. Если
innodb_strict_mode
выключен, предупреждения выпущены, и временная таблица
составлена, используя несжатый формат строки.
DYNAMIC
и COMPRESSED
это варианты
COMPACT
и поэтому обрабатывают
CHAR
аналогично подходу
COMPACT
. Подробности в
разделе 16.8.2.
Таблицы, которые используют COMPACT
или
REDUNDANT
, хранят первые 768 байт столбцов переменной длины
(VARCHAR
,
VARBINARY
,
BLOB
и
TEXT
)
в индексной записи в пределах узла
B-tree
с остатком, сохраненным в страницах переполнения.
Для таблиц, определенных с ROW_FORMAT=COMPACT
,
CHAR
обработан как столбец переменной длины, если длина значения
столбца больше или равна 768 байтам, что может произойти, если максимальная
длина байта набора символов больше 3, как это с utf8mb4
.
Для COMPACT
или REDUNDANT
, если значение столбца составляет 768 байтов или меньше, никакая страница
переполнения не нужна и некоторая экономия во вводе/выводе может получиться,
так как значение находится в узле B-дерева. Это работает хорошо на
относительно коротких BLOB
, но может заставить узлы B-дерева
заполняться данными, а не значениями ключа, уменьшая их эффективность.
Таблицы со многими столбцами BLOB
могут заставить узлы B-дерева
становиться слишком полными данными и содержать слишком мало строк, заставляя
все индексировать менее эффективно, чем если бы строки были короче или если
значения столбцов были сохранены вне страницы.
Формат строки по умолчанию DYNAMIC
, как определено опцией
innodb_default_row_format
. См.
раздел 16.10.3.
Для информации о физической структуре строки таблиц, которые используют
форматы REDUNDANT
или COMPACT
, см.
раздел 16.8.2.
Как DBA, Вы должны управлять дисковым вводом/выводом, чтобы
препятствовать перегрузке подсистемы ввода/вывода
и управлять дисковым пространством, чтобы избежать переполнения устройства
хранения данных. Модель ACID
требует определенного количества ввода/вывода, который мог бы казаться
избыточным, но помогает гарантировать надежность данных. В пределах этих
ограничений InnoDB
предпринимает попытки оптимизировать базу
данных и организацию дисковых файлов, чтобы минимизировать количество
дискового ввода/вывода. Иногда, ввод/вывод отложен, пока база данных не
освободится или пока все должно быть приведено в последовательное состояние,
как во время перезапуска базы данных после
быстрого завершения работы.
Этот раздел обсуждает основные соображения для ввода/вывода и дискового
пространства с таблицами MySQL InnoDB
):
Управление количеством фонового ввода/вывода улучшает работу запроса.
InnoDB
использует асинхронный дисковый ввод/вывод где только
возможно, создавая много потоков, чтобы обработать операции ввода/вывода,
разрешая другим операциям базы данных продолжиться в то время, как ввод/вывод
все еще происходит. На Linux и платформах Windows InnoDB
использует доступные функции OS и библиотеки, чтобы выполнить
нативный асинхронный ввод/вывод. На других
платформах InnoDB
все еще использует потоки ввода/вывода, но
потоки могут фактически ждать запросов ввода/вывода, этот метод известен как
симулированный асинхронный ввод/вывод.
Если InnoDB
может решить, что есть высокая вероятность, что
данные могли бы скоро быть необходимы, это выполняет операции чтения вперед,
чтобы принести те данные в буферный пул так, чтобы это было доступно в
памяти. Обращение с несколькими большими запросами чтения для непрерывных
данных может быть более эффективным чем обращение с несколькими маленькими.
Есть две эвристики чтения вперед в InnoDB
:
В последовательном чтении вперед, если InnoDB
знает, что образец доступа к сегменту в табличном пространстве
последователен, это отправляет заранее пакет чтений страниц базы данных
системе ввода/вывода.
InnoDB
знает, что некоторая
область в табличном пространстве, кажется, находится в процессе того, чтобы
быть полностью считанной в буферный пул, это отправляет остающиеся чтения в
систему ввода/вывода.Подробности в разделе 16.6.3.5.
InnoDB
использует новый метод сброса файла, вовлекающий
структуру, названную буфер
doublewrite, который включен по умолчанию в большинстве случаев
(innodb_doublewrite=ON
). Это добавляет безопасности восстановлению после отключения
электричества катастрофического отказа и улучшает работу относительно
большинства вариантов Unix, уменьшая
потребность в операциях fsync()
.
Перед записью страниц в файл с данными InnoDB
сначала пишет их в непрерывной области табличного пространства, названной
буфером doublewrite. Только после завершения записи в буфер doublewrite,
делается запись страниц на их надлежащие позиции в файле с данными. Если есть
катастрофический отказ процесса
mysqld или чего-то еще в середине записи страницы,
InnoDB
может позже найти хорошую копию страницы в буфере
doublewrite во время восстановления.
Если системные файлы табличного пространства (файлы ibdata
) расположены на устройствах Fusion-io, которые поддерживают
атомные записи, буферизация doublewrite автоматически отключена, и
Fusion-io используются для всех файлов с данными. Поскольку буферная
установка doublewrite глобальна, doublewrite-буферизация также отключена для
файлов с данными, находящихся на не-Fusion-io аппаратных средствах. Эта
функция поддерживается только на аппаратных средствах Fusion-io NVMFS в
Linux. Чтобы в полной мере воспользоваться этой особенностью, установите
innodb_flush_method
в O_DIRECT
.
Файлы с данными, которые Вы определяете в конфигурационном файле,
используя опцию
innodb_data_file_path
создают
системное табличное
пространство. Файлы логически связаны, чтобы сформировать системное
табличное пространство. В использовании нет никакого чередования. Вы не
можете определить, где в пределах системного табличного пространства Ваши
таблицы выделены. В создаваемом системном табличном пространстве
InnoDB
выделяет место, начиная с первого файла с данными.
Чтобы избежать проблем, которые идут с хранением всех таблиц и индексов
в системном табличном пространстве, Вы можете включить опцию
innodb_file_per_table
(значение по умолчанию), которая хранит
каждую недавно составленную таблицу в отдельном файле табличного пространства
(с расширением .ibd
). Для таблицы, сохраненной этим путем, есть
меньше фрагментации в пределах дискового файла, и когда таблица усечена,
пространство возвращено к операционной системе вместо того, чтобы все еще
быть сохраненным InnoDB в пределах системного табличного пространства. Для
получения дополнительной информации см.
раздел 16.7.4.
Вы можете также сохранить таблицы в
общих табличных пространствах
. Общие табличные пространства это совместно используемые табличные
пространства, создаваемые с CREATE
TABLESPACE
. Они могут быть созданы за пределами каталога данных
MySQL, способны к хранению многих таблиц и поддерживают таблицы всех форматов
строки. Для получения дополнительной информации см.
раздел 16.7.9.
Каждое табличное пространство состоит из
страниц.
У каждого табличного пространства в случае MySQL есть тот же самый
размер страницы.
По умолчанию у всех табличных пространств есть размер страницы 16KB,
Вы можете уменьшить размер страницы до 8 КБ или 4 КБ, определяя опцию
innodb_page_size
, когда Вы создаете экземпляр MySQL. Вы можете также увеличить размер
страницы до 32 КБ или 64 КБ. Для получения дополнительной информации
обратитесь к описанию опции
innodb_page_size
.
Страницы сгруппированы в экстенты
размера 1 МБ для страниц до 16 КБ в размере (64 последовательных страницы по
16 КБ, 128 страниц по 8KB или 256 страниц по 4KB). Для размера страницы 32
КБ размер экстента 2MB. Для размера страницы 64KB размер экстента 4MB.
Файлы в табличном пространстве называют
сегментами в InnoDB
.
Эти сегменты отличаются от
сегмента отмены, который фактически содержит много
сегментов табличного пространства.
Когда сегмент растет в табличном пространстве, InnoDB
выделяет первые 32 страницы по одной. После этого InnoDB
начинает выделять целые экстенты сегменту. InnoDB
может добавить
до 4 экстентов за один раз к большому сегменту, чтобы гарантировать
хорошее размещение данных.
Два сегмента выделены для каждого индекса. Один для безлистных узлов B-tree, другой для узлов с листьями. Хранение узлов листа непрерывными на диске улучшает последовательные операции ввода/вывода, потому что эти узлы листа содержат фактические табличные данные.
Некоторые страницы в табличном пространстве содержат битовые массивы
других страниц, и поэтому несколько экстентов в табличном пространстве
InnoDB
не могут быть выделено сегментам в целом, только
как отдельные страницы.
Когда Вы запрашиваете доступное свободное пространство в табличном
пространстве посредством SHOW TABLE
STATUS
, InnoDB
сообщает экстенты, которые определенно
свободны в табличном пространстве. InnoDB
всегда имеет в запасе
некоторые экстенты для уборки и других внутренних целей, эти сохраненные
экстенты не включены в свободное пространство.
Когда Вы удаляете данные из таблицы, InnoDB
сокращает соответствующее B-дерево индексов. Становится ли освобожденное
пространство доступным другим пользователям, зависит от того,
освобождаются ли отдельные страницы или экстенты в табличном пространстве.
Удаление таблицы или удаление всех строк из нее будет освобождать
пространство другим пользователям, но помните, что удаленные строки физически
удалены только чисткой,
которая происходит автоматически через некоторое время после того, как они
больше не нужны для операционных отмен или последовательных чтений. См.
раздел 16.3.
Максимальная длина строки немного меньше, чем половина страницы базы
данных для 4KB, 8KB, 16KB и 32KB
innodb_page_size
. Например, максимальная длина строки немного меньше, чем 8 КБ для
значения по умолчанию 16 КБ размера страницы InnoDB
.
Для страниц 64 КБ максимальная длина строки немного меньше 16 КБ.
Если строка не превышает максимальную длину строки, все это сохранено в местном масштабе в пределах страницы. Если строка превышает максимальную длину строки, столбцы переменной длины выбраны для внешнего хранения вне страницы в пределах максимального предела длины строки. Внешнее хранение вне страницы для столбцов переменной длины отличается форматом строки:
COMPACT и REDUNDANT
Когда столбец переменной длины выбран для внешнего хранения вне страницы,
InnoDB
хранит первые 768 байтов в местном масштабе в строке, а
остальные внешне в странице переполнения. У каждого такого столбца есть свой
собственный список страниц переполнения. 768-байтовый префикс сопровождается
20-байтовым значением, которое хранит истинную длину столбца и указывает на
список переполнения, где остальная часть значения сохранена. См.
раздел 16.10.4.
Когда столбец переменной длины выбран для внешнего хранения вне страницы,
InnoDB
хранит 20-байтовый указатель в местном масштабе в строке,
а остальное внешне в странице переполнения. См.
раздел 16.10.3.
Столбцы LONGBLOB
и
LONGTEXT
должны быть меньше 4 ГБ, и суммарная длина строки, включая
BLOB
и
TEXT
,
должна быть меньше 4 ГБ.
Создание Ваших очень больших файлов системного журнала может уменьшить дисковый ввод/вывод во время установки контрольных точек. Часто имеет смысл устанавливать полный размер файлов системного журнала столь же большим, как буферный пул или еще больше.
InnoDB
осуществляет механизм
контрольной точки, известный как
нечеткая установка
контрольных точек. InnoDB
сбрасывает измененные страницы
базы данных из буферного пула в маленьких пакетах. Нет никакой потребности
сбрасывать буферный пул в одном огромном пакете, который разрушил бы
обработку пользовательских запросов SQL во время процесса
установки контрольных точек.
Во время восстановления
катастрофического отказа InnoDB
ищет метку контрольной
точки, записанную в файлы системного журнала. Это знает, что все модификации
базы данных перед меткой присутствуют в образе базы данных на диске. Тогда
InnoDB
просматривает файлы системного журнала вперед от
контрольной точки, применяя зарегистрированные модификации к базе данных.
Случайные вставки или удаления из вторичного индекса могут заставить индексирование становится фрагментированным. Фрагментация означает, что физическое упорядочивание индексных страниц на диске не близко к индексному упорядочиванию записей на страницах, или что есть много неиспользованных страниц в блоках на 64 страницы, которые были выделены индексу.
Один признак фрагментации: что таблица занимает больше места, чем она
должна занимать. То, сколько это точно, трудно
определить. Все данные InnoDB
и индексы сохранены в
B-tree, и их
коэффициент заполнения
может измениться от 50% до 100%. Другой признак фрагментации: сканирование
таблицы, такое как это, занимает больше времени, чем
должно:
SELECT COUNT(*) FROM t WHERE non_indexed_column
<> 12345;
Предыдущий запрос требует, чтобы MySQL выполнил полное сканирование таблицы, самый медленный тип запроса для большой таблицы.
Чтобы убыстрить индексные просмотры, Вы можете периодически выполнять
нулевой ALTER
TABLE
, которая заставляет MySQL восстанавливать таблицу:
ALTER TABLE tbl_name
ENGINE=INNODB
Вы можете также использовать
ALTER TABLE
, чтобы выполнить
нулевую работу, которая восстанавливает таблицу.
tbl_name
FORCE
ALTER TABLE
и
tbl_name
ENGINE=INNODBALTER TABLE
используют
online DDL
(tbl_name
FORCEALGORITHM=COPY
). Подробности в
разделе 16.12.1.
Другой способ выполнить работу дефрагментации состоит в том, чтобы использовать mysqldump , чтобы вывести таблицу в дамп, удалить таблицу и перезагрузить ее из файла дампа.
Если вставки в индекс всегда растут, а записи удалены только из конца,
управленческий алгоритм InnoDB
гарантирует, что фрагментация в
индексе не происходит.
Чтобы восстановить дисковое пространство операционной системы,
усекая таблицу,
эта таблица должна быть сохранена в ее собственном файле
.ibd.
Для таблицы, которая будет сохранена в ее собственном файле
.ibd,
innodb_file_per_table
должен быть включен, когда таблица составлена. Дополнительно не
может быть ограничения внешнего
ключа между таблицей для усечения и другими таблицами, иначе
TRUNCATE TABLE
выдаст ошибку. Ограничение внешнего ключа между
двумя столбцами в той же самой таблице, однако, разрешено.
Когда таблица является усеченной, она удалена и пересоздана в новом файле
.ibd
, а освобожденное пространство возвращено операционной
системе. Это в отличие от усечения таблиц, которые сохранены в пределах
системного табличного
пространства (таблицы, составленные, когда
innodb_file_per_table=OFF
) и таблиц, сохраненных в совместно
используемых общих табличных
пространствах, где только InnoDB
может использовать
освобожденное пространство после того, как таблица усечена.
Способность усечь таблицы и возвратить дисковое пространство операционной
системе также означает, что
физические резервные копии
могут быть меньшими. Усечение таблиц, которые сохранены в системном табличном
пространстве (таблицы, составленные, когда
innodb_file_per_table=OFF
)
или в общем табличном пространстве оставляет блоки неиспользуемого
места в табличном пространстве.
online DDL
улучшает много типов ALTER TABLE
, чтобы избежать табличного копирования или блокирования операций
DML в то время, как
DDL происходит.
Особенность online DDL обладает следующими преимуществами:
Это улучшает отклик и доступность в занятых производственных средах, где создание таблицы, недоступной в течение многих минут или часов, не практично.
LOCK=EXCLUSIVE
), позволить запросы, но не DML
(LOCK=SHARED
) или позволить полный доступ запросам и DML к
таблице (LOCK=NONE
). Когда Вы опускаете LOCK
или определяете LOCK=DEFAULT
, MySQL позволяет такой большой
параллелизм, насколько возможно, в зависимости от типа работы.Исторически, много операций DDL
в таблицах InnoDB
были дороги. Многие
ALTER TABLE
работали, составляя новую, пустую, таблицу, определенную с требуемыми
табличными опциями и индексами, затем копируя существующие строки к новой
таблице поштучно, обновляя индексирование по мере того, как строки были
вставлены. После того, как все строки оригинальной таблицы были
скопированы, старая таблица была удалена, а копия переименована с
названием оригинальной таблицы.
MySQL 5.5 и MySQL 5.1 с InnoDB Plugin оптимизировали
CREATE INDEX
и DROP INDEX
, чтобы
избегать копирующего таблицу поведения. Та особенность была известна, как
быстрое создание индекса
. MySQL 5.6 улучшил много других типов
ALTER TABLE
, чтобы избежать
копировать таблицу. Другое улучшение позволило запросам
SELECT
INSERT
,
UPDATE
и
DELETE
(DML) продолжиться в то время, как
таблица изменяется. В MySQL 5.7 ALTER
TABLE RENAME INDEX
был также улучшен, чтобы избежать табличного
копирования. Эта комбинация особенностей теперь известна как
online DDL.
Этот механизм также означает, что Вы можете вообще ускорить полный процесс создания и загрузки таблицы, составляя таблицу без вторичного индекса, затем добавляя, вторичный индекс после того, как данные загружены.
Хотя никакие изменения синтаксиса не требуются в
CREATE INDEX
или
DROP INDEX
,
некоторые факторы затрагивают работу и семантику этой работы (см.
раздел 16.12.9).
Возможность online DDL в MySQL 5.6 улучшила много операций DDL, которые
прежде требовали табличной копии или блокировали операции DML на таблице.
Таблица 16.9
показывает изменения ALTER TABLE
как особенность DDL онлайн относится к каждому запросу.
За исключением параметров разделения в
ALTER TABLE
, online DDL для разделенных таблиц
следуют тем же самым правилам, которые относятся к обычным таблицам. Для
получения дополнительной информации см.
раздел 16.12.8.
Столбец In-Place? показывает, которые
операции позволяют ALGORITHM=INPLACE
.
ALGORITHM=INPLACE
, но все еще вовлекают некоторое
количество табличного копирования.LOCK=NONE
, чтобы утверждать, что полный
параллелизм позволен во время DDL, но MySQL автоматически позволяет этот
уровень параллелизма, когда можно. Когда параллельный DML позволен,
параллельные запросы также всегда позволяются.LOCK=SHARED
,
чтобы утверждать, что параллельные запросы позволены во время DDL, но MySQL
автоматически позволяет этот уровень параллелизма когда возможно.Таблица 16.9. Резюме состояния онлайн для операций DDL
Операция | In-Place? | Copies Table? | Allows Concurrent DML? | Allows Concurrent Query? | Примечания |
---|---|---|---|---|---|
CREATE INDEX
, ADD INDEX |
Yes* | No* | Да | Да | Некоторые ограничения для
индекса FULLTEXT . |
ADD FULLTEXT
INDEX | Да | No* | Нет | Да |
Создание первого индекса FULLTEXT для таблицы, вовлекает
табличную копию, если нет столбца FTS_DOC_ID . Последующие
индексы FULLTEXT на той же самой таблице могут
быть созданы оперативно. |
ADD SPATIAL INDEX
| Да | Нет | Нет | Да | Оптовая загрузка не поддержана. |
RENAME INDEX
| Да | Нет | Да | Да | Только изменяет табличные метаданные. |
DROP INDEX
| Да | Нет | Да | Да | Только изменяет табличные метаданные. |
OPTIMIZE TABLE
| Да | Да | Да | Да |
ALGORITHM=COPY используется, если old_alter_table=1 или
включена опция mysqld
--skip-new . OPTIMIZE TABLE
использует онлайн DDL (ALGORITHM=INPLACE ), не поддерживая
таблицы с индексами FULLTEXT. |
Установить значение по умолчанию для столбца. | Да | Нет | Да | Да | Только изменяет табличные метаданные. |
Изменить для столбца значение auto-increment. | Да | Нет | Да | Да | Изменяет значение, сохраненное в памяти, а не в файле с данными. |
Добавить ограничение внешнего ключа | Yes* | No* | Да | Да |
Чтобы избежать копировать таблицу, отключите
foreign_key_checks
во время создания ограничения. |
Удалить ограничение внешнего ключа | Да | Нет | Да | Да |
foreign_key_checks
может быть включена или отключена. |
Переименовать столбец | Yes* | No* | Yes* | Да | Чтобы позволить параллельный DML, сохраните тот же
самый тип данных и измените только имя столбца. ALGORITHM=INPLACE
не поддержан для того, чтобы переименовать
произведенный столбец.
|
Добавить | Yes* | Yes* | Yes* | Да | Параллельный DML не позволен, добавляя столбец
auto-increment.
Хотя ALGORITHM=INPLACE позволен, данные реорганизованы
существенно, таким образом, это все еще дорогая работа.
ALGORITHM=INPLACE поддержан для того, чтобы добавить
произведенный
виртуальный столбец, но не для того, чтобы добавить
произведенный
сохраненный столбец. Добавление произведенного виртуального столбца не
требует табличной копии. |
Удалить столбец | Да | Yes* | Да | Да | Хотя ALGORITHM=INPLACE
позволен, данные реорганизованы существенно, таким образом, это все еще
дорогая работа. ALGORITHM=INPLACE поддержан для того, чтобы
удалить произведенный столбец. Удаление
произведенного виртуального столбца не требует табличной копии. |
Reorder columns | Да | Да | Да | Да | Хотя ALGORITHM=INPLACE позволен, данные
реорганизованы существенно, таким образом, это все еще дорогая работа.
|
Изменить свойства ROW_FORMAT |
Да | Да | Да | Да |
Хотя ALGORITHM=INPLACE позволен, данные
реорганизованы существенно, таким образом, это все еще дорогая работа.
|
Изменить свойства KEY_BLOCK_SIZE |
Да | Да | Да | Да |
Хотя ALGORITHM=INPLACE позволен, данные
реорганизованы существенно, таким образом, это все еще дорогая работа.
|
Сделать столбец NULL |
Да | Да | Да | Да |
Хотя ALGORITHM=INPLACE позволен, данные
реорганизованы существенно, таким образом, это все еще дорогая работа.
|
Сделать столбец NOT NULL |
Yes* | Да | Да | Да | STRICT_ALL_TABLES
или STRICT_TRANS_TABLES
SQL_MODE
требуется для работы. Работа терпит неудачу, если столбец содержит значения
NULL. Сервер запрещает изменения столбцов внешнего ключа, у которых есть
потенциал, чтобы вызвать потерю ссылочной целостности.
Для получения дополнительной информации см.
раздел 14.1.7.
Хотя ALGORITHM=INPLACE позволен, данные
реорганизованы существенно, таким образом, это все еще дорогая работа.
|
Изменить тип столбца | No* | Yes* | Нет | Да | Исключение: VARCHAR
может быть увеличен, используя онлайн
ALTER TABLE . |
Добавить primary key | Yes* | Да | Да | Да |
Хотя ALGORITHM=INPLACE позволен, данные
реорганизованы существенно, таким образом, это все еще дорогая работа.
ALGORITHM=INPLACE не позволен при определенных условиях, если
столбцы должны быть преобразованы в NOT NULL . См.
Пример 16.9. |
Удалить primary key и добавить другой | Да | Да | Да | Да |
ALGORITHM=INPLACE позволен только, когда Вы добавляете новый
первичный ключ в том же самом ALTER
TABLE . |
Удалить primary key | Нет | Да | Нет | Да |
Ограничения применяются, когда Вы удаляете первичный ключ, не добавляя новый
в том же самом ALTER TABLE . |
Сменить набор символов | Нет | Да | Нет | Да | Пересоздает таблицу, если новая кодировка символов отличается. |
Определить набор символов | Нет | Да | Нет | Да | Пересоздает таблицу, если новая кодировка символов отличается. |
Пересоздать с опцией FORCE |
Да | Да | Да | Да | ALGORITHM=COPY
используется, если old_alter_table=1 или включена опция
mysqld
--skip-new . Пересоздание таблицы с использованием онлайн DDL
(ALGORITHM=INPLACE ) не поддержано для
таблиц с индексами FULLTEXT. |
Пересоздать с null ALTER
TABLE ... ENGINE=INNODB | Да | Да | Да | Да | ALGORITHM=COPY используется, если
old_alter_table=1 или включена опция
mysqld
--skip-new . Пересоздание таблицы с использованием онлайн DDL
(ALGORITHM=INPLACE ) не поддержано для
таблиц с индексами FULLTEXT. |
Установить
постоянные опции статистики на уровне таблицы
(STATS_PERSISTENT , STATS_AUTO_RECALC
STATS_SAMPLE_PAGES ). |
Да | Нет | Да | Да | Только изменяет табличные метаданные. |
Следующие разделы показывают основной синтаксис и примечания использования, связанные с DDL онлайн, для каждой из главных операций, которые могут быть выполнены с параллельным DML:
Создание вторичных
индексов: CREATE INDEX
или
name
ON
table
(col_list
)ALTER TABLE
. Создание индекса
table
ADD
INDEX name
(col_list
)FULLTEXT
все еще требует блокировки таблицы.
DROP INDEX name
ON
table
;
или ALTER
TABLE table
DROP INDEX
name
Создание и удаление вторичного индекса на таблице пропускает копирующее таблицу поведение.
Таблица остается доступной для чтения и записи
в то время, как индекс создается или удаляется.
CREATE INDEX
или
DROP INDEX
заканчивается только после того, как все транзакции, которые получают доступ
к таблице, завершены, чтобы начальное состояние индекса отразило новое
содержание таблицы. Ранее изменение таблицы в то время, как индекс создается
или удаляется, как правило, приводило к
тупику, который отменял
INSERT
,
UPDATE
или
DELETE
.
Установите значение по умолчанию для столбца:
ALTER TABLE
или tbl
ALTER COLUMN
col
SET DEFAULT literal
ALTER TABLE
tbl
ALTER COLUMN
col
DROP DEFAULT
Значения по умолчанию для столбцов сохранены в словаре данных.
ALTER TABLE table
AUTO_INCREMENT=next_value
;
Особенно в распределенной системе, используя репликацию, Вы иногда сбрасываете счетчик автоинкремента для таблицы к определенному значению. Следующая строка, вставленная в таблицу, использует указанное значение для своего столбца auto-increment. Вы могли бы также использовать этот метод в окружающей среде складирования данных, где Вы периодически очищаете все таблицы и перезагружаете их и можете перезапустить последовательность автоинкремента от 1.
ALTER TABLE tbl
CHANGE old_col_name
new_col_name
datatype
Когда Вы сохраняете тот же самый тип данных и параметр
[NOT] NULL
, только изменяя имя столбца, эта работа может
всегда выполняться онлайн.
Вы можете также переименовать столбец, который является частью ограничения
внешнего ключа. Определение внешнего ключа автоматически обновлено, чтобы
использовать новое имя столбца. Переименование столбца, участвующего во
внешнем ключе, работает только с оперативным режимом
ALTER TABLE
.
Если Вы используете ALGORITHM=COPY
или некоторое другое условие
заставляет команду использовать ALGORITHM=COPY
негласно,
ALTER TABLE
потерпит неудачу.
VARCHAR
,
используя оперативное ALTER TABLE
, как в этом примере:
ALTER TABLE t1 ALGORITHM=INPLACE, CHANGE COLUMN c1 c1 VARCHAR(255);
Число байтов длины, требуемое столбцом
VARCHAR
,
должно остаться тем же самым. Для VARCHAR
от 0 до 255, один байт длины обязан кодировать значение. Для
VARCHAR
в 256 байт или больше
надо два байта. В результате оперативный
ALTER TABLE
допускает только увеличение
VARCHAR
от 0 до 255 байт или
увеличение размера от значения, равного или большего 256 байтов. Оперативный
ALTER TABLE
не поддерживает
увеличение VARCHAR
от значения
меньше 256 байт до значения, равного или больше 256 байтов. В этом случае
число необходимых байтов длины изменилось бы от 1 до 2, что поддержано только
табличной копией (ALGORITHM=COPY
). Например, попытка изменить
размер столбца VARCHAR
от
255 до 256, используя оперативный
ALTER TABLE
возвратила бы ошибку:
ALTER TABLE t1 ALGORITHM=INPLACE, CHANGE COLUMN c1 c1 VARCHAR(256); ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.
Уменьшение размера VARCHAR
,
используя оперативный ALTER TABLE
не поддержано. Уменьшение VARCHAR
требует табличной копии (ALGORITHM=COPY
).
Добавление или удаление ограничения внешнего ключа:
ALTER TABLEtbl1
ADD CONSTRAINTfk_name
FOREIGN KEYindex
(col1
) REFERENCEStbl2
(col2
)referential_actions
; ALTER TABLEtbl
DROP FOREIGN KEYfk_name
;
Удаление внешнего ключа может быть выполнено онлайн с включенной или
выключенной опцией
foreign_key_checks
. Создание внешнего ключа онлайн требует
выключения
foreign_key_checks
.
Если Вы не знаете названия ограничений внешнего ключа на особую таблицу,
делаете следующее запрос и находите имя ограничения в параметре
CONSTRAINT
для каждого внешнего ключа:
show create table table
\G
Или запросите таблицу
information_schema.table_constraints
и используйте столбцы
constraint_name
и constraint_type
, чтобы
идентифицировать имена внешнего ключа.
Вы можете также удалить внешний ключ и его связанный индекс в единственном запросе:
ALTER TABLEtable
DROP FOREIGN KEYconstraint
, DROP INDEXindex
;
Если внешние ключи
уже присутствуют в измененной таблице (то есть, это
дочерняя таблица,
содержащая любой FOREIGN KEY ... REFERENCE
), дополнительные
ограничения относятся к операциям онлайн DDL, даже те, которые
непосредственно не вовлекают столбцы внешнего ключа:
ALTER TABLE
на дочерней таблице мог ждать завершения другой транзакции, если бы изменение
родительской таблицы вызвало связанные изменения в дочерней таблице через
ON UPDATE
или ON DELETE
, используя параметры
CASCADE
или SET NULL
.
FOREIGN KEY
, это могло ждать конца
ALTER TABLE
, если
INSERT
,
UPDATE
или
DELETE
вызвал
ON UPDATE
или ON DELETE
в дочерней таблице.
Любая ALTER TABLE
,
выполненная с ALGORITHM=COPY
, предотвращает параллельные
операции DML. Параллельные запросы все еще позволены. Таким образом,
копирующая таблицу работа всегда включает, по крайней мере, ограничения
параллелизма LOCK=SHARED
(позволяет запросы, но не DML). Вы
можете далее ограничить параллелизм для таких операций, определяя
LOCK=EXCLUSIVE
, что предотвращает DML и запросы.
Некоторый другой вызов ALTER TABLE
позволяет параллельный DML, но все еще требует табличной копии.
Добавление, удаление или переупорядочивание столбцов.
ROW_FORMAT
или KEY_BLOCK_SIZE
.OPTIMIZE TABLE
.FORCE
.ALTER
TABLE ... ENGINE=INNODB
.Поскольку Ваша схема базы данных развивается с новыми столбцами, типами
данных, ограничениями, индексами и так далее, держите Ваш
CREATE TABLE
современным с последними табличными определениями. Даже с исполнительными
усовершенствованиями DDL онлайн, более эффективно создать устойчивые
структуры базы данных вначале, вместо того, чтобы создать часть схемы и затем
использовать ALTER TABLE
позже.
Основное исключение: вторичные индексы на таблицах с большими количествами строк. Является, как правило, самым эффективным составить таблицу со всеми деталями, кроме вторичного индекса, загрузите данные, затем создать вторичный индекс. Вы можете использовать тот же самый метод с внешними ключами, если Вы знаете, что исходные данные чисты и не нуждаются в проверках непротиворечивости во время процесса загрузки.
Безотносительно последовательности
CREATE TABLE
, CREATE INDEX
, ALTER TABLE
и подобных запросов, Вы можете получить SQL, который должен восстановить
текущую форму таблицы, делая запрос SHOW CREATE TABLE
(верхний регистр table
\G\G
нужен
для опрятного форматирования). Этот вывод показывает такие пункты, как
числовая точность, NOT NULL
и CHARACTER SET
,
это иногда добавляется негласно, которые Вы можете не учесть, клонируя
таблицу на новой системе или настраивая столбцы внешнего
ключа с идентичным типом.
Online DDL улучшает несколько аспектов работы MySQL, таких как работа, параллелизм, доступность и масштабируемость:
Поскольку запросы и операции DML на таблице могут продолжиться, в то время как DDL происходит, приложения, которые получают доступ к таблице, более отзывчивы. Уменьшенная блокировка и ожидание других ресурсов всюду по серверу MySQL приводят к большей масштабируемости, даже для операций, не вовлекающих измененную таблицу.
Если работа онлайн требует временных файлов, InnoDB
создает их во временном каталоге по умолчанию, а не в каталоге, содержащем
оригинальную таблицу. Если этот каталог не является достаточно большим, чтобы
содержать такие файлы, Вы, возможно, должны установить
tmpdir
к иному каталогу. Альтернативно, Вы можете определить отдельный временный
каталог для операций InnoDB
online
ALTER TABLE
, применяя опцию
innodb_tmpdir
.
Эта опция была введена, чтобы помочь избежать временных переполнений
каталога, которые могли произойти в результате больших временных файлов,
создаваемых во время онлайн ALTER TABLE
. Подробности в разделе
B.5.3.5.
В то время, как таблица InnoDB изменяется работой DDL, таблица может или
не может быть блокирована,
в зависимости от внутренних работ и параметра
LOCK
ALTER TABLE
.
По умолчанию MySQL использует такую небольшую блокировку, насколько возможно,
во время работы DDL, Вы определяете параметр, чтобы сделать блокировку более
сильной, чем обычно (таким образом ограничиваете параллельный DML или DML и
запросов), или гарантировать, что некоторая ожидаемая степень блокировки
позволена для работы. Если LOCK
определяет уровень блокировки,
которая не доступна для того определенного вида работы DDL, например,
LOCK=SHARED
или LOCK=NONE
создавая или удаляя
первичный ключ, пункт работает как утверждение, заставляя запрос потерпеть
неудачу с ошибкой. Следующий список показывает различные возможности для
LOCK
, от самой разрешающей до самой строгой:
Для DDL с LOCK=NONE
запросы и параллельный DML
позволены. Этот пункт делает ALTER TABLE
неудачым, если вид работы DDL не может быть выполнен с требуемым
типом блокировки, так что определите LOCK=NONE
, если хранение
полностью доступной таблицы жизненно важно, и нормально отменять DDL, если
это невозможно. Например, Вы могли бы использовать этот пункт в DDL для
таблиц, вовлекающих потребительские регистрации или покупки, чтобы избежать
делать те таблицы недоступными, по ошибке создав сложный
ALTER TABLE
.
LOCK=SHARED
любые записи в таблицу (то есть,
операции DML) заблокированы, но данные в таблице могут быть считаны. Этот
пункт делает ALTER TABLE
неудачным, если вид работы DDL не может быть выполнен с требуемым типом
блокировки, так что определите LOCK=SHARED
, если хранение
таблицы, доступной для запросов, жизненно важно, и нормально отменять DDL,
если это невозможно. Например, Вы могли бы использовать этот пункт в DDL для
таблиц в хранилище данных, где нормально задерживать операции загрузки
данных, пока DDL не закончен, но запросы не могут быть отсрочены в
течение длительных периодов.LOCK=DEFAULT
или без LOCK
MySQL
использует самый низкий уровень блокировки, которая доступна для такой
работы, позволяя параллельные запросы и DML везде, где возможно. Это
установка, чтобы использовать, производя предварительно запланированные и
проверенные изменения, которые Вы знаете, не будет вызывать проблем
доступности, основанных на рабочей нагрузке для этой таблицы.LOCK=EXCLUSIVE
блокировано все. Этот пункт делает
ALTER TABLE
неудачным, если
вид работы DDL не может быть выполнен с требуемым типом блокировки, так что
определите LOCK=EXCLUSIVE
, если первоочередная задача
заканчивает DDL в самое короткое возможное время, и нормально, что заявки
ждут, когда они пытаются получить доступ к таблице. Вы могли бы также
использовать LOCK=EXCLUSIVE
, если сервер, как предполагается,
неактивен, чтобы избегать неожиданных доступов к таблице.В зависимости от внутренних работ online DDL и LOCK
в
ALTER TABLE
, online DDL может ждать того, чтобы
в настоящее время выполняемые транзакции, которые получают доступ к таблице,
завершились прежде, чем завершиться, потому что эксклюзивный доступ к таблице
требуется в течение краткого времени во время начальных и заключительных фаз
работы DDL. Эти online DDL также ждут завершения получающих доступ к таблице
транзакций, запущенных в то время, как DDL происходит. Следовательно, в
случае долгого рабочего операционного выполнения вставки, обновления,
удаления или SELECT ... FOR UPDATE
на таблице, онлайн
ALTER TABLE
может исчерпать время, поскольку это ждет эксклюзивного доступа к таблице.
Операции DML, которые выполнены на таблице в то время, как онлайн
ALTER TABLE
ждет исключительной табличной блокировки, могут
также быть заблокированы.
Поскольку есть некоторая работа обработки, связанная с записью изменений, произведенных параллельными операциями DML, затем применяя те изменения в конце, работа DDL онлайн могла занять больше времени, чем механизм в старинном стиле, который блокирует табличный доступ от других сеансов. Сокращение сырой работы сбалансировано относительно лучшего отклика для приложений, которые используют таблицу. Оценивая идеальные методы для структуры изменения таблицы, рассмотрите восприятие конечного пользователя работы, основанной на факторах, таких как времена загрузки для веб-страниц.
Недавно создаваемый вторичный индекс
\содержит только преданные данные в таблице в то время, как
CREATE INDEX
или
ALTER TABLE
заканчивает
выполняться. Это не содержит нейтральных значений, старых версий значений или
отмеченных для удаления значений.
Сырое исполнение работы DDL онлайн в значительной степени определено тем, выполнена ли работа оперативно или требует копирования и восстановления всей таблицы. См. таблицу 16.9 , чтобы видеть, какие виды операций могут быть выполнены оперативно, и любые требования для того, чтобы избежать операций табличной копии.
Исполнительное ускорение от оперативного DDL относится к операциям на вторичном индексе, не к первичному ключу. Строки таблицы InnoDB сохранены в кластеризируемом индексе организованном, основываясь на primary key, формируя то, что некоторые системы базы данных называют index-organized table. Поскольку структура таблицы близко связана с первичным ключом, пересмотр первичного ключа все еще требует копирования данных.
Когда работа с первичным ключом использует ALGORITHM=INPLACE
,
даже при том, что данные все еще скопированы, это более эффективно, чем
использование ALGORITHM=COPY
:
Никакое журналирование отмены не требуется для
ALGORITHM=INPLACE
. Эти операции добавляют издержки к запросам
DDL, которые используют ALGORITHM=COPY
.
Чтобы судить относительное исполнение операций DDL онлайн, Вы можете
выполнить такие операции на большой таблице InnoDB
,
используя текущие и более ранние версии MySQL. Вы можете также выполнить все
тесты производительности под последней версией MySQL, моделируя предыдущее
поведение DDL для предыдущих результатов,
устанавливая
old_alter_table
. Скомандуйте set old_alter_table=1
в
сеансе и примените DDL, чтобы сделать запись предварительных
чисел. Затем верните set old_alter_table=0
,
чтобы повторно включить более новое, более быстрое поведение и выполните
операции DDL снова, чтобы сделать запись чисел после
.
Для основной идеи о том, делает ли работа DDL свои оперативные изменения или выполняет табличную копию, см. значение rows affected , выведенное на экран после того, как команда заканчивается. Например, вот строки, которые Вы могли бы видеть после выполнения различных типов операций DDL:
Изменяя значение по умолчанию столбца (сверхбыстро, не затрагивает табличные данные вообще):
Query OK, 0 rows affected (0.07 sec)
0 rows affected
говорит, что таблица не скопирована):
Query OK, 0 rows affected (21.42 sec)
Query OK, 1671168 rows affected (1 min 35.54 sec)
Изменение типа данных столбца требует восстановления всех строк таблицы за
исключением изменения размера VARCHAR
, который может быть выполнен, используя онлайн
ALTER TABLE
.
Например, прежде, чем выполнить работу DDL на большой таблице, Вы могли бы проверить, будет ли работа быстра или замедлится следующим образом:
Клонируйте структуру таблицы.
Для более глубокого понимания сокращения обработки MySQL, исследуйте
таблицы performance_schema
и INFORMATION_SCHEMA
,
связанные с InnoDB
, до и после DDL, чтобы видеть число
физических чтений, записей, распределения памяти и так далее.
Как правило, Вы не должны сделать ничего специального, чтобы включить
online DDL, используя
ALTER TABLE
. См.
таблицу 16.9
для видов операций DDL, которые могут быть выполнены оперативно, позволяя
параллельный DML. Некоторые изменения требуют особых комбинаций настроек
конфигурации или параметров ALTER TABLE
.
Вы можете управлять различными аспектами особой работы DDL онлайн при
использовании LOCK
и ALGORITHM
в
ALTER TABLE
. Эти пункты
стоят в конце запроса, отделенные от таблицы и технических требований столбца
запятыми. LOCK
полезен для точной настройки степени
параллельного доступа к таблице. ALGORITHM
прежде всего предназначен для исполнительных сравнений и как отступление к
более старому копирующему таблицу поведению в случае, если Вы сталкиваетесь с
любыми проблемами с существующим кодом DDL. Например:
Чтобы избежать случайно сделать таблицу недоступной, определите
в ALTER TABLE
параметр
LOCK=NONE
(разрешает чтения и записи)
LOCK=SHARED
(только чтения).
Работа немедленно останавливается, если требуемый
уровень параллелизма недоступен.
ALGORITHM=INPLACE
и другой с ALGORITHM=COPY
,
как альтернатива установке опции
old_alter_table
.ALTER TABLE
, которая копирует
таблицу, включая ALGORITHM=INPLACE
. Запрос немедленно
останавливается, если не может использовать оперативный механизм. См.
таблицу 16.9 для
списка операций DDL, которые могут или не могут быть выполнены оперативно.
См. раздел 16.12.2
для большего количества деталей о LOCK
.
Для полных примеров использования онлайн DDL см.
раздел 16.12.5.
Перед введением online DDL
было обычной практикой объединить много операций DDL в один запрос
ALTER TABLE
.
Поскольку каждый ALTER TABLE
вовлекал копирование и восстановление таблицы, было более эффективно
произвести несколько изменений в той же самой таблице сразу, так как те
изменения могли все быть сделаны сразу. Проблема была в том, что код SQL,
вовлекающий операции DDL, было трудно поддержать и снова использовать в
различных скриптах. Определенные изменения отличались каждый раз, когда
Вам, возможно, придется создать новый
ALTER TABLE
для каждого немного отличающегося скрипта.
Для DDL, которые могут быть сделаны оперативно, как показано в
таблице 16.9,
теперь Вы можете разделить их на отдельные
ALTER TABLE
для более легких сценариев и обслуживания, не
жертвуя эффективностью. Например, Вы могли бы взять сложный
запрос, такой как:
ALTER TABLE t1 ADD INDEX i1(c1), ADD UNIQUE INDEX i2(c2), CHANGE c4_old_name c4_new_name INTEGER UNSIGNED;
и поделить это на более простые части, которые могут быть проверены и выполнены независимо:
ALTER TABLE t1 ADD INDEX i1(c1); ALTER TABLE t1 ADD UNIQUE INDEX i2(c2); ALTER TABLE t1 CHANGE c4_old_name c4_new_name INTEGER UNSIGNED NOT NULL;
Вы могли бы все еще использовать многослойный
ALTER TABLE
для:
Операции, которые должны быть выполнены в определенной последовательности, такие как создание индексирования, сопровождаемого ограничением внешнего ключа.
ALGORITHM=COPY
или
old_alter_table=1
, чтобы вызвать копирующее таблицу поведение если нужно для точной
прежней совместимости в специализированных ситуациях.Вот примеры кода, показывающих некоторые операции, работа которых, параллелизм и масштабируемость улучшены последними улучшениями online DDL.
Пример 16.1 настраивает таблицы
BIG_TABLE
и SMALL_TABLE
,
используемые в последующих примерах.
DROP INDEX
.Пример 16.1. Установки схемы для экспериментов DDL онлайн
Вот код, который настраивает начальные таблицы, используемые в этих демонстрациях:
/* Setup code for the online DDL demonstration: - Set up some config variables. - Create 2 tables that are clones of one of the INFORMATION_SCHEMA tables that always has some data. The "small" table has a couple of thousand rows. For the "big" table, keep doubling the data until it reaches over a million rows. - Set up a primary key for the sample tables, since we are demonstrating InnoDB aspects. */ set autocommit = 0; set foreign_key_checks = 1; set global innodb_file_per_table = 1; set old_alter_table=0; prompt mysql: use test; \! echo "Setting up 'small' table:" drop table if exists small_table; create table small_table as select * from information_schema.columns; alter table small_table add id int unsigned not null primary key auto_increment; select count(id) from small_table; \! echo "Setting up 'big' table:" drop table if exists big_table; create table big_table as select * from information_schema.columns; show create table big_table\G insert into big_table select * from big_table; insert into big_table select * from big_table; insert into big_table select * from big_table; insert into big_table select * from big_table; insert into big_table select * from big_table; insert into big_table select * from big_table; insert into big_table select * from big_table; insert into big_table select * from big_table; insert into big_table select * from big_table; insert into big_table select * from big_table; commit; alter table big_table add id int unsigned not null primary key auto_increment; select count(id) from big_table;
Running this code gives this output, condensed for brevity and with the most important points bolded:
Setting up 'small' table: Query OK, 0 rows affected (0.01 sec) Query OK, 1678 rows affected (0.13 sec) Records: 1678 Duplicates: 0 Warnings: 0 Query OK, 1678 rows affected (0.07 sec) Records: 1678 Duplicates: 0 Warnings: 0 +-----------+ | count(id) | +-----------+ | 1678 | +-----------+ 1 row in set (0.00 sec) Setting up 'big' table: Query OK, 0 rows affected (0.16 sec) Query OK, 1678 rows affected (0.17 sec) Records: 1678 Duplicates: 0 Warnings: 0 *************************** 1. row *************************** Table: big_table Create Table: CREATE TABLE `big_table` ( `TABLE_CATALOG` varchar(512) CHARACTER SET utf8 NOT NULL DEFAULT '', `TABLE_SCHEMA` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `TABLE_NAME` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `COLUMN_NAME` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `ORDINAL_POSITION` bigint(21) unsigned NOT NULL DEFAULT '0', `COLUMN_DEFAULT` longtext CHARACTER SET utf8, `IS_NULLABLE` varchar(3) CHARACTER SET utf8 NOT NULL DEFAULT '', `DATA_TYPE` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `CHARACTER_MAXIMUM_LENGTH` bigint(21) unsigned DEFAULT NULL, `CHARACTER_OCTET_LENGTH` bigint(21) unsigned DEFAULT NULL, `NUMERIC_PRECISION` bigint(21) unsigned DEFAULT NULL, `NUMERIC_SCALE` bigint(21) unsigned DEFAULT NULL, `DATETIME_PRECISION` bigint(21) unsigned DEFAULT NULL, `CHARACTER_SET_NAME` varchar(32) CHARACTER SET utf8 DEFAULT NULL, `COLLATION_NAME` varchar(32) CHARACTER SET utf8 DEFAULT NULL, `COLUMN_TYPE` longtext CHARACTER SET utf8 NOT NULL, `COLUMN_KEY` varchar(3) CHARACTER SET utf8 NOT NULL DEFAULT '', `EXTRA` varchar(30) CHARACTER SET utf8 NOT NULL DEFAULT '', `PRIVILEGES` varchar(80) CHARACTER SET utf8 NOT NULL DEFAULT '', `COLUMN_COMMENT` varchar(1024) CHARACTER SET utf8 NOT NULL DEFAULT '' ) ENGINE=InnoDB DEFAULT CHARSET=latin1 1 row in set (0.00 sec) Query OK, 1678 rows affected (0.09 sec) Records: 1678 Duplicates: 0 Warnings: 0 Query OK, 3356 rows affected (0.07 sec) Records: 3356 Duplicates: 0 Warnings: 0 Query OK, 6712 rows affected (0.17 sec) Records: 6712 Duplicates: 0 Warnings: 0 Query OK, 13424 rows affected (0.44 sec) Records: 13424 Duplicates: 0 Warnings: 0 Query OK, 26848 rows affected (0.63 sec) Records: 26848 Duplicates: 0 Warnings: 0 Query OK, 53696 rows affected (1.72 sec) Records: 53696 Duplicates: 0 Warnings: 0 Query OK, 107392 rows affected (3.02 sec) Records: 107392 Duplicates: 0 Warnings: 0 Query OK, 214784 rows affected (6.28 sec) Records: 214784 Duplicates: 0 Warnings: 0 Query OK, 429568 rows affected (13.25 sec) Records: 429568 Duplicates: 0 Warnings: 0 Query OK, 859136 rows affected (28.16 sec) Records: 859136 Duplicates: 0 Warnings: 0 Query OK, 0 rows affected (0.03 sec) Query OK, 1718272 rows affected (1 min 9.22 sec) Records: 1718272 Duplicates: 0 Warnings: 0 +-----------+ | count(id) | +-----------+ | 1718272 | +-----------+ 1 row in set (1.75 sec)
Пример 16.2. Скорость и эффективность CREATE INDEX и DROP INDEX
Вот последовательность запросов, демонстрирующих относительную скорость
CREATE INDEX
и
DROP INDEX
.
Для маленькой таблицы прошедшее время меньше, чем секунда, используем ли мы
быстрый или медленный метод, таким образом, мы смотрим на rows
affected, чтобы проверить, какие операции могут избежать
пересоздания таблицы. Для большой таблицы различие в эффективности очевидно,
потому что пропуск пересоздания таблицы экономит существенное время.
\! clear \! echo "=== Create and drop index (small table, new/fast technique) ===" \! echo \! echo "Data size (kilobytes) before index created: " \! du -k data/test/small_table.ibd create index i_dtyp_small on small_table (data_type), algorithm=inplace; \! echo "Data size after index created: " \! du -k data/test/small_table.ibd drop index i_dtyp_small on small_table, algorithm=inplace; -- Compare against the older slower DDL. \! echo "=== Create and drop index (small table, old/slow technique) ===" \! echo \! echo "Data size (kilobytes) before index created: " \! du -k data/test/small_table.ibd create index i_dtyp_small on small_table (data_type), algorithm=copy; \! echo "Data size after index created: " \! du -k data/test/small_table.ibd drop index i_dtyp_small on small_table, algorithm=copy; -- In the above example, we examined the "rows affected" number, -- ideally looking for a zero figure. Let's try again with a larger -- sample size, where we'll see that the actual time taken can -- vary significantly. \! echo "=== Create and drop index (big table, new/fast technique) ===" \! echo \! echo "Data size (kilobytes) before index created: " \! du -k data/test/big_table.ibd create index i_dtyp_big on big_table (data_type), algorithm=inplace; \! echo "Data size after index created: " \! du -k data/test/big_table.ibd drop index i_dtyp_big on big_table, algorithm=inplace; \! echo "=== Create and drop index (big table, old/slow technique) ===" \! echo \! echo "Data size (kilobytes) before index created: " \! du -k data/test/big_table.ibd create index i_dtyp_big on big_table (data_type), algorithm=copy; \! echo "Data size after index created: " \! du -k data/test/big_table.ibd drop index i_dtyp_big on big_table, algorithm=copy;
Выполнение этого кода дает этот вывод, сжатый для краткости и с выделенными наиболее важными моментами:
Query OK, 0 rows affected (0.00 sec) === Create and drop index (small table, new/fast technique) === Data size (kilobytes) before index created: 384 data/test/small_table.ibd Query OK, 0 rows affected (0.04 sec) Records: 0 Duplicates: 0 Warnings: 0 Data size after index created: 432 data/test/small_table.ibd Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 Query OK, 0 rows affected (0.00 sec) === Create and drop index (small table, old/slow technique) === Data size (kilobytes) before index created: 432 data/test/small_table.ibd Query OK, 1678 rows affected (0.12 sec) Records: 1678 Duplicates: 0 Warnings: 0 Data size after index created: 448 data/test/small_table.ibd Query OK, 1678 rows affected (0.10 sec) Records: 1678 Duplicates: 0 Warnings: 0 Query OK, 0 rows affected (0.00 sec) === Create and drop index (big table, new/fast technique) === Data size (kilobytes) before index created: 315392 data/test/big_table.ibd Query OK, 0 rows affected (33.32 sec) Records: 0 Duplicates: 0 Warnings: 0 Data size after index created: 335872 data/test/big_table.ibd Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 Query OK, 0 rows affected (0.00 sec) === Create and drop index (big table, old/slow technique) === Data size (kilobytes) before index created: 335872 data/test/big_table.ibd Query OK, 1718272 rows affected (1 min 5.01 sec) Records: 1718272 Duplicates: 0 Warnings: 0 Data size after index created: 348160 data/test/big_table.ibd Query OK, 1718272 rows affected (46.59 sec) Records: 1718272 Duplicates: 0 Warnings: 0
Пример 16.3. Параллельные DML во время DML CREATE INDEX и DROP INDEX
Вот некоторые отрывки кода, которые выполнены в отдельных сессиях
mysql,
соединенных с той же самой базой данных, чтобы иллюстрировать запрос DML
(вставка, обновление или удаление), работающий в то же самое время, как
CREATE INDEX
и
DROP INDEX
.
/* CREATE INDEX statement to run against a table while insert/update/delete statements are modifying the column being indexed. */ -- Run this script in one session, while simultaneously creating and dropping -- an index on test/big_table.table_name in another session. use test; create index i_concurrent on big_table(table_name); /* DROP INDEX statement to run against a table while insert/update/delete statements are modifying the column being indexed. */ -- Run this script in one session, while simultaneously creating and dropping -- an index on test/big_table.table_name in another session. use test; drop index i_concurrent on big_table; /* Some queries and insert/update/delete statements to run against a table while an index is being created or dropped. Previously, these operations would have stalled during the index create/drop period and possibly timed out or deadlocked. */ -- Run this script in one session, while simultaneously creating and dropping -- an index on test/big_table.table_name in another session. -- In the test instance, that column has about 1.7M rows, with 136 different values. -- Sample values: COLUMNS (20480), ENGINES (6144), EVENTS (24576), FILES (38912), -- TABLES (21504), VIEWS (10240). set autocommit = 0; use test; select distinct character_set_name from big_table where table_name = 'FILES'; delete from big_table where table_name = 'FILES'; select distinct character_set_name from big_table where table_name = 'FILES'; -- I'll issue the final rollback interactively, not via script, -- the better to control the timing. -- rollback;
Выполнение этого кода дает этот вывод, сжатый для краткости и с выделенными наиболее важными моментами:
mysql: source concurrent_ddl_create.sql Database changed Query OK, 0 rows affected (1 min 25.15 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql: source concurrent_ddl_drop.sql Database changed Query OK, 0 rows affected (24.98 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql: source concurrent_dml.sql Query OK, 0 rows affected (0.00 sec) Database changed +--------------------+ | character_set_name | +--------------------+ | NULL | | utf8 | +--------------------+ 2 rows in set (0.32 sec) Query OK, 38912 rows affected (1.84 sec) Empty set (0.01 sec) mysql: rollback; Query OK, 0 rows affected (1.05 sec)
Пример 16.4. Переименование столбца
Вот демонстрация использования ALTER
TABLE
, чтобы переименовать столбец. Мы используем новый быстрый
механизм DDL, чтобы изменить название, потом старый механизм DDL (с
old_alter_table=1
), чтобы восстановить оригинальное имя столбца.
Замечания:
Поскольку синтаксис для того, чтобы переименовать столбец также
вовлекает переопределение типа данных, надо определить точно тот же самый тип
данных, чтобы избежать пересоздания таблицы. В этом случае смотрим вывод
show create table
и важные
параметры table
\GCHARACTER SET
и NOT NULL
берем из
оригинального определения столбца.
/* Run through a sequence of 'rename column' statements. Because this operation involves only metadata, not table data, it is fast for big and small tables, with new or old DDL mechanisms. */ \! clear \! echo "Rename column (fast technique, small table):" alter table small_table change `IS_NULLABLE` `NULLABLE` varchar(3) character set utf8 not null, algorithm=inplace; \! echo "Rename back to original name (slow technique):" alter table small_table change `NULLABLE` `IS_NULLABLE` varchar(3) character set utf8 not null, algorithm=copy; \! echo "Rename column (fast technique, big table):" alter table big_table change `IS_NULLABLE` `NULLABLE` varchar(3) character set utf8 not null, algorithm=inplace; \! echo "Rename back to original name (slow technique):" alter table big_table change `NULLABLE` `IS_NULLABLE` varchar(3) character set utf8 not null, algorithm=copy;
Выполнение этого кода дает этот вывод, сжатый для краткости и с выделенными наиболее важными моментами:
Rename column (fast technique, small table): Query OK, 0 rows affected (0.05 sec) Query OK, 0 rows affected (0.13 sec) Records: 0 Duplicates: 0 Warnings: 0 Rename back to original name (slow technique): Query OK, 0 rows affected (0.00 sec) Query OK, 1678 rows affected (0.35 sec) Records: 1678 Duplicates: 0 Warnings: 0 Rename column (fast technique, big table): Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.11 sec) Records: 0 Duplicates: 0 Warnings: 0 Rename back to original name (slow technique): Query OK, 0 rows affected (0.00 sec) Query OK, 1718272 rows affected (1 min 0.00 sec) Records: 1718272 Duplicates: 0 Warnings: 0 Query OK, 0 rows affected (0.00 sec)
Пример 16.5. Удаление Foreign Keys
Вот демонстрация внешних ключей, включая усовершенствование скорости удаления ограничения внешнего ключа.
/* Demonstrate aspects of foreign keys that are or aren't affected by the DDL improvements. - Create a new table with only a few values to serve as the parent table. - Set up the 'small' and 'big' tables as child tables using a foreign key. - Verify that the ON DELETE CASCADE clause makes changes ripple from parent to child tables. - Drop the foreign key constraints, and optionally associated indexes. (This is the operation that is sped up.) */ \! clear -- Make sure foreign keys are being enforced, and allow -- rollback after doing some DELETEs that affect both -- parent and child tables. set foreign_key_checks = 1; set autocommit = 0; -- Create a parent table, containing values that we know are already present -- in the child tables. drop table if exists schema_names; create table schema_names (id int unsigned not null primary key auto_increment, schema_name varchar(64) character set utf8 not null, index i_schema (schema_name)) as select distinct table_schema schema_name from small_table; show create table schema_names\G show create table small_table\G show create table big_table\G -- Creating the foreign key constraint still involves a table rebuild when foreign_key_checks=1, -- as illustrated by the "rows affected" figure. alter table small_table add constraint small_fk foreign key i_table_schema (table_schema) references schema_names(schema_name) on delete cascade; alter table big_table add constraint big_fk foreign key i_table_schema (table_schema) references schema_names(schema_name) on delete cascade; show create table small_table\G show create table big_table\G select schema_name from schema_names order by schema_name; select count(table_schema) howmany, table_schema from small_table group by table_schema; select count(table_schema) howmany, table_schema from big_table group by table_schema; -- big_table is the parent table. -- schema_names is the parent table. -- big_table is the child table. -- (One row in the parent table can have many "children" in the child table.) -- Changes to the parent table can ripple through to the child table. -- For example, removing the value 'test' from schema_names.schema_name will -- result in the removal of 20K or so rows from big_table. delete from schema_names where schema_name = 'test'; select schema_name from schema_names order by schema_name; select count(table_schema) howmany, table_schema from small_table group by table_schema; select count(table_schema) howmany, table_schema from big_table group by table_schema; -- Because we've turned off autocommit, we can still get back those deleted rows -- if the DELETE was issued by mistake. rollback; select schema_name from schema_names order by schema_name; select count(table_schema) howmany, table_schema from small_table group by table_schema; select count(table_schema) howmany, table_schema from big_table group by table_schema; -- All of the cross-checking between parent and child tables would be -- deadly slow if there wasn't the requirement for the corresponding -- columns to be indexed! -- But we can get rid of the foreign key using a fast operation -- that doesn't rebuild the table. -- If we didn't specify a constraint name when setting up the foreign key, we would -- have to find the auto-generated name such as 'big_table_ibfk_1' in the -- output from 'show create table'. -- For the small table, drop the foreign key and the associated index. -- Having an index on a small table is less critical. \! echo "DROP FOREIGN KEY and INDEX from small_table:" alter table small_table drop foreign key small_fk, drop index small_fk; -- For the big table, drop the foreign key and leave the associated index. -- If we are still doing queries that reference the indexed column, the index is -- very important to avoid a full table scan of the big table. \! echo "DROP FOREIGN KEY from big_table:" alter table big_table drop foreign key big_fk; show create table small_table\G show create table big_table\G
Выполнение этого кода дает этот вывод, сжатый для краткости и с выделенными наиболее важными моментами:
Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.01 sec) Query OK, 4 rows affected (0.03 sec) Records: 4 Duplicates: 0 Warnings: 0 *************************** 1. row *************************** Table: schema_names Create Table: CREATE TABLE `schema_names` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `schema_name` varchar(64) CHARACTER SET utf8 NOT NULL, PRIMARY KEY (`id`), KEY `i_schema` (`schema_name`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) *************************** 1. row *************************** Table: small_table Create Table: CREATE TABLE `small_table` ( `TABLE_CATALOG` varchar(512) CHARACTER SET utf8 NOT NULL DEFAULT '', `TABLE_SCHEMA` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `TABLE_NAME` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `COLUMN_NAME` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `ORDINAL_POSITION` bigint(21) unsigned NOT NULL DEFAULT '0', `COLUMN_DEFAULT` longtext CHARACTER SET utf8, `IS_NULLABLE` varchar(3) CHARACTER SET utf8 NOT NULL, `DATA_TYPE` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `CHARACTER_MAXIMUM_LENGTH` bigint(21) unsigned DEFAULT NULL, `CHARACTER_OCTET_LENGTH` bigint(21) unsigned DEFAULT NULL, `NUMERIC_PRECISION` bigint(21) unsigned DEFAULT NULL, `NUMERIC_SCALE` bigint(21) unsigned DEFAULT NULL, `DATETIME_PRECISION` bigint(21) unsigned DEFAULT NULL, `CHARACTER_SET_NAME` varchar(32) CHARACTER SET utf8 DEFAULT NULL, `COLLATION_NAME` varchar(32) CHARACTER SET utf8 DEFAULT NULL, `COLUMN_TYPE` longtext CHARACTER SET utf8 NOT NULL, `COLUMN_KEY` varchar(3) CHARACTER SET utf8 NOT NULL DEFAULT '', `EXTRA` varchar(30) CHARACTER SET utf8 NOT NULL DEFAULT '', `PRIVILEGES` varchar(80) CHARACTER SET utf8 NOT NULL DEFAULT '', `COLUMN_COMMENT` varchar(1024) CHARACTER SET utf8 NOT NULL DEFAULT '', `id` int(10) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1679 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) *************************** 1. row *************************** Table: big_table Create Table: CREATE TABLE `big_table` ( `TABLE_CATALOG` varchar(512) CHARACTER SET utf8 NOT NULL DEFAULT '', `TABLE_SCHEMA` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `TABLE_NAME` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `COLUMN_NAME` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `ORDINAL_POSITION` bigint(21) unsigned NOT NULL DEFAULT '0', `COLUMN_DEFAULT` longtext CHARACTER SET utf8, `IS_NULLABLE` varchar(3) CHARACTER SET utf8 NOT NULL, `DATA_TYPE` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `CHARACTER_MAXIMUM_LENGTH` bigint(21) unsigned DEFAULT NULL, `CHARACTER_OCTET_LENGTH` bigint(21) unsigned DEFAULT NULL, `NUMERIC_PRECISION` bigint(21) unsigned DEFAULT NULL, `NUMERIC_SCALE` bigint(21) unsigned DEFAULT NULL, `DATETIME_PRECISION` bigint(21) unsigned DEFAULT NULL, `CHARACTER_SET_NAME` varchar(32) CHARACTER SET utf8 DEFAULT NULL, `COLLATION_NAME` varchar(32) CHARACTER SET utf8 DEFAULT NULL, `COLUMN_TYPE` longtext CHARACTER SET utf8 NOT NULL, `COLUMN_KEY` varchar(3) CHARACTER SET utf8 NOT NULL DEFAULT '', `EXTRA` varchar(30) CHARACTER SET utf8 NOT NULL DEFAULT '', `PRIVILEGES` varchar(80) CHARACTER SET utf8 NOT NULL DEFAULT '', `COLUMN_COMMENT` varchar(1024) CHARACTER SET utf8 NOT NULL DEFAULT '', `id` int(10) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`), KEY `big_fk` (`TABLE_SCHEMA`) ) ENGINE=InnoDB AUTO_INCREMENT=1718273 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) Query OK, 1678 rows affected (0.10 sec) Records: 1678 Duplicates: 0 Warnings: 0 Query OK, 1718272 rows affected (1 min 14.54 sec) Records: 1718272 Duplicates: 0 Warnings: 0 *************************** 1. row *************************** Table: small_table Create Table: CREATE TABLE `small_table` ( `TABLE_CATALOG` varchar(512) CHARACTER SET utf8 NOT NULL DEFAULT '', `TABLE_SCHEMA` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `TABLE_NAME` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `COLUMN_NAME` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `ORDINAL_POSITION` bigint(21) unsigned NOT NULL DEFAULT '0', `COLUMN_DEFAULT` longtext CHARACTER SET utf8, `IS_NULLABLE` varchar(3) CHARACTER SET utf8 NOT NULL, `DATA_TYPE` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `CHARACTER_MAXIMUM_LENGTH` bigint(21) unsigned DEFAULT NULL, `CHARACTER_OCTET_LENGTH` bigint(21) unsigned DEFAULT NULL, `NUMERIC_PRECISION` bigint(21) unsigned DEFAULT NULL, `NUMERIC_SCALE` bigint(21) unsigned DEFAULT NULL, `DATETIME_PRECISION` bigint(21) unsigned DEFAULT NULL, `CHARACTER_SET_NAME` varchar(32) CHARACTER SET utf8 DEFAULT NULL, `COLLATION_NAME` varchar(32) CHARACTER SET utf8 DEFAULT NULL, `COLUMN_TYPE` longtext CHARACTER SET utf8 NOT NULL, `COLUMN_KEY` varchar(3) CHARACTER SET utf8 NOT NULL DEFAULT '', `EXTRA` varchar(30) CHARACTER SET utf8 NOT NULL DEFAULT '', `PRIVILEGES` varchar(80) CHARACTER SET utf8 NOT NULL DEFAULT '', `COLUMN_COMMENT` varchar(1024) CHARACTER SET utf8 NOT NULL DEFAULT '', `id` int(10) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`), KEY `small_fk` (`TABLE_SCHEMA`), CONSTRAINT `small_fk` FOREIGN KEY (`TABLE_SCHEMA`) REFERENCES `schema_names` (`schema_name`) ON DELETE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=1679 DEFAULT CHARSET=latin1 1 row in set (0.12 sec) *************************** 1. row *************************** Table: big_table Create Table: CREATE TABLE `big_table` ( `TABLE_CATALOG` varchar(512) CHARACTER SET utf8 NOT NULL DEFAULT '', `TABLE_SCHEMA` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `TABLE_NAME` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `COLUMN_NAME` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `ORDINAL_POSITION` bigint(21) unsigned NOT NULL DEFAULT '0', `COLUMN_DEFAULT` longtext CHARACTER SET utf8, `IS_NULLABLE` varchar(3) CHARACTER SET utf8 NOT NULL, `DATA_TYPE` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `CHARACTER_MAXIMUM_LENGTH` bigint(21) unsigned DEFAULT NULL, `CHARACTER_OCTET_LENGTH` bigint(21) unsigned DEFAULT NULL, `NUMERIC_PRECISION` bigint(21) unsigned DEFAULT NULL, `NUMERIC_SCALE` bigint(21) unsigned DEFAULT NULL, `DATETIME_PRECISION` bigint(21) unsigned DEFAULT NULL, `CHARACTER_SET_NAME` varchar(32) CHARACTER SET utf8 DEFAULT NULL, `COLLATION_NAME` varchar(32) CHARACTER SET utf8 DEFAULT NULL, `COLUMN_TYPE` longtext CHARACTER SET utf8 NOT NULL, `COLUMN_KEY` varchar(3) CHARACTER SET utf8 NOT NULL DEFAULT '', `EXTRA` varchar(30) CHARACTER SET utf8 NOT NULL DEFAULT '', `PRIVILEGES` varchar(80) CHARACTER SET utf8 NOT NULL DEFAULT '', `COLUMN_COMMENT` varchar(1024) CHARACTER SET utf8 NOT NULL DEFAULT '', `id` int(10) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`), KEY `big_fk` (`TABLE_SCHEMA`), CONSTRAINT `big_fk` FOREIGN KEY (`TABLE_SCHEMA`) REFERENCES `schema_names` (`schema_name`) ON DELETE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=1718273 DEFAULT CHARSET=latin1 1 row in set (0.01 sec) +--------------------+ | schema_name | +--------------------+ | information_schema | | mysql | | performance_schema | | test | +--------------------+ 4 rows in set (0.00 sec) +---------+--------------------+ | howmany | table_schema | +---------+--------------------+ | 563 | information_schema | | 286 | mysql | | 786 | performance_schema | | 43 | test | +---------+--------------------+ 4 rows in set (0.01 sec) +---------+--------------------+ | howmany | table_schema | +---------+--------------------+ | 576512 | information_schema | | 292864 | mysql | | 804864 | performance_schema | | 44032 | test | +---------+--------------------+ 4 rows in set (2.10 sec) Query OK, 1 row affected (1.52 sec) +--------------------+ | schema_name | +--------------------+ | information_schema | | mysql | | performance_schema | +--------------------+ 3 rows in set (0.00 sec) +---------+--------------------+ | howmany | table_schema | +---------+--------------------+ | 563 | information_schema | | 286 | mysql | | 786 | performance_schema | +---------+--------------------+ 3 rows in set (0.00 sec) +---------+--------------------+ | howmany | table_schema | +---------+--------------------+ | 576512 | information_schema | | 292864 | mysql | | 804864 | performance_schema | +---------+--------------------+ 3 rows in set (1.74 sec) Query OK, 0 rows affected (0.60 sec) +--------------------+ | schema_name | +--------------------+ | information_schema | | mysql | | performance_schema | | test | +--------------------+ 4 rows in set (0.00 sec) +---------+--------------------+ | howmany | table_schema | +---------+--------------------+ | 563 | information_schema | | 286 | mysql | | 786 | performance_schema | | 43 | test | +---------+--------------------+ 4 rows in set (0.01 sec) +---------+--------------------+ | howmany | table_schema | +---------+--------------------+ | 576512 | information_schema | | 292864 | mysql | | 804864 | performance_schema | | 44032 | test | +---------+--------------------+ 4 rows in set (1.59 sec) DROP FOREIGN KEY and INDEX from small_table: Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 DROP FOREIGN KEY from big_table: Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0 *************************** 1. row *************************** Table: small_table Create Table: CREATE TABLE `small_table` ( `TABLE_CATALOG` varchar(512) CHARACTER SET utf8 NOT NULL DEFAULT '', `TABLE_SCHEMA` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `TABLE_NAME` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `COLUMN_NAME` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `ORDINAL_POSITION` bigint(21) unsigned NOT NULL DEFAULT '0', `COLUMN_DEFAULT` longtext CHARACTER SET utf8, `IS_NULLABLE` varchar(3) CHARACTER SET utf8 NOT NULL, `DATA_TYPE` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `CHARACTER_MAXIMUM_LENGTH` bigint(21) unsigned DEFAULT NULL, `CHARACTER_OCTET_LENGTH` bigint(21) unsigned DEFAULT NULL, `NUMERIC_PRECISION` bigint(21) unsigned DEFAULT NULL, `NUMERIC_SCALE` bigint(21) unsigned DEFAULT NULL, `DATETIME_PRECISION` bigint(21) unsigned DEFAULT NULL, `CHARACTER_SET_NAME` varchar(32) CHARACTER SET utf8 DEFAULT NULL, `COLLATION_NAME` varchar(32) CHARACTER SET utf8 DEFAULT NULL, `COLUMN_TYPE` longtext CHARACTER SET utf8 NOT NULL, `COLUMN_KEY` varchar(3) CHARACTER SET utf8 NOT NULL DEFAULT '', `EXTRA` varchar(30) CHARACTER SET utf8 NOT NULL DEFAULT '', `PRIVILEGES` varchar(80) CHARACTER SET utf8 NOT NULL DEFAULT '', `COLUMN_COMMENT` varchar(1024) CHARACTER SET utf8 NOT NULL DEFAULT '', `id` int(10) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=1679 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) *************************** 1. row *************************** Table: big_table Create Table: CREATE TABLE `big_table` ( `TABLE_CATALOG` varchar(512) CHARACTER SET utf8 NOT NULL DEFAULT '', `TABLE_SCHEMA` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `TABLE_NAME` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `COLUMN_NAME` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `ORDINAL_POSITION` bigint(21) unsigned NOT NULL DEFAULT '0', `COLUMN_DEFAULT` longtext CHARACTER SET utf8, `IS_NULLABLE` varchar(3) CHARACTER SET utf8 NOT NULL, `DATA_TYPE` varchar(64) CHARACTER SET utf8 NOT NULL DEFAULT '', `CHARACTER_MAXIMUM_LENGTH` bigint(21) unsigned DEFAULT NULL, `CHARACTER_OCTET_LENGTH` bigint(21) unsigned DEFAULT NULL, `NUMERIC_PRECISION` bigint(21) unsigned DEFAULT NULL, `NUMERIC_SCALE` bigint(21) unsigned DEFAULT NULL, `DATETIME_PRECISION` bigint(21) unsigned DEFAULT NULL, `CHARACTER_SET_NAME` varchar(32) CHARACTER SET utf8 DEFAULT NULL, `COLLATION_NAME` varchar(32) CHARACTER SET utf8 DEFAULT NULL, `COLUMN_TYPE` longtext CHARACTER SET utf8 NOT NULL, `COLUMN_KEY` varchar(3) CHARACTER SET utf8 NOT NULL DEFAULT '', `EXTRA` varchar(30) CHARACTER SET utf8 NOT NULL DEFAULT '', `PRIVILEGES` varchar(80) CHARACTER SET utf8 NOT NULL DEFAULT '', `COLUMN_COMMENT` varchar(1024) CHARACTER SET utf8 NOT NULL DEFAULT '', `id` int(10) unsigned NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`), KEY `big_fk` (`TABLE_SCHEMA`) ) ENGINE=InnoDB AUTO_INCREMENT=1718273 DEFAULT CHARSET=latin1 1 row in set (0.00 sec)
Пример 16.6. Изменение значений Auto-Increment
Вот иллюстрация увеличения нижнего предела
auto-increment
для столбца таблицы, демонстрируя, как эта работа теперь обходит
пересоздание таблицы плюс другие факты о столбцах
InnoDB
auto-increment.
/* If this script is run after foreign_key.sql, the schema_names table is already set up. But to allow this script to run multiple times without running into duplicate ID errors, we set up the schema_names table all over again. */ \! clear \! echo "=== Adjusting the Auto-Increment Limit for a Table ===" \! echo drop table if exists schema_names; create table schema_names (id int unsigned not null primary key auto_increment, schema_name varchar(64) character set utf8 not null, index i_schema (schema_name)) as select distinct table_schema schema_name from small_table; \! echo "Initial state of schema_names table." \! echo "AUTO_INCREMENT is included in SHOW CREATE TABLE output." \! echo "Note how MySQL reserved a block of IDs." \! echo "Only 4 IDs are needed in this transaction. The next inserted values get IDs 8 and 9." show create table schema_names\G select * from schema_names order by id; \! echo "Inserting even a tiny amount of data can produce gaps in the ID sequence." insert into schema_names (schema_name) values ('eight'), ('nine'); \! echo "Bumping auto-increment lower limit to 20 (fast mechanism):" alter table schema_names auto_increment=20, algorithm=inplace; \! echo "Inserting 2 rows that should get IDs 20 and 21:" insert into schema_names (schema_name) values ('foo'), ('bar'); commit; \! echo "Bumping auto-increment lower limit to 30 (slow mechanism):" alter table schema_names auto_increment=30, algorithm=copy; \! echo "Inserting 2 rows that should get IDs 30 and 31:" insert into schema_names (schema_name) values ('bletch'),('baz'); commit; select * from schema_names order by id; \! echo "Final state of schema_names table." \! echo "AUTO_INCREMENT value shows the next inserted row would get ID=32." show create table schema_names\G
Выполнение этого кода дает этот вывод, сжатый для краткости и с выделенными наиболее важными моментами:
=== Adjusting the Auto-Increment Limit for a Table === Query OK, 0 rows affected (0.01 sec) Query OK, 4 rows affected (0.02 sec) Records: 4 Duplicates: 0 Warnings: 0 Initial state of schema_names table. AUTO_INCREMENT is included in SHOW CREATE TABLE output. Note how MySQL reserved a block of IDs. Only 4 IDs are needed in this transaction. The next inserted values get IDs 8 and 9. *************************** 1. row *************************** Table: schema_names Create Table: CREATE TABLE `schema_names` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `schema_name` varchar(64) CHARACTER SET utf8 NOT NULL, PRIMARY KEY (`id`), KEY `i_schema` (`schema_name`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) +----+--------------------+ | id | schema_name | +----+--------------------+ | 1 | information_schema | | 2 | mysql | | 3 | performance_schema | | 4 | test | +----+--------------------+ 4 rows in set (0.00 sec) Inserting even a tiny amount of data can produce gaps in the ID sequence. Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 Query OK, 0 rows affected (0.00 sec) Bumping auto-increment lower limit to 20 (fast mechanism): Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 Inserting 2 rows that should get IDs 20 and 21: Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.00 sec) Bumping auto-increment lower limit to 30 (slow mechanism): Query OK, 8 rows affected (0.02 sec) Records: 8 Duplicates: 0 Warnings: 0 Inserting 2 rows that should get IDs 30 and 31: Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 Query OK, 0 rows affected (0.01 sec) +----+--------------------+ | id | schema_name | +----+--------------------+ | 1 | information_schema | | 2 | mysql | | 3 | performance_schema | | 4 | test | | 8 | eight | | 9 | nine | | 20 | foo | | 21 | bar | | 30 | bletch | | 31 | baz | +----+--------------------+ 10 rows in set (0.00 sec) Query OK, 0 rows affected (0.00 sec) Final state of schema_names table. AUTO_INCREMENT value shows the next inserted row would get ID=32. *************************** 1. row *************************** Table: schema_names Create Table: CREATE TABLE `schema_names` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `schema_name` varchar(64) CHARACTER SET utf8 NOT NULL, PRIMARY KEY (`id`), KEY `i_schema` (`schema_name`) ) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=latin1 1 row in set (0.00 sec)
Пример 16.7. Параллелизм управления с LOCK
Этот пример показывает, как использовать LOCK
в
ALTER TABLE
, чтобы позволить
или лишить параллельного доступа к таблице, в то время как происходит работа
DDL онлайн. Есть настройки, которые позволяют запросы
DML (LOCK=NONE
), только
запросы (LOCK=SHARED
) или
никакой параллельный доступ вообще (LOCK=EXCLUSIVE
).
В одном сеансе мы выполняем последовательность
ALTER TABLE
, чтобы создать и
удалить индекс, используя различные значения для LOCK
, чтобы
видеть, что происходит с ожиданием или заведением в тупик в любом сеансе. Мы
используем ту же самую таблицу BIG_TABLE
, как в предыдущих
примерах, запускающихся приблизительно с 1.7 миллионов строк. В целях
иллюстрации мы индексируем и запросим столбец IS_NULLABLE
.
Хотя в действительности было бы глупо сделать индексирование для крошечного
столбца только с 2 отличными значениями.
mysql: desc big_table; +------------------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------------+---------------------+------+-----+---------+-------+ | TABLE_CATALOG | varchar(512) | NO | | | | | TABLE_SCHEMA | varchar(64) | NO | | | | | TABLE_NAME | varchar(64) | NO | | | | | COLUMN_NAME | varchar(64) | NO | | | | | ORDINAL_POSITION | bigint(21) unsigned | NO | | 0 | | | COLUMN_DEFAULT | longtext | YES | | NULL | | | IS_NULLABLE | varchar(3) | NO | | | | ... +------------------+---------------------+------+-----+---------+-------+ 21 rows in set (0.14 sec) mysql: alter table big_table add index i1(is_nullable); Query OK, 0 rows affected (20.71 sec) mysql: alter table big_table drop index i1; Query OK, 0 rows affected (0.02 sec) mysql: alter table big_table add index i1(is_nullable), lock=exclusive; Query OK, 0 rows affected (19.44 sec) mysql: alter table big_table drop index i1; Query OK, 0 rows affected (0.03 sec) mysql: alter table big_table add index i1(is_nullable), lock=shared; Query OK, 0 rows affected (16.71 sec) mysql: alter table big_table drop index i1; Query OK, 0 rows affected (0.05 sec) mysql: alter table big_table add index i1(is_nullable), lock=none; Query OK, 0 rows affected (12.26 sec) mysql: alter table big_table drop index i1; Query OK, 0 rows affected (0.01 sec) ... repeat statements like the above while running queries ... ... and DML statements at the same time in another session ...
Ничто драматическое не происходит в сеансе, выполняющем запросы DDL.
Иногда ALTER TABLE
работает необычно долго, потому что это ждет завершения другой транзакции,
так как та транзакция изменила таблицу во время DDL или запросила
таблицу перед DDL:
mysql: alter table big_table add index i1(is_nullable), lock=none; Query OK, 0 rows affected (59.27 sec) mysql: -- The previous ALTER took so long because it was waiting for all the concurrent mysql: -- transactions to commit or roll back. mysql: alter table big_table drop index i1; Query OK, 0 rows affected (41.05 sec) mysql: -- Even doing a SELECT on the table in the other session first causes mysql: -- the ALTER TABLE above to stall until the transaction mysql: -- surrounding the SELECT is committed or rolled back.
Вот журнал от другого сеанса, работающего одновременно, где мы выпускаем
запросы данных и запросы DML для таблицы прежде, во время и после операций
DDL, показанных в предыдущих примерах. Первый листинг показывает только
запросы. Мы ожидаем, что запросы будут позволены во время использования
операций DDL через LOCK=NONE
или LOCK=SHARED
,
и запроса будет ждать, пока DDL не закончен, если
ALTER TABLE
включает
LOCK=EXCLUSIVE
.
mysql: show variables like 'autocommit'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | autocommit | ON | +---------------+-------+ 1 row in set (0.01 sec) mysql: -- A trial query before any ADD INDEX in the other session: mysql: -- Note: because autocommit is enabled, each mysql: -- transaction finishes immediately after the query. mysql: select distinct is_nullable from big_table; +-------------+ | is_nullable | +-------------+ | NO | | YES | +-------------+ 2 rows in set (4.49 sec) mysql: -- Index is being created with LOCK=EXCLUSIVE on the ALTER statement. mysql: -- The query waits until the DDL is finished before proceeding. mysql: select distinct is_nullable from big_table; +-------------+ | is_nullable | +-------------+ | NO | | YES | +-------------+ 2 rows in set (17.26 sec) mysql: -- Index is being created with LOCK=SHARED on the ALTER statement. mysql: -- The query returns its results while the DDL is in progress. mysql: -- The same thing happens with LOCK=NONE on the ALTER statement. mysql: select distinct is_nullable from big_table; +-------------+ | is_nullable | +-------------+ | NO | | YES | +-------------+ 2 rows in set (3.11 sec) mysql: -- Once the index is created, and with no DDL in progress, mysql: -- queries referencing the indexed column are very fast: mysql: select count(*) from big_table where is_nullable = 'YES'; +----------+ | count(*) | +----------+ | 411648 | +----------+ 1 row in set (0.20 sec) mysql: select distinct is_nullable from big_table; +-------------+ | is_nullable | +-------------+ | NO | | YES | +-------------+ 2 rows in set (0.00 sec)
Теперь в этом параллельном сеансе, мы выполняем некоторые транзакции,
включая запрос DML или комбинацию запросов DML и запросов данных. Применим
DELETE
, чтобы иллюстрировать
предсказуемые изменения таблицы. Поскольку транзакции в этой части могут
охватить много запросов, мы выполняем эти тесты с выключенным
autocommit
.
mysql: set global autocommit = off; Query OK, 0 rows affected (0.00 sec) mysql: -- Count the rows that will be involved in our DELETE statements: mysql: select count(*) from big_table where is_nullable = 'YES'; +----------+ | count(*) | +----------+ | 411648 | +----------+ 1 row in set (0.95 sec) mysql: -- After this point, any DDL statements back in the other session mysql: -- stall until we commit or roll back. mysql: delete from big_table where is_nullable = 'YES' limit 11648; Query OK, 11648 rows affected (0.14 sec) mysql: select count(*) from big_table where is_nullable = 'YES'; +----------+ | count(*) | +----------+ | 400000 | +----------+ 1 row in set (1.04 sec) mysql: rollback; Query OK, 0 rows affected (0.09 sec) mysql: select count(*) from big_table where is_nullable = 'YES'; +----------+ | count(*) | +----------+ | 411648 | +----------+ 1 row in set (0.93 sec) mysql: -- OK, now we're going to try that during index creation with LOCK=NONE. mysql: delete from big_table where is_nullable = 'YES' limit 11648; Query OK, 11648 rows affected (0.21 sec) mysql: -- We expect that now there will be 400000 'YES' rows left: mysql: select count(*) from big_table where is_nullable = 'YES'; +----------+ | count(*) | +----------+ | 400000 | +----------+ 1 row in set (1.25 sec) mysql: -- In the other session, the ALTER TABLE is waiting before finishing, mysql: -- because _this_ transaction hasn't committed or rolled back yet. mysql: rollback; Query OK, 0 rows affected (0.11 sec) mysql: select count(*) from big_table where is_nullable = 'YES'; +----------+ | count(*) | +----------+ | 411648 | +----------+ 1 row in set (0.19 sec) mysql: -- The ROLLBACK left the table in the same state we originally found it. mysql: -- Now let's make a permanent change while the index is being created, mysql: -- again with ALTER TABLE ... , LOCK=NONE. mysql: -- First, commit so the DROP INDEX in the other shell can finish; mysql: -- the previous SELECT started a transaction that accessed the table. mysql: commit; Query OK, 0 rows affected (0.00 sec) mysql: -- Now we add the index back in the other shell, then issue DML in this one mysql: -- while the DDL is running. mysql: delete from big_table where is_nullable = 'YES' limit 11648; Query OK, 11648 rows affected (0.23 sec) mysql: commit; Query OK, 0 rows affected (0.01 sec) mysql: -- In the other shell, the ADD INDEX has finished. mysql: select count(*) from big_table where is_nullable = 'YES'; +----------+ | count(*) | +----------+ | 400000 | +----------+ 1 row in set (0.19 sec) mysql: -- At the point the new index is finished being created, it contains entries mysql: -- only for the 400000 'YES' rows left when all concurrent transactions are finished. mysql: mysql: -- Now we will run a similar test, while ALTER TABLE ... , LOCK=SHARED is running. mysql: -- We expect a query to complete during the ALTER TABLE, but for the DELETE mysql: -- to run into some kind of issue. mysql: commit; Query OK, 0 rows affected (0.00 sec) mysql: -- As expected, the query returns results while the LOCK=SHARED DDL is running: mysql: select count(*) from big_table where is_nullable = 'YES'; +----------+ | count(*) | +----------+ | 400000 | +----------+ 1 row in set (2.07 sec) mysql: -- The DDL in the other session is not going to finish until this transaction mysql: -- is committed or rolled back. If we tried a DELETE now and it waited because mysql: -- of LOCK=SHARED on the DDL, both transactions would wait forever (deadlock). mysql: -- MySQL detects this condition and cancels the attempted DML statement. mysql: delete from big_table where is_nullable = 'YES' limit 100000; ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction mysql: -- The transaction here is still going, so in the other shell, the ADD INDEX operation mysql: -- is waiting for this transaction to commit or roll back. mysql: rollback; Query OK, 0 rows affected (0.00 sec) mysql: -- Now let's try issuing a query and some DML, on one line, while running mysql: -- ALTER TABLE ... , LOCK=EXCLUSIVE in the other shell. mysql: -- Notice how even the query is held up until the DDL is finished. mysql: -- By the time the DELETE is issued, there is no conflicting access mysql: -- to the table and we avoid the deadlock error. mysql: select count(*) from big_table where is_nullable = 'YES'; delete from big_table where is_nullable = 'YES' limit 100000; +----------+ | count(*) | +----------+ | 400000 | +----------+ 1 row in set (15.98 sec) Query OK, 100000 rows affected (2.81 sec) mysql: select count(*) from big_table where is_nullable = 'YES'; +----------+ | count(*) | +----------+ | 300000 | +----------+ 1 row in set (0.17 sec) mysql: rollback; Query OK, 0 rows affected (1.36 sec) mysql: select count(*) from big_table where is_nullable = 'YES'; +----------+ | count(*) | +----------+ | 400000 | +----------+ 1 row in set (0.19 sec) mysql: commit; Query OK, 0 rows affected (0.00 sec) mysql: -- Next, we try ALTER TABLE ... , LOCK=EXCLUSIVE in the other session mysql: -- and only issue DML, not any query, in the concurrent transaction here. mysql: delete from big_table where is_nullable = 'YES' limit 100000; Query OK, 100000 rows affected (16.37 sec) mysql: -- That was OK because the ALTER TABLE did not have to wait for the transaction mysql: -- here to complete. The DELETE in this session waited until the index was ready. mysql: select count(*) from big_table where is_nullable = 'YES'; +----------+ | count(*) | +----------+ | 300000 | +----------+ 1 row in set (0.16 sec) mysql: commit; Query OK, 0 rows affected (0.00 sec)
В предыдущих примерах мы узнали что:
LOCK
для ALTER
TABLE
отделен от остальной части запроса запятой.
ALTER TABLE
использует
LOCK=NONE
или LOCK=SHARED
.autocommit
.
Если он выключен, сделайте все возможное, чтобы закончить транзакции в других
сеансах (даже только запросы) прежде, чем выполнить операции DDL на таблице.
LOCK=SHARED
параллельные транзакции, которые смешивают
запросы и DML, могли столкнуться с ошибками тупика и быть перезапущенными
после того, как DDL закончен.LOCK=NONE
параллельные транзакции могут свободно смешать
запросы и DML. Работа DDL ждет, пока параллельные транзакции не завершены.
LOCK=EXCLUSIVE
параллельные транзакции могут свободно
смешать запросы и DML, но те транзакции ждут, пока работа DDL не закончена
прежде, чем они смогут получить доступ к таблице.Пример 16.8. Установки схемы для экспериментов DDL онлайн
Вы можете создать много индексов на таблице одним вызовом
ALTER TABLE
.
Это относительно эффективно, потому что кластеризируемый индекс
таблицы должен быть просмотрен только однажды (хотя данные отсортированы
отдельно для каждого нового индекса). Например:
CREATE TABLE T1(A INT PRIMARY KEY, B INT, C CHAR(1)) ENGINE=InnoDB; INSERT INTO T1 VALUES (1,2,'a'), (2,3,'b'), (3,2,'c'), (4,3,'d'), (5,2,'e'); COMMIT; ALTER TABLE T1 ADD INDEX (B), ADD UNIQUE INDEX (C);
Вышеупомянутые запросы составляют таблицу T1
с первичным ключом на столбце A
, вставляют несколько строк,
затем создают два новых индекса на столбцах B
и C
.
Если было много строк, вставленных в
T1
до ALTER
TABLE
, этот подход намного более эффективен, чем создание всех
вторичных индексов прежде, чем загрузить данные.
Поскольку удаление вторичного индекса, также не требует никакого
копирования табличных данных, одинаково эффективно удалить много индексов
одним вызовом ALTER TABLE
или
несколькими DROP INDEX
:
ALTER TABLE T1 DROP INDEX B, DROP INDEX C;
Или:
DROP INDEX B ON T1; DROP INDEX C ON T1;
Пример 16.9. Создание и удаление первичного ключа
Реструктурирование
кластеризируемого индекса всегда требует копирования табличных данных.
Таким образом, лучше определять
primary key, когда Вы
составляете таблицу, вместо ALTER TABLE ... ADD PRIMARY KEY
позже, чтобы избежать пересоздания таблицы.
Определение PRIMARY KEY
позже требует копирования
данных, как в следующем примере:
CREATE TABLE T2 (A INT, B INT); INSERT INTO T2 VALUES (NULL, 1); ALTER TABLE T2 ADD PRIMARY KEY (B);
Когда Вы создаете индекс UNIQUE
или PRIMARY KEY
,
MySQL должен сделать некоторую дополнительную работу. Для UNIQUE
MySQL проверяет, что таблица не содержит двойных значений для ключа. Для
PRIMARY KEY
MySQL также проверяет что ни один из
столбцов PRIMARY KEY
не содержит NULL
.
Когда Вы добавляете первичный ключ, используя
ALGORITHM=COPY
, MySQL фактически преобразовывает
NULL
в связанных столбцах к значениям по умолчанию: 0 для чисел,
пустая строка для символьно-ориентированных столбцов и BLOB, 0000-00-00
00:00:00 для DATETIME
. Это нестандартное поведение, Oracle не
рекомендует на него полагаться. Добавление использования первичного ключа
ALGORITHM=INPLACE
позволено только когда
SQL_MODE
включает
the strict_trans_tables
или
strict_all_tables
, когда SQL_MODE
строгий,
ADD PRIMARY KEY ... , ALGORITHM=INPLACE
позволен, но запрос
может все еще потерпеть неудачу, если требуемые столбцы первичного ключа
содержат NULL
. Поведение ALGORITHM=INPLACE
более стандартно-послушно.
Следующие примеры показывают различные возможности для
ADD PRIMARY KEY
. С ALGORITHM=COPY
работа преуспевает несмотря на присутствие NULL
в столбцах
первичного ключа, данные тихо изменены, что может вызвать проблемы.
mysql> CREATE TABLE add_pk_via_copy (c1 INT, c2 VARCHAR(10), c3 DATETIME); Query OK, 0 rows affected (0.03 sec) mysql> INSERT INTO add_pk_via_copy VALUES (1,'a','2014-11-03 11:01:37'), (NULL,NULL,NULL); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> SET sql_mode = ''; Query OK, 0 rows affected (0.00 sec) mysql> ALTER TABLE add_pk_via_copy ADD PRIMARY KEY (c1,c2,c3), ALGORITHM=COPY; Query OK, 2 rows affected, 3 warnings (0.07 sec) Records: 2 Duplicates: 0 Warnings: 3 mysql> SHOW WARNINGS; +---------+------+-----------------------------------------+ | Level | Code | Message | +---------+------+-----------------------------------------+ | Warning | 1265 | Data truncated for column 'c1' at row 2 | | Warning | 1265 | Data truncated for column 'c2' at row 2 | | Warning | 1265 | Data truncated for column 'c3' at row 2 | +---------+------+-----------------------------------------+ 3 rows in set (0.00 sec) mysql> SELECT * FROM add_pk_via_copy; +----+----+---------------------+ | c1 | c2 | c3 | +----+----+---------------------+ | 0 | | 0000-00-00 00:00:00 | | 1 | a | 2014-11-03 11:01:37 | +----+----+---------------------+ 2 rows in set (0.00 sec)
С ALGORITHM=INPLACE
работа могла потерпеть неудачу по
различным причинам, потому что эта установка считает целостность данных
высоким приоритетом: запрос дает ошибку, если
SQL_MODE
недостаточно
строг, или если столбцы первичного ключа содержат
NULL
. Как только мы обращаемся к обоим требованиям,
ALTER TABLE
успешна.
mysql> CREATE TABLE add_pk_via_inplace (c1 INT, c2 VARCHAR(10), c3 DATETIME); Query OK, 0 rows affected (0.02 sec) mysql> INSERT INTO add_pk_via_inplace VALUES (1, 'a', '2014-11-03 11:01:37'),(NULL,NULL,NULL); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM add_pk_via_inplace; +------+------+---------------------+ | c1 | c2 | c3 | +------+------+---------------------+ | 1 | a | 2014-11-03 11:01:37 | | NULL | NULL | NULL | +------+------+---------------------+ 2 rows in set (0.00 sec) mysql> SET sql_mode = ''; Query OK, 0 rows affected (0.00 sec) mysql> ALTER TABLE add_pk_via_inplace ADD PRIMARY KEY (c1,c2,c3), ALGORITHM=INPLACE; ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: cannot silently convert NULL values, as required in this SQL_MODE. Try ALGORITHM=COPY. mysql> SET sql_mode ='strict_trans_tables'; Query OK, 0 rows affected (0.00 sec) mysql> ALTER TABLE add_pk_via_inplace ADD PRIMARY KEY (c1,c2,c3), ALGORITHM=INPLACE; ERROR 1138 (22004): Invalid use of NULL value mysql> DELETE FROM add_pk_via_inplace WHERE c1 IS NULL OR c2 IS NULL OR c3 IS NULL; Query OK, 1 row affected (0.01 sec) mysql> SELECT * FROM add_pk_via_inplace; +----+----+---------------------+ | c1 | c2 | c3 | +----+----+---------------------+ | 1 | a | 2014-11-03 11:01:37 | +----+----+---------------------+ 1 row in set (0.00 sec) mysql> ALTER TABLE add_pk_via_inplace ADD PRIMARY KEY (c1,c2,c3), ALGORITHM=INPLACE; Query OK, 0 rows affected (0.09 sec) Records: 0 Duplicates: 0 Warnings: 0
Если Вы составляете таблицу без первичного ключа, InnoDB выбирает один для
Вас, которые могут быть первым UNIQUE
ключом, определенный на
столбце NOT NULL
или произведенный системой ключ. Чтобы избежать
любой неуверенности и потенциального требования пространства для
дополнительного скрытого столбца, определите PRIMARY KEY
в
CREATE TABLE
.
Каждой операцией ALTER TABLE
для InnoDB
управляют несколько аспектов:
Есть ли какое-либо изменение физического представления таблицы или это просто изменение метаданных, которые могут быть сделаны, не касаясь таблицы непосредственно.
foreign_key_checks
.ALTER TABLE
превращены в низкоуровневые операции, вовлекающие одну или более таблиц, и те
операции следуют регулярным правилам для DDL онлайн.LOCK
в ALTER TABLE
.Этот раздел объясняет, как эти факторы затрагивают различные виды
ALTER TABLE
.
Вот основные причины, почему работа DDL онлайн могла потерпеть неудачу:
Если LOCK
определяет низкую степень блокировки
(SHARED
или NONE
), это не совместимо с особым
типом работы DDL.
tmpdir
или
innodb_tmpdir
исчерпывает дисковое пространство, в то время как MySQL пишет временные
файлы на диске во время создания индекса.
Для получения дополнительной информации см.
раздел B.5.3.5.ALTER TABLE
занимает много времени, и параллельный DML изменяет таблицу так, что
размер временного журнала превышает значение параметра
innodb_online_alter_log_max_size
. Это условие вызывает ошибку
DB_ONLINE_LOG_TOO_BIG
.NULL
в столбец, создавая индекс
primary key на том столбце.
Изменения, произведенные параллельным DML, имеют приоритет, и
ALTER TABLE
откатывается.Хотя параметр конфигурации
innodb_file_per_table
имеет сильное воздействие на
представление таблицы, все операции online DDL работают одинаково хорошо,
включена ли та опция или отключена, и расположена ли таблица физически в ее
собственном файле .ibd или в
системном табличном пространстве.
У InnoDB есть два типа индексов: кластеризируемые, представляющие все данные в таблице, и дополнительные вторичные, чтобы ускорить запросы. Так как кластеризируемый индекс содержит значения данных в его узлах B-дерева, добавление или удаление кластеризируемого индекса действительно вовлекает копирование данных и создание новой копии таблицы. Вторичный индекс, однако, содержит только ключ индекса и значение первичного ключа. Этот тип индекса может быть создан или удален, не копируя данные в кластеризируемом индексе. Поскольку каждый вторичный индекс содержит копии значений первичного ключа (получает доступ к кластеризируемому индексу при необходимости), когда Вы изменяете определение первичного ключа, все вторичные индексы обновлены также.
Удаление вторичного индекса просто. Только внутренние системные таблицы InnoDB и таблицы словаря данных MySQL обновлены, чтобы отразить факт, что индекс больше не существует. InnoDB возвращает место для индекса табличному пространству, чтобы новый индекс или дополнительные строки таблицы могут использовать пространство.
Чтобы добавить вторичный индекс к существующей таблице, InnoDB просматривает таблицу и сортирует строки, используя буферы памяти и временные файлы, в порядке значений ключевых столбцов вторичного индекса. B-дерево тогда создано в порядке значений ключа, что более эффективно, чем вставка строк в индекс в случайном порядке. Поскольку узлы B-дерева разделены, когда они заполняются, создание индекса таким образом приводит к более высокому коэффициенту заполнения для индекса, делая это более эффективным для последующего доступа.
Хотя никакие данные не потеряны, если сервер отказывает в то время,
как выполняется ALTER TABLE
,
процесс восстановления
катастрофического отказа отличается для
кластеризируемого и
вторичного индексов.
Если сервер отказывает в то время, как идет создание вторичного
индекса, после восстановления MySQL удаляет любой частично созданный индекс.
Вы должны запустить повторно ALTER TABLE
или CREATE INDEX
.
Когда катастрофический отказ происходит во время создания кластеризируемого индекса, восстановление является более сложным, потому что данные в таблице должны быть скопированы к полностью новому кластеризируемому индексу. Помните, что все таблицы InnoDB сохранены как кластеризуемый индекс.
MySQL создает новый кластеризируемый индекс, копируя существующие данные от оригинальной таблицы InnoDB во временную таблицу, у которой есть желаемая структура индекса. Как только данные полностью скопированы к этой временной таблице, оригинальная таблица переименована. Временная таблица, включающая кластеризируемый индекс, переименована с названием оригинальной таблицы, а оригинальная таблица исключена из базы данных.
Если системный катастрофический отказ происходит в то время, как идет создание кластеризируемого индекса, никакие данные не потеряны, но Вы должны завершить процесс восстановления, используя временные таблицы, которые существуют во время процесса. Так как кластеризируемый индекса редко обновляется или пересматривают первичные ключи на больших таблицах, столкнуться с системным катастрофическим отказом во время этой работы шансов мало, поэтому это руководство не предоставляет информацию о восстановлении от этого сбоя.
За исключением параметров разделения в
ALTER TABLE
, online DDL следует тем же самым правилам,
которые относятся к обычным таблицам. Правила DDL обрисованы в общих чертах в
таблице 16.9.
Параметры разделения ALTER TABLE
не проходят тот же самый внутренний DDL онлайн API, как
обычные таблицы и позволены только в соединении с
ALGORITHM=DEFAULT
и LOCK=DEFAULT
.
Если Вы используете параметры разделения в
ALTER TABLE
, разделенная
таблица будет переразделена с использованием
ALTER TABLE
COPY
.
Другими словами, новая разделенная таблица составлена с новой схемой
разделения. Недавно составленная таблица будет включать любые изменения,
примененные ALTER TABLE
,
табличные данные будут скопированы в новую структуру таблицы.
Если Вы не изменяете разделения таблицы
или выполняете любое другое управление разделением в Вашем
ALTER TABLE
,
ALTER TABLE
будет использовать INPLACE
на каждом табличном разделе.
Знайте, однако, что когда INPLACE
ALTER TABLE
выполнен на каждом
разделе, будут увеличены требования к системным ресурсам из-за операций,
выполняемых на многих разделах.
Даже при том, что разделы в ALTER
TABLE
не проходят тот же самый внутренний DDL онлайн API, как
обычные таблицы, MySQL все еще пытается минимизировать копирование данных и
блокировку где только возможно:
ADD PARTITION
и DROP PARTITION
для таблиц, разделенных RANGE
или LIST
не копируют существующие данные.
TRUNCATE PARTITION
не копирует существующих данных для всех
типов разделенных таблиц.ADD PARTITION
и
COALESCE PARTITION
для таблиц, разделенных HASH
или
LIST
. MySQL копирует данные, держа
совместно используемую блокировку.REORGANIZE PARTITION
, REBUILD PARTITION
,
ADD PARTITION
или COALESCE PARTITION
для таблицы, разделенной by LINEAR HASH
или LIST
,
параллельные запросы позволены. Данные затронутого раздела скопированы, держа
совместно используемую блокировку (чтение) метаданных на табличном уровне.
Полнотекстовый поиск (FTS) и внешние ключи не поддержаны
разделенными таблицами InnoDB
. Подробности в разделах
13.9.5 и
20.6.2.
Примите следующие ограничения во внимание, выполняя операции online DDL:
Работа DDL онлайн, которая копирует таблицу, может вызвать ошибку,
если работа использует все доступное дисковое пространство на файловой
системе, где каталог данных находится (
datadir
). Чтобы избежать этой проблемы, гарантируйте, что
есть достаточно дискового пространства, чтобы выполнить операции
online ALTER TABLE
,
которые копируют таблицу. Во время этих операций MySQL пишет временные файлы
во временный каталог ($TMPDIR
в Unix, %TEMP%
в
Windows или каталог, определенный переменной
--tmpdir
).
Каждый временный файл является достаточно большим, чтобы держать один столбец
в новой таблице или индексе, и удален, как только это слито в заключительную
таблицу. Такие операции могут потребовать временное пространство, равное
сумме данных в таблице плюс индексы.
Вы можете использовать опцию
innodb_tmpdir
, чтобы определить отдельный временный каталог
для операций DDL онлайн. Опция
innodb_tmpdir
была введена, чтобы помочь избежать временных
переполнений каталога, которые могли произойти в результате больших временных
файлов вида, создаваемых во время операций онлайн
ALTER TABLE
,
которые пересоздают таблицу.
TEMPORARY TABLE
.
Об этом сообщили как MySQL Bug #39833.LOCK=NONE
в ALTER TABLE
не позволен, если есть ограничения
ON...CASCADE
или ON...SET NULL
на таблицу.LOCK
в ALTER TABLE
может потребовать эксклюзивного доступа к таблице
в течение краткого времени во время начальных и заключительных фаз работы
DDL. Таким образом, работа DDL онлайн могла бы ждать прежде, чем закончиться,
если есть продолжительное выполнение вставки, обновления, удаления или
SELECT ... FOR UPDATE
на таблице, работа DDL онлайн могла бы
ждать прежде, чем закончиться, если подобная продолжительная транзакция
запущена в то время, как выполняется
ALTER TABLE
.ALTER TABLE
, применит
online-журнал операций DML, которые были выполнены
одновременно на той же самой таблице от других потоков соединения. Когда
операции DML применены, возможно столкнуться с ошибкой дубликата ключа
(ERROR 1062 (23000): Duplicate entry), даже если бы двойная
запись является только временной и исправилась бы более поздней запись в
online-журнале. Это подобно идее ограничения
внешнего ключа, в котором ограничения должны держаться во время транзакции.
OPTIMIZE TABLE
для
InnoDB
отображена на ALTER
TABLE
, чтобы восстановить таблицу, обновить индексную статистику
и свободное неиспользуемое место в кластеризируемом индексе. Вторичный индекс
не создаются так эффективно, потому что ключи вставлены в порядке, в котором
они появились в первичном ключе.
OPTIMIZE TABLE
также поддерживает online DDL для
пересоздания таблиц InnoDB
. Для дополнительной информации см.
раздел 16.12.1.
До MySQL 5.6.17/5.7.4 не было поддержки online DDL для этого.
Таблицы InnoDB
, составленные перед MySQL 5.6, не
поддерживают ALTER
TABLE ... ALGORITHM=INPLACE
для таблиц, которые включают временные
столбцы (DATE
,
DATETIME
или
TIMESTAMP
)
и не были пересозданы через
ALTER TABLE ... ALGORITHM=COPY
. В этом случае
ALTER TABLE ... ALGORITHM=INPLACE
возвращает следующую ошибку:
ERROR 1846 (0A000): ALGORITHM=INPLACE is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY.
Нет никакого механизма, чтобы сделать паузу в online DDL или ограничить ввод/вывод или использование центрального процессора для работы DDL.
Для дополнительной информации, связанной с выполнением онлайн операции DDL на больших таблицах, см. раздел 16.12.2.
Системные переменные, которые являются истиной или ложью, могут
быть включены при запуске сервера или отключены при использовании префикса
--skip-
. Например, чтобы включить или отключить адаптивный хэш
индекс, Вы можете использовать
--innodb_adaptive_hash_index
или
--skip-innodb_adaptive_hash_index
в командной строке или
innodb_adaptive_hash_index
или
skip-innodb_adaptive_hash_index
в файле опций.
--var_name
=value
в командной строке или как
var_name
=value
в файле опций.GLOBAL
и SESSION
обратитесь к описанию команды
SET
.InnoDB
.
Раздел 16.6
объясняет, как использовать эти опции.InnoDB
,
основанные на машинной конфигурации и Вашей
рабочей нагрузке базы данных.Таблица 16.10. Опции и переменные
InnoDB
Устаревшая | 5.5.22 | ||
Формат командной строки | --ignore-builtin-innodb | ||
Системная переменная | Имя |
ignore_builtin_innodb
| |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | boolean |
В MySQL 5.1 эта опция заставила сервер вести себя как будто встроенный
InnoDB
не присутствовал, что заставляет InnoDB Plugin
использовать вместо этого. В MySQL 8.0 InnoDB
механизм хранения по умолчанию и InnoDB Plugin
не используется, таким образом, эта опция проигнорирована.
--innodb[=value
]
Устаревшая | 5.7.5 | ||
Формат командной строки | --innodb[=value] | ||
Допустимые значения | Тип |
enumeration | |
Значение по умолчанию | ON | ||
Допустимые значения | OFF | ||
ON | |||
FORCE | |||
Допустимые значения | Тип | boolean |
Загрузка средств управления InnoDB
, если сервер был собран с
поддержкой InnoDB
. У этой опции есть формат tristate, с
возможными значениями OFF
,
ON
или FORCE
. См.
раздел 6.6.2.
Чтобы отключить InnoDB
, используйте
--innodb=OFF
или
--skip-innodb
.
В этом случае, потому что InnoDB
механизм хранения по умолчанию, сервер не будет запускаться, если Вы также не
будете использовать
--default-storage-engine
и
--default-tmp-storage-engine
, чтобы установить значением по
умолчанию некоторый другой механизм для постоянных и для
TEMPORARY
таблиц.
Механизм хранения InnoDB
больше не может быть отключен, и
--innodb=OFF
и
--skip-innodb
устарели и не имеют никакого эффекта. Их использование приводит к
предупреждению. Эти опции будут удалены в будущем выпуске MySQL.
--innodb-status-file
Формат командной строки | --innodb-status-file | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Управляет, создает ли InnoDB
файл
innodb_status.
в каталоге данных MySQL.
Если включено, pid
InnoDB
периодически пишет вывод
SHOW ENGINE INNODB STATUS
в этот файл.
По умолчанию файл не создается. Чтобы создать его, запустите
mysqld
с опцией --innodb-status-file=1
.
Файл удален во время нормального завершения работы.
--skip-innodb
Отключает InnoDB
. См. описание
--innodb
.
daemon_memcached_enable_binlog
Формат командной строки | --daemon_memcached_enable_binlog=# | ||
Системная переменная | Имя |
daemon_memcached_enable_binlog | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | false |
См. раздел 16.19 для подробностей об этой опции.
daemon_memcached_engine_lib_name
Формат командной строки | --daemon_memcached_engine_lib_name=library
| ||
Системная переменная | Имя |
daemon_memcached_engine_lib_name | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | file name | |
Значение по умолчанию | innodb_engine.so |
Определяет совместно используемую библиотеку, которая осуществляет
плагин InnoDB
memcached.
См. раздел 16.19.
daemon_memcached_engine_lib_path
Формат командной строки | --daemon_memcached_engine_lib_path=directory
| ||
Системная переменная | Имя |
daemon_memcached_engine_lib_path | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | directory name | |
Значение по умолчанию | NULL |
Путь к каталогу, содержащесу совместно используемую библиотеку, которая
осуществляет плагин InnoDB
memcached
. Значение по умолчанию NULL, представляя каталог плагинов MySQL. Вы
не должны менять этот параметр, не определяя иной механизм хранения,
плагин для которого расположен за пределами каталога плагинов MySQL.
См. раздел 16.19.
daemon_memcached_option
Формат командной строки | --daemon_memcached_option=options | ||
Системная переменная | Имя |
daemon_memcached_option | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | string | |
Значение по умолчанию |
|
Используется, чтобы передать разделенные пробелом опции memcached опции к основному демону кэширования объекта памяти при запуске. Например, Вы могли бы изменить порт, на котором слушает memcached, уменьшить максимальное количество одновременных соединений, изменить максимальный размер памяти для пары ключ/значение или позволить отладочные сообщения для журнала ошибок.
См. раздел 16.19.
daemon_memcached_r_batch_size
Формат командной строки | --daemon_memcached_r_batch_size=# | ||
Системная переменная | Имя |
daemon_memcached_r_batch_size | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 1 |
Определяет, сколько операций чтения
memcached (get
) выполнить
прежде, чем сделать COMMIT
,
чтобы запустить новую транзакцию. Копия
daemon_memcached_w_batch_size
.
Это значение установлено в 1 по умолчанию, чтобы любые изменения, произведенные в таблице через запросы SQL, были немедленно видимы в memcached. Вы могли бы увеличить это, чтобы уменьшить издержки от частых передач в системе, где к основной таблице получают доступ только через интерфейс memcached . Если Вы устанавливаете слишком большое значение, размер данных в undo или redo добавит издержек по системе хранения, как с любой продолжительной транзакцией.
См. раздел 16.19.
daemon_memcached_w_batch_size
Формат командной строки | --daemon_memcached_w_batch_size=# | ||
Системная переменная | Имя |
daemon_memcached_w_batch_size | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 1 |
Определяет, скольким операциям записи
memcached таким, как add
,
set
или incr
, выполниться прежде, чем сделать
COMMIT
. Копия
daemon_memcached_r_batch_size
.
Это значение установлено в 1 по умолчанию, при условии, что любые хранимые
данные важны, чтобы сохранить в случае отключения электричества и должны
немедленно быть переданы. Храня некритические данные, Вы могли бы увеличить
это значение, чтобы уменьшить издержки, но тогда последние
N
-1 операций записи могут быть потеряны в
случае катастрофического отказа. См.
раздел 16.19.
ignore_builtin_innodb
Устаревшая | 5.5.22 | ||
Формат командной строки | --ignore-builtin-innodb | ||
Системная переменная | Имя |
ignore_builtin_innodb | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | boolean |
См. описание на
--ignore-builtin-innodb
.
innodb_adaptive_flushing
Формат командной строки | --innodb_adaptive_flushing=# | ||
Системная переменная | Имя |
innodb_adaptive_flushing | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | ON |
Определяет, скорректировать ли динамически уровень сброса грязных страниц в буферном пуле, основываясь на рабочей нагрузке. Корректировка уровня потока динамически предназначена, чтобы избежать взрывов деятельности ввода/вывода. Эта установка включена по умолчанию. См. раздел 16.6.3.6. Для общих советов по настройке ввода/вывода см. раздел 9.5.8.
innodb_adaptive_flushing_lwm
Формат командной строки | --innodb_adaptive_flushing_lwm=# | ||
Системная переменная | Имя |
innodb_adaptive_flushing_lwm | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 10 | ||
Минимум | 0 | ||
Максимум | 70 |
Нижний предел процента размера журнала redo, на котором включен адаптивный сброс.
innodb_adaptive_hash_index
Формат командной строки | --innodb_adaptive_hash_index=# | ||
Системная переменная | Имя |
innodb_adaptive_hash_index | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | ON |
Включен или отключен адаптивный хеш индекс. Может быть желательно, в зависимости от Вашей рабочей нагрузки, динамически включить или отключить адаптивный хеш индекс, чтобы улучшить работу запроса. Поскольку адаптивный хеш индекс, возможно, не полезен для всех рабочих нагрузок, надо смотреть результаты работы с ним, используя реалистические рабочие нагрузки. См. раздел 16.4.3.
Эта переменная включена по умолчанию. Вы можете изменить этот параметр,
используя SET GLOBAL
, не перезапуская сервер. Изменение настроек
требует привилегии SUPER
. Вы можете также использовать
--skip-innodb_adaptive_hash_index
при запуске сервера,
чтобы отключить это.
Отключение адаптивного хеш-индекса опустошает хэш-таблицу немедленно. Нормальное функционирование может продолжиться, в то время как хэш-таблица освобождена, и выполняются запросы, которые использовали хэш-таблицу, получают доступ к индексным B-деревьям непосредственно вместо этого. Когда адаптивный хеш-индекс повторно включен, хэш-таблица заполнена снова во время нормального функционирования.
innodb_adaptive_hash_index_parts
Формат командной строки | --innodb_adaptive_hash_index_parts=# | ||
Системная переменная | Имя |
innodb_adaptive_hash_index_parts | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | numeric | |
Значение по умолчанию | 8 | ||
Минимум | 1 | ||
Максимум | 512 |
Разделы системы поиска адаптивного хеш-индекса. Каждый индекс связан с определенным разделом, каждый раздел защищен отдельно.
Адаптивный хеш индекс разделен на 8 частей по умолчанию. Максимальная установка 512.
См. раздел 16.4.3.
innodb_adaptive_max_sleep_delay
Формат командной строки | --innodb_adaptive_max_sleep_delay=# | ||
Системная переменная | Имя |
innodb_adaptive_max_sleep_delay | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 150000 | ||
Минимум | 0 | ||
Максимум | 1000000 |
Позволяет автоматически скорректировать значение
innodb_thread_sleep_delay
, согласно текущей рабочей нагрузке.
Любое ненулевое значение включает автоматизированную динамическую
корректировку innodb_thread_sleep_delay
до максимального значения, определенного в
innodb_adaptive_max_sleep_delay
.
Значение представляет число микросекунд. Эта опция может быть полезной
в занятых системах, более чем с 16 потоками InnoDB
.
Практически это является самым ценным для систем MySQL с сотнями или
тысячами одновременных соединений.
См. раздел 16.6.5.
innodb_api_bk_commit_interval
Формат командной строки | --innodb_api_bk_commit_interval=# | ||
Системная переменная | Имя |
innodb_api_bk_commit_interval | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 5 | ||
Минимум | 1 | ||
Максимум | 1073741824 |
Как часто передать неактивные соединения, которые используют
InnoDB
memcached, в секундах. См.
раздел 16.19.
innodb_api_disable_rowlock
Формат командной строки | --innodb_api_disable_rowlock=# | ||
Системная переменная | Имя | innodb_api_disable_rowlock | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Используйте эту переменную, чтобы отключить блокировки строки, когда
InnoDB
memcached выполняет DML.
По умолчанию innodb_api_disable_rowlock
OFF
,
что означает, что memcached
просит блокировки строки для операций получения и установки. Когда
innodb_api_disable_rowlock
ON
,
memcached просит табличную блокировку
вместо блокировок строки.
innodb_api_disable_rowlock
не является динамичной. Это должно быть определено в командной строке
mysqld или
введено в конфигурационный файл MySQL. Конфигурация вступает в силу, когда
плагин установлен, что делается каждый раз, когда сервер MySQL запущен.
innodb_api_enable_binlog
Формат командной строки | --innodb_api_enable_binlog=# | ||
Системная переменная | Имя |
innodb_api_enable_binlog | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Позволяет Вам использовать плагин memcached с MySQL двоичным журналом. См. раздел 16.19.
innodb_api_enable_mdl
Формат командной строки | --innodb_api_enable_mdl=# | ||
Системная переменная | Имя |
innodb_api_enable_mdl | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Блокирует таблицу, используемую memcached, чтобы это не могло быть удалено или изменено DDL через интерфейс SQL. См. раздел 16.19.
innodb_api_trx_level
Формат командной строки | --innodb_api_trx_level=# | ||
Системная переменная | Имя |
innodb_api_trx_level | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 0 |
Позволяет Вам управлять операционным уровнем изоляции на запросах, обработанных интерфейсом memcached . См. раздел 16.19. Константы, соответствующие именам:
0 =
READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE
Формат командной строки | --innodb_autoextend_increment=# | ||
Системная переменная | Имя |
innodb_autoextend_increment | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 64 | ||
Минимум | 1 | ||
Максимум | 1000 |
Размер увеличения (в MB) для того, чтобы расширить размер файла
системного табличного
пространства, когда это становится полным. Значение по умолчанию 64. Эта
переменная не затрагивает файлы file-per-table (.ibd
),
которые создаются, если Вы используете
innodb_file_per_table=1
, или общее табличное пространство.
Те файлы автомасштабируются независимо от значения
innodb_autoextend_increment
.
Начальные расширения идут небольшими порциями, после которых расширения
происходят блоками по 4MB.
innodb_autoinc_lock_mode
Формат командной строки | --innodb_autoinc_lock_mode=# | ||
Системная переменная | Имя |
innodb_autoinc_lock_mode | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 1 | ||
Допустимые значения | 0 | ||
1 | |||
2 |
Режим блокировки, чтобы произвести значения auto-increment. Допустимые значения 0, 1 или 2 для режимов traditional, consecutive или interleaved. раздел 16.8.5 описывает характеристики этих режимов.
У этой переменной есть значение по умолчанию 1 (consecutive).
innodb_background_drop_list_empty
Формат командной строки | --innodb_background_drop_list_empty=# | ||
Системная переменная | Имя |
innodb_background_drop_list_empty | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Включение опции отладки
innodb_background_drop_list_empty
помогает избежать отказов, задерживая табличное создание, пока фоновый список
удаления не пуст. Например, если случай теста A поместил таблицу
t1
в фоновый список, случай теста B пока фоновый список не пуст
прежде, чем составить таблицу t1
.
innodb_buffer_pool_chunk_size
Формат командной строки | --innodb_buffer_pool_chunk_size | ||
Системная переменная | Имя |
innodb_buffer_pool_chunk_size | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 134217728 | ||
Минимум | 1048576 | ||
Максимум | innodb_buffer_pool_size/innodb_buffer_pool_instances
|
innodb_buffer_pool_chunk_size
определяет размер куска для
изменения размера буферного пула.
innodb_buffer_pool_size
является динамичным, который позволяет Вам
изменять размеры буферного пула, не перезапуская сервер. Чтобы избежать
копировать все буферные страницы пула во время изменения размеров операций,
работа выполнена кусками. Размер куска определен
innodb_buffer_pool_chunk_size
. По умолчанию
innodb_buffer_pool_chunk_size
128 MB (134217728 байт).
Число страниц, содержавшихся в куске, зависит от значения
innodb_page_size
. innodb_buffer_pool_chunk_size
может быть увеличен или уменьшен с шагом 1MB (1048576 байт).
Следующие условия применяются, изменяя
innodb_buffer_pool_chunk_size
:
Если
innodb_buffer_pool_chunk_size
*
innodb_buffer_pool_instances
больше чем текущий буферный размер
пула, когда буферный пул инициализирован,
innodb_buffer_pool_chunk_size
усечен к
innodb_buffer_pool_size
/
innodb_buffer_pool_instances
.
innodb_buffer_pool_chunk_size
*
innodb_buffer_pool_instances
. Если Вы изменяете
innodb_buffer_pool_chunk_size
,
innodb_buffer_pool_size
автоматически скорректирован к значению,
которое равно или кратно
innodb_buffer_pool_chunk_size
*
innodb_buffer_pool_instances
, что не меньше, чем текущий буферный
размер пула. Корректировка происходит, когда буферный пул инициализирован.
Меняя
innodb_buffer_pool_chunk_size
будьте осторожны, так как
изменяя это значение можно автоматически увеличить размер буферного пула.
Прежде, чем Вы измените
innodb_buffer_pool_chunk_size
, вычислите эффект, который это будет
иметь
innodb_buffer_pool_size
, чтобы
гарантировать, что получающийся буферный размер пула является приемлемым.
Чтобы избегать потенциальных исполнительных проблем, число кусков
(
innodb_buffer_pool_size
/
innodb_buffer_pool_chunk_size
) не должно превысить 1000.
См. раздел 16.6.3.2.
innodb_buffer_pool_debug
Формат командной строки | --innodb_buffer_pool_debug=# | ||
Системная переменная | Имя |
innodb_buffer_pool_debug | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Включение этой опции разрешает многократные буферные экземпляры, когда
буферный пул меньше 1GB, игнорируя ограничение минимума размера пула в 1GB,
наложенное на
innodb_buffer_pool_instances
. Опция innodb_buffer_pool_debug
доступна, если поддержка отладка собрана с использованием опции
WITH_DEBUG
в
CMake.
innodb_buffer_pool_dump_at_shutdown
Формат командной строки | --innodb_buffer_pool_dump_at_shutdown=# | ||
Системная переменная | Имя |
innodb_buffer_pool_dump_at_shutdown | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | ON |
Определяет, сделать ли запись страниц, кэшируемых в
буферном пуле, когда сервер
MySQL закрыт, чтобы сократить процесс
разминки в следующем перезапуске.
Как правило используется в комбинации с
innodb_buffer_pool_load_at_startup
.
Опция
innodb_buffer_pool_dump_pct
определяет процент последний раз
используемых буферных страниц пула для дампа.
innodb_buffer_pool_dump_at_shutdown
и
innodb_buffer_pool_load_at_startup
включены по умолчанию.
См. раздел 16.6.3.8.
innodb_buffer_pool_dump_now
Формат командной строки | --innodb_buffer_pool_dump_now=# | ||
Системная переменная | Имя |
innodb_buffer_pool_dump_now | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Немедленно делает запись страниц, кэшируемых в
буферном пуле.
Как правило используется в комбинации с
innodb_buffer_pool_load_now
.
См. раздел 16.6.3.8.
innodb_buffer_pool_dump_pct
Формат командной строки | --innodb_buffer_pool_dump_pct=# | ||
Системная переменная | Имя |
innodb_buffer_pool_dump_pct | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 25 | ||
Минимум | 1 | ||
Максимум | 100 |
Определяет процент последний раз используемых страниц для каждого
буферного пула, чтобы читать и сбросить в дамп. Диапазон 1-100. Значение по
умолчанию 25. Например, если есть 4 буферных пула с 100 страницами каждый, и
innodb_buffer_pool_dump_pct
25, то 25 последний раз используемых
страниц из каждого буферного пула выведены в дамп.
innodb_buffer_pool_filename
Формат командной строки | --innodb_buffer_pool_filename=file | ||
Системная переменная | Имя |
innodb_buffer_pool_filename | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | file name | |
Значение по умолчанию | ib_buffer_pool |
Определяет название файла, который хранит список ID
табличного пространства и страниц, произведенный
innodb_buffer_pool_dump_at_shutdown
или
innodb_buffer_pool_dump_now
. ID сохраняют следующий формат:
space, page_id
. По умолчанию, файл называют
ib_buffer_pool
и расположен он в каталоге данных.
Местоположение не по умолчанию должно быть определено
относительно каталога данных.
Имя файла может быть определено во время выполнения, используя
SET
:
SET GLOBAL innodb_buffer_pool_filename='file_name'
;
Вы можете также определить определяемое пользователем имя файла при
запуске в строке запуска или конфигурационном файле MySQL. Определяя имя
файла при запуске, файл должен уже существовать или
InnoDB
возвратит ошибку запуска, указывающую, что нет такого
файла или каталога.
См. раздел 16.6.3.8.
innodb_buffer_pool_instances
Формат командной строки | --innodb_buffer_pool_instances=# | ||
Системная переменная | Имя |
innodb_buffer_pool_instances | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения (Windows, 32-bit platforms) | Тип | integer | |
Значение по умолчанию | (autosized) | ||
Минимум | 1 | ||
Максимум | 64 | ||
Допустимые значения (Другие) | Тип | integer | |
Значение по умолчанию | 8 (или 1, если innodb_buffer_pool_size < 1GB
| ||
Минимум | 1 | ||
Максимум | 64 |
Число областей, на которые буферный пул разделен. Для систем с буферными пулами в диапазоне нескольких гигабай деление буферного пула на отдельные экземпляры может улучшить параллелизм, уменьшая издержки на различное чтение потоков и запись кэшируемых страниц. Каждая страница, которая сохранена или считана из буферного пула, назначена на один из буферных экземпляров пула беспорядочно, используя хеширующую функцию. Каждый буферный пул управляет своими собственными свободными списками, списками потока, LRU и всеми другими структурами данных, соединенными с буферным пулом, и защищен его собственным mutex.
Эта опция вступает в силу, только когда Вы устанавливаете
innodb_buffer_pool_size
в 1GB или больше.
Полный буферный размер пула разделен среди всех буферных пулов.
Для лучшей эффективности определите комбинацию
innodb_buffer_pool_instances
и
innodb_buffer_pool_size
так, чтобы каждый буферный экземпляр был минимум в 1GB.
Значение по умолчанию в 32-bit Windows зависит от значения
innodb_buffer_pool_size
:
Если
innodb_buffer_pool_size
больше 1.3GB, значение по умолчанию для
innodb_buffer_pool_instances
=
innodb_buffer_pool_size
/128MB,
с отдельным распределением памяти для каждого куска. 1.3GB
был выбран в качестве границы, в которой есть существенный риск для
32-битной Windows не быть способной выделить непрерывное адресное
пространство, необходимое для единственного буферного пула.
На всех других платформах значение по умолчанию 8, когда
innodb_buffer_pool_size
больше или равен 1GB. Иначе 1.
См. раздел 16.6.3.2.
innodb_buffer_pool_load_abort
Формат командной строки | --innodb_buffer_pool_load_abort=# | ||
Системная переменная | Имя |
innodb_buffer_pool_load_abort | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Прерывает процесс восстановления содержания
буферного пула, вызванный
innodb_buffer_pool_load_at_startup
или
innodb_buffer_pool_load_now
.
См. раздел 16.6.3.8.
innodb_buffer_pool_load_at_startup
Формат командной строки | --innodb_buffer_pool_load_at_startup=# | ||
Системная переменная | Имя |
innodb_buffer_pool_load_at_startup | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | ON |
Определяет, что на запуске сервера MySQL
буферный пул автоматически
подогревается, загружая те же самые
страницы, которые это содержало в более раннее время. Как правило,
используется в комбинации с
innodb_buffer_pool_dump_at_shutdown
.
innodb_buffer_pool_dump_at_shutdown
и innodb_buffer_pool_load_at_startup
включены по умолчанию.
См. раздел 16.6.3.8.
innodb_buffer_pool_load_now
Формат командной строки | --innodb_buffer_pool_load_now=# | ||
Системная переменная | Имя |
innodb_buffer_pool_load_now | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Немедленно нагревает буферный пул, загружая ряд страниц данных, не ожидая перезапуска сервера. Может быть полезным, чтобы возвратить кэш-память к известному состоянию во время сопоставительного анализа, или к готовому сервер MySQL, чтобы возобновить его нормальную рабочую нагрузку после выполнения запросов для отчетов или обслуживания. См. раздел 16.6.3.8.
innodb_buffer_pool_size
Формат командной строки | --innodb_buffer_pool_size=# | ||
Системная переменная | Имя |
innodb_buffer_pool_size | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 8388608 | ||
Минимум | 1048576 | ||
Допустимые значения (32-bit platforms) | Тип | integer | |
Значение по умолчанию | 134217728 | ||
Минимум | 5242880 | ||
Максимум | 2**32-1 | ||
Допустимые значения (64-bit platforms) | Тип | integer | |
Значение по умолчанию | 134217728 | ||
Минимум | 5242880 | ||
Максимум | 2**64-1 |
Размер в байтах буферного пула
, области памяти, где InnoDB
хранит таблицу кэшей и
индексные данные. Значение по умолчанию составляет 128 МБ. Максимальное
значение зависит от архитектуры центрального процессора: максимум 4294967295
(232-1) в 32-bit системах и 18446744073709551615
(264-1) в 64-bit системах. В 32-bit системах
архитектура центрального процессора и операционная система могут наложить
более низкий практический максимальный размер, чем установленный максимум.
Когда размер буферного пула больше 1GB, установка
innodb_buffer_pool_instances
к значению больше 1 может улучшить
масштабируемость относительно занятого сервера.
Буферный пул большего размера требует, чтобы меньше дискового ввода/вывода получило доступ к тем же самым табличным данным. На специализированном сервере базы данных Вы могли бы установить буферный размер пула в 80% размера физической памяти машины. Знайте о следующих потенциальных проблемах, когда конфигурируете размер буфера, и будьте подготовлены вычислить размер буферного пула в случае необходимости.
Соревнование за физическую память может вызвать своп в операционной системе.
InnoDB
резервирует дополнительную память для буферов и
структур управления, чтобы полное выделенное место было приблизительно на
10% больше, чем указанный размер пула.Когда Вы увеличиваете или уменьшаете
размер пула, работа выполнена в кусках. Размер куска определен
innodb_buffer_pool_chunk_size
, у которой есть значение
по умолчанию 128 MB.
Буферный размер должен всегда быть равным или кратным
innodb_buffer_pool_chunk_size
*
innodb_buffer_pool_instances
.
Если Вы изменяете буферный размер к значению, которое не равно или кратно
innodb_buffer_pool_chunk_size
*
innodb_buffer_pool_instances
,
буферный размер автоматически скорректирован к значению, которое равно или
кратно
innodb_buffer_pool_chunk_size
*
innodb_buffer_pool_instances
, но не меньше, чем
указанный буферный размер.
innodb_buffer_pool_size
может быть установлен динамически,
что позволяет Вам изменять размеры буферного пула, не перезапуская сервер.
Innodb_buffer_pool_resize_status
сообщает о состоянии изменения размера буферного пула. См.
раздел 16.6.3.2.
innodb_change_buffer_max_size
Формат командной строки | --innodb_change_buffer_max_size=# | ||
Системная переменная | Имя |
innodb_change_buffer_max_size | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 25 | ||
Минимум | 0 | ||
Максимум | 50 |
Максимальный размер для буфера изменений, как процент от полного размера буферного пула. Вы могли бы увеличить это значение для сервера MySQL с тяжелой вставкой, обновлением и удалением или уменьшить это для сервера MySQL с неизменными данными. Для общих советов по настройке ввода/вывода см. раздел 9.5.8.
innodb_change_buffering
Формат командной строки | --innodb_change_buffering=# | ||
Системная переменная | Имя |
innodb_change_buffering | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | enumeration | |
Значение по умолчанию | all | ||
Допустимые значения | none | ||
inserts | |||
deletes | |||
changes | |||
purges | |||
all |
Выполняет ли InnoDB
буферизацию изменений,
оптимизируя задержки операции записи вторичного индекса так, чтобы операции
ввода/вывода могли быть выполнены последовательно. Разрешенные значения
описаны в следующей таблице. Значения могут также быть определены в цифровой
форме. Для получения дополнительной информации см.
раздел 16.6.4.
Для общих советов по настройке ввода/вывода см.
раздел 9.5.8.
Таблица 16.11. Разрешенные значения для innodb_change_buffering
Value | Числовое значение | Описание |
---|---|---|
none | 0 | Не буферизовать операции. |
inserts | 1 | Буферизовать операции вставки. |
deletes | 2 | Буферизовать операции маркировки удаления, строго говоря, отметка записей индекса для более позднего удаления во время работы чистки. |
changes | 3 | Буферизовать операции маркировки удаления и вставки. |
purges | 4 | Буферизовать операции удаления, которые происходят в фоне. |
all | 5 | По умолчанию. Буферизовать операции маркировки удаления, вставки и чистки. |
Формат командной строки | --innodb_change_buffering_debug=# | ||
Системная переменная | Имя |
innodb_change_buffering_debug | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 0 | ||
Максимум | 2 |
Устанавливает флаг отладки для буферизации изменений. Значение 1 пишет
все изменения буфера изменения. Значение 2 пишет катастрофический отказ при
слиянии. Значение по умолчанию 0 указывает, что флаг отладки, не установлен.
Эта опция только доступна, когда отладка поддержки собрана с использованием
WITH_DEBUG
в
CMake.
innodb_checksum_algorithm
Формат командной строки | --innodb_checksum_algorithm=# | ||
Системная переменная | Имя |
innodb_checksum_algorithm | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | enumeration | |
Значение по умолчанию | crc32 | ||
Допустимые значения | innodb | ||
crc32 | |||
none | |||
strict_innodb | |||
strict_crc32 | |||
strict_none |
Определяет, как произвести и проверить
контрольную сумму, сохраненную в
каждом дисковом блоке каждого
табличного пространства. Значение по умолчанию для
innodb_checksum_algorithm
crc32
.
MySQL Enterprise Backup до версии 3.8.0 не поддерживают табличные пространства с использованием контрольных сумм CRC32. MySQL Enterprise Backup добавляет поддержку контрольной суммы CRC32 в 3.8.1 с некоторыми ограничениями.
Значение innodb
обратно совместимо со всеми версиями MySQL.
Значение crc32
использует алгоритм, который быстрее, чтобы
вычислить контрольную сумму для каждого измененного блока и проверить
контрольные суммы при каждом дисковом чтении. Это просматривает блоки по 32
бита за один раз, что является быстрее алгоритма контрольной суммы
innodb
, который просматривает блоки по 8 бит за раз. Значение
none
пишет постоянную величину в области контрольной суммы
вместо того, чтобы вычислить значение, основанное на данных о блоке. Блоки в
табличном пространстве могут использовать соединение старых, новых и никаких
значений контрольной суммы, будучи обновлены постепенно, по мере того, как
данные изменены. Как только любые блоки в табличном пространстве изменены,
чтобы использовать crc32
, связанные таблицы не могут быть
считаны более ранними версиями MySQL.
Форма strict_*
работает как
innodb
, crc32
и
none
, за исключением того, что InnoDB
сообщает об ошибке, если сталкивается с допустимым, но несоответствующим
значением контрольной суммы. В этом случае страница все еще принята как
допустимая. Рекомендуется, чтобы Вы использовали strict_*
только
в новом экземпляре, чтобы настроить все табличные пространства впервые.
Настройки strict_*
несколько быстрее, потому что они не должны
вычислить все значения контрольной суммы во время дисковых чтений.
Следующая таблица иллюстрирует различие между значениями опции и их
версиями strict_
. none
, innodb
и
crc32
пишут указанный тип значения контрольной суммы в каждый
блок данных, но для совместимости принимают любое из других значений
контрольной суммы, проверяя блок во время работы чтения.
Форма strict_
каждого параметра также принимает любое допустимое
значение контрольной суммы, но печатает сообщение об ошибке, когда
сталкивается с несоответствием допустимого значения контрольной суммы.
Используя strict_*
можно сделать проверку быстрее, если все
файлы с данными создаются с идентичным значением
innodb_checksum_algorithm
.
Таблица 16.12. Настройки innodb_checksum_algorithm
Значение | Произведенная контрольная сумма (при записи) | Разрешенные контрольные суммы (при чтении) |
---|---|---|
none | Число. | Любая из контрольных сумм, произведенных none ,
innodb или crc32 . |
innodb | Контрольная сумма, вычисленная в программном
обеспечении, используя оригинальный алгоритм InnoDB . |
Любая из контрольных сумм, произведенных none ,
innodb или crc32 . |
crc32 | Контрольная сумма, вычисленная с использованием
алгоритма crc32 , возможно сделанного аппаратными средствами.
| Любая из контрольных сумм, произведенных none ,
innodb или crc32 . |
strict_none | Число. | Любая из контрольных сумм,
произведенных none , innodb или crc32 .
InnoDB печатает сообщение об ошибке, если сталкивается с
допустимой, но несоответствующей контрольной суммой. |
strict_innodb | Контрольная сумма, вычисленная в программном
обеспечении, используя оригинальный алгоритм InnoDB . |
Любая из контрольных сумм,
произведенных none , innodb или crc32 .
InnoDB печатает сообщение об ошибке, если сталкивается с
допустимой, но несоответствующей контрольной суммой. |
strict_crc32 | Контрольная сумма, вычисленная с использованием
алгоритма crc32 , возможно сделанного аппаратными средствами.
| Любая из контрольных сумм,
произведенных none , innodb или crc32 .
InnoDB печатает сообщение об ошибке, если сталкивается с
допустимой, но несоответствующей контрольной суммой.
|
Формат командной строки | --innodb_cmp_per_index_enabled=# | ||
Системная переменная | Имя |
innodb_cmp_per_index_enabled | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF | ||
Допустимые значения | OFF | ||
ON |
Включает индексную связанную со сжатием статистику в
INFORMATION_SCHEMA.INNODB_CMP_PER_INDEX
.
Поскольку эти статистические данные могут быть дорогими в сборе, включите эту
опцию только на тесте или ведомых экземплярах во время исполнительной
настройки, связанной с
сжатыми таблицами InnoDB
.
innodb_commit_concurrency
Формат командной строки | --innodb_commit_concurrency=# | ||
Системная переменная | Имя |
innodb_commit_concurrency | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 0 | ||
Минимум | 0 | ||
Максимум | 1000 |
Число потоков, которые могут завершать транзакции в то же самое время. Значение 0 (значение по умолчанию) разрешает любое число транзакций одновременно.
Значение innodb_commit_concurrency
не может быть изменено во
время выполнения от ноля до отличного от нуля или наоборот. Значение может
быть изменено от одного ненулевого значения до другого.
innodb_compress_debug
Формат командной строки | --innodb_compress_debug=# | ||
Системная переменная | Имя |
innodb_compress_debug
| |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | enumeration | |
Значение по умолчанию | none | ||
Допустимые значения | none | ||
zlib | |||
lz4 | |||
lz4hc |
Сжимает все таблицы, используя указанный алгоритм сжатия, не имея
необходимости определять атрибут COMPRESSION
для каждой таблицы. Эта опция доступна только, если поддержка отладки собрана
с использованием
WITH_DEBUG
в CMake.
innodb_compression_failure_threshold_pct
Формат командной строки | --innodb_compression_failure_threshold_pct=#
| ||
Системная переменная | Имя |
innodb_compression_failure_threshold_pct | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 5 | ||
Минимум | 0 | ||
Максимум | 100 |
Устанавливает предел, в котором MySQL начинает добавлять место в пределах сжатых страниц, чтобы избежать дорогих отказов сжатия. Значение 0 отключает механизм, который контролирует эффективность сжатия и динамически корректирует количество места. См. раздел 16.9.1.6.
innodb_compression_level
Формат командной строки | --innodb_compression_level=# | ||
Системная переменная | Имя |
innodb_compression_level | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 6 | ||
Минимум | 0 | ||
Максимум | 9 |
Определяет уровень zlib сжатия, чтобы использовать для сжатых таблицы и индекса. См. раздел 16.9.1.6 .
innodb_compression_pad_pct_max
Формат командной строки | --innodb_compression_pad_pct_max=# | ||
Системная переменная | Имя |
innodb_compression_pad_pct_max | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 50 | ||
Минимум | 0 | ||
Максимум | 75 |
Определяет максимальный процент, который может быть сохранен как свободное
пространство в пределах каждой сжатой
страницы,
позволяя реорганизовать данные и журнал модификации в пределах страницы,
когда a сжатая таблица или
индекс обновлены, и данные могли бы быть повторно сжаты. Применяется только
когда
innodb_compression_failure_threshold_pct
установлен в ненулевое значение, и уровень
отказов сжатия передает
предел. См. раздел
16.9.1.6.
innodb_concurrency_tickets
Формат командной строки | --innodb_concurrency_tickets=# | ||
Системная переменная | Имя |
innodb_concurrency_tickets | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 5000 | ||
Минимум | 1 | ||
Максимум | 4294967295 |
Определяет число потоков,
которые могут работать одновременно. Поток помещен в очередь, когда он
пытается обратиться к InnoDB
, если число потоков уже достигло
предела параллелизма. Когда потоку разрешают работать, ему дают несколько
свободных тикетов, заданное значением
innodb_concurrency_tickets
, поток работает, пока не израсходует
свои тикеты. После этого поток снова подвергается проверке параллелизма (и
возможна организация очереди) в следующий раз, когда пытается обратиться к
InnoDB
. Значение по умолчанию 5000.
С маленьким значением innodb_concurrency_tickets
маленькие транзакции, которые должны обработать только несколько строк,
конкурирует справедливо с большими транзакциями, которые обрабатывают много
строк. Недостаток маленького
innodb_concurrency_tickets
: большие транзакции должны образовать
петли через очередь много раз прежде, чем они смогут завершиться, что
расширяет отрезок времени, требуемый, чтобы завершить их задачу.
С большим значением innodb_concurrency_tickets
большие транзакции проводят меньше времени, ожидая позиции в конце очереди
(управляемой
innodb_thread_concurrency
) и получение строки требует
большего количества времени. Большие транзакции также требуют меньше
проходов через очередь. Недостаток большого
innodb_concurrency_tickets
: слишком много больших транзакций,
работающих в то же самое время, могут держать меньшие транзакции, заставляя
их ждать более длительное время перед выполнением.
С отличным от нуля значением
innodb_thread_concurrency
Вы, возможно, должны корректировать
innodb_concurrency_tickets
, чтобы найти оптимальный баланс между
большими и меньшими транзакциями. SHOW ENGINE INNODB STATUS
показывает число билетов, остающихся для транзакции выполнения в ее потоке,
при текущем проходе через очередь. Эти данные могут также быть получены из
столбца TRX_CONCURRENCY_TICKETS
таблицы
INFORMATION_SCHEMA.INNODB_TRX
.
См. раздел 16.6.5.
innodb_data_file_path
Формат командной строки | --innodb_data_file_path=name | ||
Системная переменная | Имя |
innodb_data_file_path | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | string | |
Значение по умолчанию | ibdata1:12M:autoextend |
Пути к файлам с данными и
их размеры. Полный путь к каталогу к каждому файлу с данными сформирован,
добавляя
innodb_data_home_dir
к каждому пути, определенному здесь.
Размеры файл определен в KB, MB или GB (1024 MB), добавляя K
,
M
или G
к значению размера. Определяя размер файла
с данными в килобайтах (КБ), умножьте его на 1024. Иначе значения КБ
округлены к самому близкому мегабайту (MB). Сумма размеров файлов должна
быть, по крайней мере, немного больше 10 МБ. Если Вы не определяете
innodb_data_file_path
, поведение по умолчанию должно создать
единственный автомасштабируемый файл с данными, немного больше 12 МБ,
названный ibdata1
. Предел размера отдельных файлов определен
Вашей операционной системой. Вы можете установить размер файла больше 4 ГБ на
тех операционных системах, которые поддерживают большие файлы. Вы можете
также использовать сырой дисковый
раздел в качестве файлов с данными. См.
раздел 16.6.
Следующие минимальные размеры файла проведены в жизнь для
первого системного файла с данными табличного
пространства (ibdata1
), чтобы гарантировать, что есть достаточно
пространства для буферных блоков doublewrite (Bug #20972309):
Для
innodb_page_size
16 KB или меньше минимальный размер файла с
данными составляет 3 МБ.
innodb_page_size
32 KB минимальный размер файла с
данными составляет 6 MB.innodb_page_size
64 KB минимальный размер файла с данными составляет 12 MB.
Формат командной строки | --innodb_data_home_dir=dir_name | ||
Системная переменная | Имя |
innodb_data_home_dir | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | Имя каталога |
Общая часть пути к каталогу для всех
файлов с данными в
системном табличном
пространстве. Эта установка не затрагивает местоположение табличных
пространств file-per-table,
когда включена опция
innodb_file_per_table
. Значение по умолчанию каталог MySQL
data
. Если Вы определяете значение как пустую строку, Вы можете
использовать абсолютные пути к файлам в
innodb_data_file_path
.
innodb_deadlock_detect
Формат командной строки | --innodb_deadlock_detect | ||
Системная переменная | Имя |
innodb_deadlock_detect | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | ON |
Эта опция используется, чтобы отключить обнаружение тупика. На системах с
высоким параллелизмом обнаружение тупика может вызвать замедление, когда
многочисленные потоки ждут той же самой блокировки. Время от времени может
быть более эффективно отключить обнаружение тупика и положиться на
innodb_lock_wait_timeout
для операционной отмены,
когда тупик происходит.
innodb_default_row_format
Формат командной строки | --innodb_default_row_format=# | ||
Системная переменная | Имя |
innodb_default_row_format | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | enumeration | |
Значение по умолчанию | DYNAMIC | ||
Допустимые значения | DYNAMIC | ||
COMPACT | |||
REDUNDANT |
Определяет формат строки по умолчанию для таблицы (включая создаваемые
пользователем временные таблицы). Настройка по умолчанию DYNAMIC
.
Другие разрешенные значения COMPACT
и REDUNDANT
.
COMPRESSED
не поддержан для использования в системном табличном
пространстве и не может быть определен как значение по умолчанию.
Недавно составленные таблицы используют формат строки, определенный
innodb_default_row_format
, когда опция ROW_FORMAT
не
определена явно или когда используется ROW_FORMAT=DEFAULT
.
Когда ROW_FORMAT
не определена явно или определена как
ROW_FORMAT=DEFAULT
, любая работа, которая пересоздает таблицу,
также тихо изменяет формат строки таблицы к формату, определенному
innodb_default_row_format
. См.
раздел 16.10.2.
Внутренние временные таблицы, составленные сервером, чтобы обработать
запросы, используют формат DYNAMIC
, независимо от
innodb_default_row_format
.
innodb_disable_sort_file_cache
Формат командной строки | --innodb_disable_sort_file_cache=# | ||
Системная переменная | Имя |
innodb_disable_sort_file_cache | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Если включено, эта переменная отключает кэш файловой системы операционной
системы для сортировки и слияния временных файлов. Эффект состоит в том,
чтобы открыть такие файлы с эквивалентом O_DIRECT
.
innodb_doublewrite
Формат командной строки | --innodb-doublewrite | ||
Системная переменная | Имя |
innodb_doublewrite | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | ON |
Если эта переменная включена (значение по умолчанию),
InnoDB
хранит все данные дважды, сначала в
буфере doublewrite,
затем в фактические файлы с данными
. Эта переменная может быть выключена
--skip-innodb_doublewrite
для точек отсчета или случаев, когда
главная работа необходима, а не беспокойство о целостности данных
или возможных отказах.
Если системные файлы табличного пространства (ibdata
) расположены на устройствах Fusion-io, которые поддерживают атомную
запись, буфер doublewrite автоматически отключен, и атомная запись Fusion-io
используются для всех файлов с данными. Поскольку буферная установка
doublewrite глобальна, буферизация также отключена для файлов с данными,
находящихся на не-Fusion-io. Эта функция поддерживается только на аппаратных
средствах Fusion-io и включена только для Fusion-io NVMFS в Linux.
Чтобы в полной мере воспользоваться этой особенностью, установите
innodb_flush_method
в O_DIRECT
.
innodb_fast_shutdown
Формат командной строки | --innodb_fast_shutdown[=#] | ||
Системная переменная | Имя |
innodb_fast_shutdown | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 1 | ||
Допустимые значения | 0 | ||
1 | |||
2 |
Режим InnoDB
shutdown
. Если значение 0, InnoDB
делает
медленное завершение работы,
полную чистку
и слияние буфера изменений перед закрытием. Если значение 1 (значение по
умолчанию), InnoDB
пропускает эти операции при завершении
работы, процесс, известный как
быстрое завершение работы.
Если значение 2, InnoDB
сбрасывает журналы и закрывается, как
будто MySQL отказал, никакие переданные транзакции не потеряны, но работа
восстановления катастрофического
отказа заставляет следующий запуск занять больше времени.
Медленное завершение работы может занять минуты или даже часы в крайних случаях, где значительное количество данных все еще буферизовано. Используйте медленный метод завершения работы прежде, чем обновить MySQL между главными выпусквси, чтобы все файлы с данными были полностью подготовлены в случае, если процесс обновления обновляет формат файла.
innodb_fast_shutdown=2
применяется
в чрезвычайной ситуации или ситуациях с поиском неисправностей, чтобы
получить абсолютное самое быстрое завершение работы, если данные
подвергаются риску повреждения.
innodb_fil_make_page_dirty_debug
Формат командной строки | --innodb_fil_make_page_dirty_debug=# | ||
Системная переменная | Имя |
innodb_fil_make_page_dirty_debug | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 0 | ||
Максимум | 2**32-1 |
По умолчанию установка innodb_fil_make_page_dirty_debug
в ID
табличного пространства немедленно помечает грязной первую страницу
табличного пространства. Если
innodb_saved_page_number_debug
установлен в значение не по
умолчанию, установка innodb_fil_make_page_dirty_debug
помечает
грязной указанную страницу. innodb_fil_make_page_dirty_debug
доступна только если поддержка отладки собрана с использованием
WITH_DEBUG
в
CMake.
innodb_file_per_table
Формат командной строки | --innodb_file_per_table | ||
Системная переменная | Имя |
innodb_file_per_table | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | ON |
Когда innodb_file_per_table
включен (значение по умолчанию),
InnoDB
хранит данные и индекс для каждой недавно составленной
таблицы в отдельном файле
.ibd
,
а не в системном табличном пространстве. Место для этих таблиц освобождено,
когда таблицы удалены или усеченные. Эта установка позволяет несколько других
особенностй, например, сжатие.
См. раздел 16.7.4.
Знайте, что включение
innodb_file_per_table
также значит, что
ALTER TABLE
переместит
таблицу из системного табличного пространства в отдельный файл
.ibd
в случаях, где ALTER
TABLE
обновляет таблицу (ALGORITHM=COPY
).
Исключение: таблицы, которые были помещены в системное табличное
пространство, используя опцию TABLESPACE=innodb_system
в
CREATE TABLE
или
ALTER TABLE
.
Эти таблицы не затронуты innodb_file_per_table
и могут быть перемещены только в табличные пространства file-per-table,
применяя ALTER TABLE
... TABLESPACE=innodb_file_per_table
.
Если innodb_file_per_table
выключен, InnoDB
хранит данные для всех таблиц и индексов в
файлах ibdata,
которые составляют
системное табличное пространство. Эта установка уменьшает издержки
операций файловой системы для таких операций, как
DROP TABLE
или
TRUNCATE TABLE
.
Для окружающей среды сервера является самым уместным, что все устройства
хранения данных посвящены данным MySQL. Поскольку системное табличное
пространство никогда не сжимается и совместно использовано всеми базами
данных, избегайте загружать огромное количество временных данных, если
innodb_file_per_table=OFF
. Настройте отдельный экземпляр в таких
случаях, чтобы Вы могли удалить весь экземпляр, чтобы восстановить место.
innodb_file_per_table
включен по умолчанию. Рассмотрите
отключение этого, если обратная совместимость с MySQL 5.5 или ранее является
важной. Это не даст
ALTER TABLE
переместить
таблицы из системного табличного пространства.
innodb_file_per_table
является динамичным и может быть установлен
в ON
или OFF
через SET GLOBAL
.
Вы можете также установить эти параметры в
конфигурационном файле
MySQL (my.cnf
или my.ini
), но это требует
закрытия и перезапуска сервера.
Динамическое изменение значения этого параметра требует
привилегии SUPER
и немедленно затрагивает
работу всех соединений.
innodb_file_per-table
не затрагивает создание временных таблиц.
Все временные таблицы составлены в совместно используемом
временном табличном пространстве.
innodb_fill_factor
Формат командной строки | --innodb_fill_factor=# | ||
Системная переменная | Имя |
innodb_fill_factor
| |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 100 | ||
Минимум | 10 | ||
Максимум | 100 |
InnoDB
выполняет оптовую загрузку, когда создает или
восстанавливает индекс. Этот метод известен как
создание сортированного индекса.
innodb_fill_factor
определяет процент пространства на каждой
странице B-дерева, которая заполнена во время создания сортированного
индекса, с остающимся пространством, сохраненным для будущего роста индекса.
Например, установка innodb_fill_factor
в 80 резервирует 20%
пространства на каждой странице B-дерева для будущего роста индекса.
Фактические проценты могут измениться. innodb_fill_factor
интерпретируется как подсказка, а не жесткий предел.
innodb_fill_factor
определяет 100 листьев 1/16 пространства в кластеризируемых
индексных страницах, свободных для будущего роста индекса.
innodb_fill_factor
относится к страницам листа и нелиста
B-дерева. Это не относится к внешним страницам, используемым для
TEXT
или
BLOB
.
См. раздел 16.8.11.
innodb_flush_log_at_timeout
Системная переменная | Имя |
innodb_flush_log_at_timeout | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 1 | ||
Минимум | 1 | ||
Максимум | 2700 |
Записать и сбросить журналы каждые N
секунд.
innodb_flush_log_at_timeout
позволяет периоду тайм-аута между
потоками быть увеличенным, чтобы уменьшить сброс и избежать падения
производительности групповых записей в двоичный журнал.
Настройка по умолчанию для
innodb_flush_log_at_timeout
однажды в секунду.
innodb_flush_log_at_trx_commit
Формат командной строки | --innodb_flush_log_at_trx_commit[=#] | ||
Системная переменная | Имя |
innodb_flush_log_at_trx_commit | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | enumeration | |
Значение по умолчанию | 1 | ||
Допустимые значения | 0 | ||
1 | |||
2 |
Управляет балансом между строгой совместимостью с ACID для commit и и более высокой производительностью, которая возможна, когда передача связанных операций ввода/вывода перестроена и сделана в пакетах. Вы можете достигнуть лучшей производительности, изменяя значение по умолчанию, но тогда Вы можете потерять до секунды транзакций в катастрофическом отказе.
Значение по умолчанию 1 требуется для полного соответствия ACID. С этим значением содержимое буфера журнала записано в файл системного журнала в каждой передаче транзакции, и файл системного журнала сброшен на диск.
innodb_flush_log_at_timeout
,
который позволяет Вам устанавливать частоту сброса журнала в
N
секунд (где
N
1 ... 2700
, по умолчанию 1).
Однако, любой катастрофический отказ процесса
mysqld
может стереть до N
секунд транзакций.InnoDB
вызывают сброс
журнала, независимый от innodb_flush_log_at_trx_commit
.innodb_flush_log_at_trx_commit
.
Транзакции или применены полностью или стерты полностью.Для длительности и последовательности в установке репликации, которая
использует InnoDB
с транзакциями:
Если двоичное журналирование включено, установите
sync_binlog=1
.
innodb_flush_log_at_trx_commit=1
.
Много операционных систем и некоторые дисковые аппаратные средства дурачат
работу потока. Они могут сказать
mysqld, что
сброс имел место, даже при том, что это не так. Тогда длительность транзакций
не гарантируется даже с установкой 1, и в худшем случае отключение
электричества может даже повредить данные InnoDB
.
Использование поддержанного батареей дискового кэша в дисковом контроллере
SCSI или в самом диске делает работу более безопасной. Вы можете также
попытаться использовать команду Unix hdparm,
чтобы отключить кэширование диска или используйте некоторую другую команду,
определенную для аппаратных средств.
Формат командной строки | --innodb_flush_method=name | ||
Системная переменная | Имя |
innodb_flush_method
| |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения (Unix) | Тип | string | |
Значение по умолчанию | fsync | ||
Допустимые значения | fsync | ||
O_DSYNC | |||
littlesync | |||
nosync | |||
O_DIRECT | |||
O_DIRECT_NO_FSYNC | |||
Допустимые значения (Windows) | Тип | string | |
Значение по умолчанию | unbuffered | ||
Допустимые значения | unbuffered | ||
normal |
Определяет метод, используемый, чтобы сбросить данные к файлам с данными и файлам системного журнала, которые могут затронуть пропускную способность ввода/вывода.
В Unix-системах значение по умолчанию
fsync
. В Windows unbuffered
.
В MySQL 8.0 опции
innodb_flush_method
могут быть определены в цифровой форме.
innodb_flush_method
в Unix:
fsync
или 0
: InnoDB
использует fsync()
, чтобы сбросить данные и файлы системного
журнала. fsync
настройка по умолчанию.
O_DSYNC
или 1
:
InnoDB
использует O_SYNC
, чтобы
открыть и сбросить файлы системного журнала, и
fsync()
, чтобы сбросить файлы данных.
InnoDB
не использует O_DSYNC
непосредственно,
потому что были проблемы с этим на многих вариантах Unix.littlesync
или 2
:
Эта опция используется для тестирования собственной производительности и в
настоящее время не поддерживается. Используйте на ваш собственный риск.nosync
или 3
:
Эта опция используется для тестирования собственной производительности и в
настоящее время не поддерживается. Используйте на ваш собственный риск.O_DIRECT
или 4
:
InnoDB
использует O_DIRECT
(или directio()
в Solaris), чтобы открыть файлы данных, и
fsync()
, чтобы сбросить данные и файлы системного журнала.
Эта опция доступна на некоторых версиях GNU/Linux, FreeBSD и Solaris.O_DIRECT_NO_FSYNC
или 5
:
InnoDB
использует O_DIRECT
во время ввода/вывода, но пропускает fsync()
позже.
Эта установка является подходящей для некоторых типов файловых систем, но не
других. Например, это не является подходящим для XFS. Если Вы не уверены,
требует ли файловая система, которую Вы используете, fsync()
,
например, чтобы сохранить все метаданные о файле,
надо использовать O_DIRECT
.innodb_flush_method
в Windows:
unbuffered
или 0
:
InnoDB
использует моделируемый асинхронный ввод/вывод и
небуферизованный ввод/вывод.
normal
или 1
:
InnoDB
моделируемый асинхронный ввод/вывод и
буферизованный ввод/вывод.То, как каждая настройка затрагивают работу, зависит от конфигурации
аппаратных средств и рабочей нагрузки. Определите эффективность своей особой
конфигурации, чтобы решить, которую установку использовать или сохранить
настройку по умолчанию. Исследуйте
Innodb_data_fsyncs
, чтобы видеть общее количество fsync()
для
каждой установки. Соединение чтения и записи в Вашей рабочей нагрузке может
затронуть, как установка работает. Например, на системе с контроллером
RAID и поддержанным батареей кэшем
O_DIRECT
может помочь избежать двойной буферизации между
буферным пулом InnoDB
и кэшем файловой системы операционной
системы. На некоторых системах, где данные и файлы системного журнала
расположены на SAN, значении по умолчанию или O_DSYNC
могло бы быть быстрее для нагруженной чтением рабочей нагрузки с главным
образом запросами SELECT
. Всегда проверяйте этот параметр с
аппаратными средствами и рабочей нагрузкой, которые отражают Вашу
производственную среду. Для общих советов о настройке ввода/вывода см.
раздел 9.5.8.
innodb_flush_neighbors
Формат командной строки | --innodb_flush_neighbors | ||
Системная переменная | Имя |
innodb_flush_neighbors
| |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | enumeration | |
Значение по умолчанию | 1 | ||
Допустимые значения | 0 | ||
1 | |||
2 |
Определяет сброс страниц из буферного пула и другие грязные страницы в том же самом экстенте.
Значение по умолчанию 1 сбрасывает грязные страницы в том же самом экстенте из буферного пула.
innodb_flush_neighbors
и никакие другие грязные страницы из буферного пула не сбрасываются.Когда табличные данные хранятся на традиционном устройстве хранения данных HDD, сброс such соседних страниц в одной работе уменьшает ввод/вывод (прежде всего для операций поиска) по сравнению со сбросом отдельных страниц в разное время. Для табличных данных, хранимых на SSD, время поиска не значимый фактор, и Вы можете выключить эту установку. Для общих советов о настройке ввода/вывода см. раздел 9.5.8.
innodb_flush_sync
Формат командной строки | --innodb_flush_sync=# | ||
Системная переменная | Имя |
innodb_flush_sync
| |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | ON |
innodb_flush_sync
включен по умолчанию, вызывает установку
innodb_io_capacity
, которая будет проигнорирована для взрывов деятельности
ввода/вывода, которые происходят в
контрольных точках. Чтобы
придерживаться предела на фоновую деятельность ввода/вывода, определенного
innodb_io_capacity
, выключите innodb_flush_sync
.
innodb_flushing_avg_loops
Формат командной строки | --innodb_flushing_avg_loops=# | ||
Системная переменная | Имя |
innodb_flushing_avg_loops | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 30 | ||
Минимум | 1 | ||
Максимум | 1000 |
Число итераций, для которых InnoDB сохраняет ранее расчетный образ состояния сброса, управляя, как быстро quickly адаптивный сброс отвечает на изменяющуюся нагрузку. Увеличение значения заставляет уровень операций сброса измениться гладко и постепенно, как рабочая нагрузка изменяется. Уменьшение значения заставляет адаптивный сброс корректироваться быстро к изменениям рабочей нагрузки, что может вызвать пики сброса, если увеличения и уменьшения рабочей нагрузки внезапны.
innodb_force_load_corrupted
Формат командной строки | --innodb_force_load_corrupted | ||
Системная переменная | Имя |
innodb_force_load_corrupted | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Позволяет InnoDB загружать таблицы при запуске, которые отмечены как поврежденные. Используйте только во время поиска неисправностей, чтобы возвратить данные, которые иначе недоступны. Когда поиск неисправностей выполнен, выключите это и перезапустите сервер.
innodb_force_recovery
Формат командной строки | --innodb_force_recovery=# | ||
Системная переменная | Имя |
innodb_force_recovery | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 0 | ||
Минимум | 0 | ||
Максимум | 6 |
Режим восстановления
катастрофического отказа, измененный в серьезных ситуациях с поиском
неисправностей. Возможные значения от 0 до 6. Для смысла этих значений и
важной информации о innodb_force_recovery
см.
раздел 16.20.2.
Установите эту переменную в значение больше 0 в чрезвычайной ситуации,
чтобы Вы могли запустить InnoDB
и выведите свои таблицы в дамп.
Как мера по безопасности, InnoDB
запрещает
INSERT
,
UPDATE
или
DELETE
, когда
innodb_force_recovery
больше 0. Установка
innodb_force_recovery
в 4 или больше
переводит InnoDB
в режим только для чтения.
Эти ограничения могут заставить такие команды управления репликацией, как
--relay-log-info-repository=TABLE
и
--master-info-repository=TABLE
терпеть неудачу с ошибкой
сохранения информации в таблицах InnoDB
.
Формат командной строки | --innodb_ft_aux_table=# | ||
Системная переменная | Имя |
innodb_ft_aux_table | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | string |
Определяет полностью определенное имя таблицы, содержащей индекс
FULLTEXT
. Эта переменная предназначена в диагностических целях.
После того, как Вы устанавливаете эту переменную в имя в формате
,
таблицы db_name
/table_name
INFORMATION_SCHEMA
INNODB_FT_INDEX_TABLE
,
INNODB_FT_INDEX_CACHE
,
INNODB_FT_CONFIG
, INNODB_FT_DELETED
и
INNODB_FT_BEING_DELETED
покажет информацию о поисковом индексе для указанной таблицы.
innodb_ft_cache_size
Формат командной строки | --innodb_ft_cache_size=# | ||
Системная переменная | Имя |
innodb_ft_cache_size | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 8000000 | ||
Минимум | 1600000 | ||
Максимум | 80000000 |
Выделенная память в байтах для кэша FULLTEXT
, который держит
разобранный документ в памяти, создавая индекс FULLTEXT
.
Вставки и обновления сохранены на диск, когда предел размера
innodb_ft_cache_size
исчерпан. innodb_ft_cache_size
определяет размер кэша на таблицу. Чтобы установить глобальный предел для
всех таблиц см.
innodb_ft_total_cache_size
.
innodb_ft_enable_diag_print
Формат командной строки | --innodb_ft_enable_diag_print=# | ||
Системная переменная | Имя |
innodb_ft_enable_diag_print | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Включить ли дополнительный диагностический вывод полнотекстового поиска. Эта опция прежде всего предназначена для усовершенствованной отладки FTS и не будет представлять интерес для большинства пользователей. Вывод напечатан в журнал ошибок и включает такую информацию, как:
Ход синхронизации индекса FTS (когда предел кэша FTS достигнут). Например:
FTS SYNC for table test, deleted count: 100 size: 10000 bytes SYNC words: 100
FTS start optimize test FTS_OPTIMIZE: optimize "mysql" FTS_OPTIMIZE: processed "mysql"
Number of doc processed: 1000
FTS Search Processing time: 1 secs: 100 millisec: row(s) 10000 Full Search Memory: 245678 (bytes), Row: 10000
Формат командной строки | --innodb_ft_enable_stopword=# | ||
Системная переменная | Имя |
innodb_ft_enable_stopword | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | ON |
Определяет ряд стоп-слов,
связанный с индексом InnoDB
FULLTEXT
, когда индекс
создается. Если
innodb_ft_user_stopword_table
установлена, стоп-слова
взяты от той таблицы. Иначе если
innodb_ft_server_stopword_table
установлена, стоп-слова взяты от той таблицы. Иначе используется встроенный
набор стоп-слов по умолчанию.
innodb_ft_max_token_size
Формат командной строки | --innodb_ft_max_token_size=# | ||
Системная переменная | Имя |
innodb_ft_max_token_size | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 84 | ||
Минимум | 10 | ||
Максимум | 84 | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 84 | ||
Минимум | 10 | ||
Максимум | 84 |
Максимальная символьная длина слов, которые сохранены в индексе InnoDB
FULLTEXT
. Установка предела для этого значения уменьшает размер
индекса, таким образом ускоряя запросы, опуская долгие ключевые слова или
произвольные наборы символов, которые не являются реальными словами и вряд ли
будут критериями поиска.
innodb_ft_min_token_size
Формат командной строки | --innodb_ft_min_token_size=# | ||
Системная переменная | Имя |
innodb_ft_min_token_size | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 3 | ||
Минимум | 0 | ||
Максимум | 16 |
Минимальная длина слов, которые сохранены в индексе InnoDB
FULLTEXT
. Увеличение этого значения уменьшает размер индекса,
таким образом ускоряя запросы, опуская общее слово, которые вряд ли будут
существенными в контексте поиска, такие как английские слова
a и to. Для контента,
использующего набор символов CJK
(Chinese, Japanese, Korean), определяют значение 1.
innodb_ft_num_word_optimize
Формат командной строки | --innodb_ft_num_word_optimize=# | ||
Системная переменная | Имя |
innodb_ft_num_word_optimize | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 2000 |
Число слов, чтобы обработать во время каждого вызова
OPTIMIZE TABLE
для индекса
InnoDB
FULLTEXT
. Поскольку большая вставка или
обновление таблицы, содержащей полнотекстовый индекс может потребовать
существенное обслуживание индекса, чтобы включить все изменения, Вы могли бы
сделать серию OPTIMIZE TABLE
, продолжающих работу друг друга.
innodb_ft_result_cache_limit
Формат командной строки | --innodb_ft_result_cache_limit=# | ||
Системная переменная | Имя |
innodb_ft_result_cache_limit | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 2000000000 | ||
Минимум | 1000000 | ||
Максимум | 2**32-1 |
InnoDB
FULLTEXT search (FTS)
запрашивает предел кэша результата (определенный в байтах) на запрос FTS или
поток. Результаты запроса FTS обработаны в памяти. Используйте
innodb_ft_result_cache_limit
, чтобы устанавливать границу
размера кэша результатов FTS, чтобы избежать чрезмерного потребления памяти в
случае очень большого результата запроса FTS (миллионы или сотни миллионов
строк, например). Память выделена как требуется, когда запрос FTS
обработан. Если предел размера кэша результата достигнут, ошибка возвращена,
указывая, что запрос превышает максимальную позволенную память.
Максимальное значение innodb_ft_result_cache_limit
для всех
платформ 2**32-1. Bug #71554.
innodb_ft_server_stopword_table
Формат командной строки | --innodb_ft_server_stopword_table=db_name/table_name
| ||
Системная переменная | Имя |
innodb_ft_server_stopword_table | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | string | |
Значение по умолчанию | NULL |
Эта опция используется, чтобы определить Ваш собственный
список стоп-слов FULLTEXT
для всех таблицы. Сконфигурировать
Ваш собственный список для определенной таблицы можно через
innodb_ft_user_stopword_table
.
Установите innodb_ft_server_stopword_table
в
название таблицы, содержащей список стоп-слов, в формате
.
db_name
/table_name
Таблица должна существовать прежде, чем Вы сконфигурируете
innodb_ft_server_stopword_table
.
innodb_ft_enable_stopword
должен быть включен и
innodb_ft_server_stopword_table
должна быть сконфигурирована
прежде, чем Вы создадите FULLTEXT
.
Таблица должна быть таблицей InnoDB
с одним столбцом
VARCHAR
с именем value
.
Подробности в разделе 13.9.4.
innodb_ft_sort_pll_degree
Формат командной строки | --innodb_ft_sort_pll_degree=# | ||
Системная переменная | Имя |
innodb_ft_sort_pll_degree | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 2 | ||
Минимум | 1 | ||
Максимум | 32 |
Число потоков, чтобы параллельно индексировать и размечать текст в
индексе FULLTEXT
, при создании
поискового индекса. См.
innodb_sort_buffer_size
.
innodb_ft_total_cache_size
Формат командной строки | --innodb_ft_total_cache_size=# | ||
Системная переменная | Имя |
innodb_ft_total_cache_size | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 640000000 | ||
Минимум | 32000000 | ||
Максимум | 1600000000 |
Полная выделенная память в байтах для кэша поискового индекса FULLTEXT
для всех таблиц. Составление многочисленных таблиц, каждая с полнотекстовым
поисковым индексом, может потреблять существенную часть доступной памяти.
innodb_ft_total_cache_size
определяет глобальный предел памяти
для всего полнотекстового поиска, чтобы помочь избежать чрезмерного
потребления памяти. Если глобальный предел достигнут
вызвана принудительная синхронизация.
innodb_ft_user_stopword_table
Формат командной строки | --innodb_ft_user_stopword_table=db_name/table_name
| ||
Системная переменная | Имя |
innodb_ft_user_stopword_table | |
Область действия | Global, Session | ||
Динамическая | Да | ||
Допустимые значения | Тип | string | |
Значение по умолчанию | NULL |
Эта опция используется, чтобы определить Ваш список стоп-слов
FULLTEXT
на определенной таблице. Сконфигурировать Ваш
собственный список для всех таблиц можно с помощью
innodb_ft_server_stopword_table
.
Установите innodb_ft_user_stopword_table
в
название таблицы, содержащей список стоп-слов, в формате
.
db_name
/table_name
Таблица должна существовать прежде, чем Вы сконфигурируете
innodb_ft_user_stopword_table
.
innodb_ft_enable_stopword
должен быть включен и
innodb_ft_user_stopword_table
должен быть сконфигурирован
прежде, чем Вы создадите индекс FULLTEXT
.
Таблица должна быть таблицей InnoDB
с одним столбцом
VARCHAR
с именем value
.
innodb_io_capacity
Формат командной строки | --innodb_io_capacity=# | ||
Системная переменная | Имя |
innodb_io_capacity
| |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения (32-bit platforms) | Тип | integer | |
Значение по умолчанию | 200 | ||
Минимум | 100 | ||
Максимум | 2**32-1 | ||
Допустимые значения (64-bit platforms) | Тип | integer | |
Значение по умолчанию | 200 | ||
Минимум | 100 | ||
Максимум | 2**64-1 |
innodb_io_capacity
ставит верхний предел для деятельности ввода/вывода, выполненной
фоновыми задачами InnoDB
, например,
сбросом страниц из
буферного пула и слиянием данных
из буфера изменений.
innodb_io_capacity
полный предел для всех экземпляров буферного пула. Когда грязные
страницы сбрасываются, предел разделен одинаково среди буферных экземпляров.
innodb_io_capacity
должен быть установлен в приблизительно число операций
ввода/вывода, которые система может выполнить в секунду. Идеально сохранить
установку столь низкой, как возможно, но не настолько низкой, что фоновые
действия отстают. Если значение слишком высоко, данные удалены из буферного
пула и буфера вставок слишком быстро, чтобы кэшироваться и
обеспечить существенную выгоду.
Значение по умолчанию 200. Для занятых систем, способных к более высоким уровням ввода/вывода, Вы можете установить более высокое значение, чтобы помочь серверу обработать фоновую работу обслуживания, связанную с высоким показателем изменений строки.
Вообще, Вы можете увеличить значение как функцию числа дисков, используемых для ввода/вывода. Например, Вы можете увеличить значение на системах, которые используют много дисков или диски (SSD).
Настройка по умолчанию 200 вообще достаточна для SSD более низкого уровня.
Для более высокого уровня bus-attached SSD считают более высокую установку,
например 1000. Для систем с отдельными дисками на 5400 RPM или 7200 RPM
Вы могли бы снизить значение до 100
, которое представляет
предполагаемую пропорцию операций в секунду ввода/вывода (IOPS), доступную
дисководам старшего поколения, которые могли
выполнить приблизительно 100 IOPS.
Хотя Вы можете определить очень высокое значение, например, миллион, практически у таких больших значений мало пользы. Вообще, значение 20000 или выше не рекомендуется, если Вы не доказали, что меньшие значения недостаточны для Вашей рабочей нагрузки.
Рассмотрите рабочую нагрузку, настраивая
innodb_io_capacity
. Системы с большими записями, вероятно,
извлекут выгоду из более высокой установки. Более низкая установка может быть
достаточной для систем с маленьким уровнем записи.
Вы можете установить innodb_io_capacity
в 100
или больше до максимума, определенного
innodb_io_capacity_max
.
innodb_io_capacity
может быть установлен в файле опции MySQL
(my.cnf
или my.ini
)
или изменен динамически использованием SET GLOBAL
, что
требует привилегии SUPER
.
innodb_flush_sync
вызывает установку
innodb_io_capacity
, которая будет проигнорирована во время
взрывов деятельности ввода/вывода, которые происходят в контрольных точках.
innodb_flush_sync
включен по умолчанию.
См. раздел 16.6.7 .
innodb_io_capacity_max
Формат командной строки | --innodb_io_capacity_max=# | ||
Системная переменная | Имя |
innodb_io_capacity_max
| |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения (32-bit platforms) | Тип | integer | |
Значение по умолчанию | see description | ||
Минимум | 100 | ||
Максимум | 2**32-1 | ||
Допустимые значения (Unix, 64-bit platforms) | Тип | integer | |
Значение по умолчанию | См. описание | ||
Минимум | 100 | ||
Максимум | 2**64-1 | ||
Допустимые значения (Windows, 64-bit platforms) | Тип | integer | |
Значение по умолчанию | См. описание | ||
Минимум | 100 | ||
Максимум | 2**32-1 |
Если сброс отстает, InnoDB
может начать сбрасывать
более настойчиво чем предел, наложенный
innodb_io_capacity
.
innodb_io_capacity_max
определяет верхний предел
ввода/вывода в таких ситуациях.
innodb_io_capacity_max
это полный предел для
всех буферных экземпляров.
Если Вы определяете
innodb_io_capacity
при запуске, но не определяете значение для
innodb_io_capacity_max
, innodb_io_capacity_max
по умолчанию дважды значение
innodb_io_capacity
, но минимум 2000.
Конфигурируя innodb_io_capacity_max
, дважды
innodb_io_capacity
часто хорошая начальная точка. Значение по
умолчанию 2000 предназначено для рабочих нагрузок, которые используют диск
SSD или больше, чем один обычный диск. Установка 2000, вероятно, слишком
высока для рабочих нагрузок, которые не используют SSD или много дисков, и
могли позволить слишком большой сброс. Для единственного диска рекомендуется
установка между 200 и 400. Для bus-attached SSD ставьте более высокую
установку, около 2500. Как с
innodb_io_capacity
, сохраните установку столь низкой, как
можно, но не настолько низкой, чтобы InnoDB
не может достаточно масштабироваться вне предела
innodb_io_capacity
, если это надо.
Рассмотрите рабочую нагрузку, настраивая
innodb_io_capacity_max
. Системы с большой записью могут извлечь
выгоду из более высокой установки. Более низкая установка может быть
достаточной для систем с маленьким объемом записей.
innodb_io_capacity_max
не может быть установлен в значение ниже,
чем innodb_io_capacity
.
Установка
innodb_io_capacity_max
в DEFAULT
через
SET
(SET GLOBAL innodb_io_capacity_max=DEFAULT
) ставит
innodb_io_capacity_max
к максимальному значению.
См. раздел 16.6.3.7 .
innodb_limit_optimistic_insert_debug
Формат командной строки | --innodb_limit_optimistic_insert_debug=#
| ||
Системная переменная | Имя |
innodb_limit_optimistic_insert_debug | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 0 | ||
Минимум | 0 | ||
Максимум | 2**32-1 |
Ограничивает число записей на страницу
B-tree.
Значение по умолчанию 0 указывает, что никакой предел не наложен. Эта опция
доступна только если поддержка отладки собрана с использованием
WITH_DEBUG
в
CMake.
innodb_lock_wait_timeout
Формат командной строки | --innodb_lock_wait_timeout=# | ||
Системная переменная | Имя |
innodb_lock_wait_timeout | |
Область действия | Global, Session | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 50 | ||
Минимум | 1 | ||
Максимум | 1073741824 |
Отрезок времени в секундах, который транзакция ждет a блокировки строки перед отказом. Значение по умолчанию составляет 50 секунд. Транзакция, которая пытается получить доступ к строке, которая заблокирована другой транзакция ждет самое большее это число секунд для доступ к строке прежде, чем выпустить следующую ошибку:
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
Когда блокировка ждет и тайм-аут происходит, текущий запрос
откатывается (не вся транзакция!).
Чтобы вся транзакция откатывалась до прежнего уровня, запускайте сервер с
--innodb_rollback_on_timeout
. См.
раздел 16.20.4.
Вы могли бы уменьшить это значение для очень интерактивных приложений или систем OLTP, чтобы вывести на экран пользовательскую обратную связь быстро или поместить обновление в очередь для того, чтобы обработать позже. Вы могли бы увеличить это значение для продолжительных операций, таких как шаг преобразования в хранилище данных, которые ждут большой вставки или операций обновления, чтобы закончиться.
innodb_lock_wait_timeout
относится только к строковой
блокировке. Табличная блокировка
MySQL не происходит внутри InnoDB
и этот тайм-аут не относится к ожиданию табличных блокировок.
Значение тайм-аута не относится к
тупикам, когда
innodb_deadlock_detect
включен (значение по умолчанию) потому, что
InnoDB
обнаруживает тупики и откатывает одну
из заведенных в тупик транзакций. Когда
innodb_deadlock_detect
включен, InnoDB
полагается на
innodb_lock_wait_timeout
для операционной отмены,
когда тупик происходит.
innodb_lock_wait_timeout
может быть установлен во время выполнения
с помощью SET GLOBAL
или SET SESSION
. Изменение
GLOBAL
требует привилегии SUPER
и влияет на
работу всех клиентов, которые впоследствии соединяются. Любой клиент может
изменить SESSION
для
innodb_lock_wait_timeout
, который затрагивает только того клиента.
innodb_log_buffer_size
Формат командной строки | --innodb_log_buffer_size=# | ||
Системная переменная | Имя |
innodb_log_buffer_size | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 16777216 | ||
Минимум | 1048576 | ||
Максимум | 4294967295 | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 1048576 | ||
Минимум | 1048576 | ||
Максимум | 4294967295 |
Размер в байтах буфера для записи на диск файлов системного журнала. Значение по умолчанию составляет 16 МБ. Большой буфер журнала позволяет большим транзакциям работать без потребности писать журнал на диск прежде, чем транзакция transactions завершится. Таким образом, если у Вас есть транзакции, которые обновляют, вставляют или удаляют много строк, увеличение журнала сохраняет дисковый ввод/вывод. См. раздел 9.5.8.
innodb_log_checksums
Формат командной строки | --innodb_log_checksums=# | ||
Системная переменная | Имя |
innodb_log_checksums | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | ON |
Включает или отключает контрольные суммы для страницы журнала redo.
innodb_log_checksums=ON
включает алгоритм CRC-32C
контрольной суммы для страницы журнала redo. Когда
innodb_log_checksums
отключен, содержание области контрольной
суммы страницы журнала проигнорировано.
Контрольные суммы на заголовке страницы журнала и странице контрольной точки журнала никогда не отключаются.
innodb_log_compressed_pages
Формат командной строки | --innodb_log_compressed_pages=# | ||
Системная переменная | Имя |
innodb_log_compressed_pages | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | ON |
Определяет, записаны ли образы пересжатых страниц в журнал redo. Пересжатие может произойти, когда изменения произведены в сжатых данных.
innodb_log_compressed_pages
включен по умолчанию, чтобы
предотвратить повреждение, которое могло произойти, если иная версия
алгоритма сжатия zlib
используется во время восстановления.
Если Вы уверены, что версия zlib
не будет изменяться, Вы можете
отключить innodb_log_compressed_pages
, чтобы уменьшить
журнал для рабочих нагрузок, которые изменяют сжатые данные.
Измерить эффект включения или отключения
innodb_log_compressed_pages
можно, сравнивая генерацию журнала
redo для обеих настроек при той же самой рабочей нагрузке.
Это включает наблюдение за Log sequence number
(LSN) в разделе
LOG
вывода SHOW ENGINE
INNODB STATUS
или мониторинг
Innodb_os_log_written
для числа байтов, написанных
в файлы журнала redo.
innodb_log_file_size
Формат командной строки | --innodb_log_file_size=# | ||
Системная переменная | Имя |
innodb_log_file_size | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 50331648 | ||
Минимум | 4194304 | ||
Максимум | 512GB / innodb_log_files_in_group | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 5242880 | ||
Минимум | 1048576 | ||
Максимум | 4294967295 |
Размер в байтах каждого
файла системного журнала в
группе журнала. Объединенный размер файлов системного журнала
(innodb_log_file_size
*
innodb_log_files_in_group
) не может превысить максимальное
значение, которое является немного меньше 512 ГБ. Пара файлов по 255 GB
, например, позволила бы Вам приближаться к пределу, но не превышать его.
Значение по умолчанию составляет 48 МБ. Заметные значения колеблются от 4 МБ
до 1/N
размера
буферного пула, где N
число файлов системного
журнала в группе. Чем больше значение, тем меньше деятельности потока
контрольной точки необходимо в буферном пуле, сохраняя дисковый ввод/вывод.
Большие файлы системного журнала также делают
восстановление катастрофического
отказа медленнее, хотя усовершенствования работы восстановления в MySQL
5.5 и выше делают размер файла системного журнала меньше.
Минимум innodb_log_file_size
увеличен с 1MB до 4MB в MySQL
8.0.
innodb_log_files_in_group
Формат командной строки | --innodb_log_files_in_group=# | ||
Системная переменная | Имя |
innodb_log_files_in_group | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 2 | ||
Минимум | 2 | ||
Максимум | 100 |
Число файлов системного журнала
в группе журнала.
InnoDB
пишет файлы круговым способом. Значение по умолчанию (и
рекомендуемое) значение 2. Местоположение этих файлов определено
innodb_log_group_home_dir
. Объединенный размер файлов системного
журнала (
innodb_log_file_size
*innodb_log_files_in_group
)
может быть до 512 ГБ.
innodb_log_group_home_dir
Формат командной строки | --innodb_log_group_home_dir=dir_name | ||
Системная переменная | Имя |
innodb_log_group_home_dir | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | directory name |
Путь к каталогу с файлами
журнала redo,
число которых определено
innodb_log_files_in_group
. Если Вы не определяете
переменные журнала, значение по умолчанию должно создать два файла
ib_logfile0
и ib_logfile1
в
каталоге данных MySQL. Их размер задан в
innodb_log_file_size
.
innodb_log_write_ahead_size
Формат командной строки | --innodb_log_write_ahead_size=# | ||
Системная переменная | Имя |
innodb_log_write_ahead_size | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 8192 | ||
Минимум | 512 (log file block size) | ||
Максимум | Equal to innodb_page_size |
Размер блока для журнала redo в байтах. Чтобы избежать
avoid чтения на записи, установите
innodb_log_write_ahead_size
, чтобы
соответствовать размеру блока кэша файловой системы. Чтение на записи
происходит, когда блоки журнала не полностью кэшируются файловой системой
из-за несоответствия написанным размером блока и размером
блока кэша файловой системы.
Минимальное значение размер блока файла системного журнала (512).
Предзапись не происходит, когда минимальное значение определено. Максимальное
значение равно
innodb_page_size
. Если Вы определяете значение для
innodb_log_write_ahead_size
больше
innodb_page_size
, innodb_log_write_ahead_size
усечено к
innodb_page_size
.
Установка innodb_log_write_ahead_size
слишком низко относительно операционной системы или размера блока кэша
файловой системы приведет к чтению на записи.
Установка значения слишком высоким может оказать небольшое влияние на
производительность fsync
для файла системного журнала из-за
нескольких блоков, написанных сразу.
innodb_lru_scan_depth
Формат командной строки | --innodb_lru_scan_depth=# | ||
Системная переменная | Имя |
innodb_lru_scan_depth | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения (32-bit platforms) | Тип | integer | |
Значение по умолчанию | 1024 | ||
Минимум | 100 | ||
Максимум | 2**32-1 | ||
Допустимые значения (64-bit platforms) | Тип | integer | |
Значение по умолчанию | 1024 | ||
Минимум | 100 | ||
Максимум | 2**64-1 |
Параметр, который влияет на алгоритмы и эвристику для работы the сброса буферного пула. Прежде всего интересен для исполнительных экспертов, настраивающих рабочие нагрузки. Это определяет для экземпляра буферного пула как далеко вниз поток уборщика страницы просматривает список LRU, ища грязные страницы, чтобы сбросить. Это фоновая работа, выполненная раз в секунду.
Установка, меньшая чем значение по умолчанию, является вообще подходящей для большинства рабочих нагрузок. Значение, которое намного выше, чем необходимо, может воздействовать на работу. Рассмотрите увеличение значения только если у Вас есть запас ввода/вывода при типичной рабочей нагрузке. Наоборот, если рабочая нагрузка насыщает Ваш ввод/вывод, уменьшите значение, особенно в случае большого буферного пула.
Настраивая innodb_lru_scan_depth
, начните с низкого
значения и сконфигурируйте установку с целью редкого наблюдения нулевых
свободных страниц. Кроме того, рассмотрите корректировку
innodb_lru_scan_depth
, изменяя число буферных экземпляров.
innodb_lru_scan_depth
*
innodb_buffer_pool_instances
определяет объем работы, выполненный потоком уборщика
страницы каждую секунду.
innodb_max_dirty_pages_pct
Формат командной строки | --innodb_max_dirty_pages_pct=# | ||
Системная переменная | Имя |
innodb_max_dirty_pages_pct | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | numeric | |
Значение по умолчанию | 75 | ||
Минимум | 0 | ||
Максимум | 99.99 | ||
Допустимые значения | Тип | numeric | |
Значение по умолчанию | 90 | ||
Минимум | 0 | ||
Максимум | 100 |
InnoDB
пытается сбросить
данные из буферного пула,
чтобы процент грязных страниц
не превысил это значение. Значение по умолчанию 75.
innodb_max_dirty_pages_pct
устанавливает цель для сброса.
Это не затрагивает уровень сброса. Для информации об управлении уровнем
сброса см. раздел
16.6.3.6.
Подробности в разделе 16.6.3.7.
innodb_max_dirty_pages_pct_lwm
Формат командной строки | --innodb_max_dirty_pages_pct_lwm=# | ||
Системная переменная | Имя |
innodb_max_dirty_pages_pct_lwm | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | numeric | |
Значение по умолчанию | 0 | ||
Минимум | 0 | ||
Максимум | 99.99 |
Нижний процент грязных страниц , где предварительный сброс управляет коэффициентом грязных страниц. Значение по умолчанию 0 отключает предварительный сброс полностью. Для дополнительной информации об этой переменной см. раздел 16.6.3.7.
innodb_max_purge_lag
Формат командной строки | --innodb_max_purge_lag=# | ||
Системная переменная | Имя |
innodb_max_purge_lag | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 0 | ||
Минимум | 0 | ||
Максимум | 4294967295 |
Эта переменная управляет, как задержатся
INSERT
,
UPDATE
и
DELETE
, когда
чистка отстает (см.
раздел 16.3).
Значение по умолчанию 0 (никаких задержек).
Система транзакций поддерживает список транзакций, которые имеют
индексные записи, помеченные для удаления,
UPDATE
или
DELETE
. Длина этого списка
представляет purge_lag
. Когда
purge_lag
превышает
innodb_max_purge_lag
, каждый запрос INSERT
,
UPDATE
и
DELETE
задержится.
Чтобы предотвратить чрезмерные задержки, где
purge_lag
становится огромным, Вы можете поправить
количество задержки, устанавливая
innodb_max_purge_lag_delay
.
Задержка вычислена в начале пакета чистки.
Типичная установка для проблематичной рабочей нагрузки могла бы быть 1 миллионом, предполагая, что транзакции являются маленькими, только 100 байтов в размере, и допустимо иметь 100 МБ неочищенных строк таблиц.
Значение задержки выведено на экран как длина списка истории в разделе
TRANSACTIONS
InnoDB Monitor.
Например, если вывод включает следующие строки, значение задержки 20:
------------ TRANSACTIONS ------------ Trx id counter 0 290328385 Purge done for trx's n:o < 0 290315608 undo n:o < 0 17 History list length 20
innodb_max_purge_lag_delay
Формат командной строки | --innodb_max_purge_lag_delay=# | ||
Системная переменная | Имя |
innodb_max_purge_lag_delay | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 0 | ||
Минимум | 0 |
Определяет максимальную задержку в миллисекундах для задержки, наложенной
innodb_max_purge_lag
. Любое ненулевое значение представляет верхний предел времени
задержки, вычисленном от формулы, основанной на значении
innodb_max_purge_lag
. Значение по умолчанию 0 значит, что нет
никакого верхнего предела, наложенного на интервал задержки.
innodb_max_undo_log_size
Формат командной строки | --innodb_max_undo_log_size=# | ||
Системная переменная | Имя |
innodb_max_undo_log_size | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 1073741824 | ||
Минимум | 10485760 | ||
Максимум | 2**64-1 |
innodb_max_undo_log_size
определяет пороговый размер для
табличных пространств отмены. Если табличное пространство отмены превышает
порог, оно может быть отмечено для усечения, когда
innodb_undo_log_truncate
включен. Значение по
умолчанию 1024 MiB (1073741824 байт).
См. раздел 16.7.8.
innodb_merge_threshold_set_all_debug
Формат командной строки | --innodb_merge_threshold_set_all_debug=#
| ||
Системная переменная | Имя |
innodb_merge_threshold_set_all_debug | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 50 | ||
Минимум | 1 | ||
Максимум | 50 |
Переопределяет текущее значение MERGE_THRESHOLD
указанным значением для всех индексов, которые в настоящее время находятся в
кэше словаря. Эта опция доступна только, если поддержка отладки собрана с
использованием WITH_DEBUG
в CMake. См.
раздел 16.6.11.
innodb_monitor_disable
Формат командной строки | --innodb_monitor_disable=[counter|module|pattern|all]
| ||
Системная переменная | Имя |
innodb_monitor_disable
| |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | string
|
Выключает один или более
счетчиков в таблице
INFORMATION_SCHEMA.INNODB_METRICS
. См.
раздел 22.30.16.
innodb_monitor_disable='latch'
отключает набор статистики для
SHOW ENGINE INNODB MUTEX
. См.
раздел 14.7.5.15.
innodb_monitor_enable
Формат командной строки | --innodb_monitor_enable=[counter|module|pattern|all]
| ||
Системная переменная | Имя |
innodb_monitor_enable | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | string |
Включает один или более
счетчиков в таблице
INFORMATION_SCHEMA.INNODB_METRICS
. См.
раздел 22.30.16.
innodb_monitor_enable='latch'
включает набору статистики для
SHOW ENGINE INNODB MUTEX
. См.
раздел 14.7.5.15.
innodb_monitor_reset
Формат командной строки | --innodb_monitor_reset=[counter|module|pattern|all]
| ||
Системная переменная | Имя |
innodb_monitor_reset | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | string |
Сбрасывает в 0 значение для одного или более
счетчиков в таблице
INFORMATION_SCHEMA.INNODB_METRICS
. См.
раздел 22.30.16.
innodb_monitor_reset='latch'
обнуляет статистику,
которую сообщает SHOW ENGINE
INNODB MUTEX
. См.
раздел 14.7.5.15.
innodb_monitor_reset_all
Формат командной строки | --innodb_monitor_reset_all=[counter|module|pattern|all]
| ||
Системная переменная | Имя |
innodb_monitor_reset_all | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | string |
Сбрасывает все значения (минимум, максимум и так далее) для одного или
более счетчиков в таблице
INFORMATION_SCHEMA.INNODB_METRICS
. См.
раздел 22.30.16.
innodb_numa_interleave
Формат командной строки | --innodb_numa_interleave=# | ||
Системная переменная | Имя |
innodb_numa_interleave
| |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Включает политику чередования памяти NUMA для распределения
буферного пула. Когда innodb_numa_interleave
включен, политика памяти NUMA установлена в MPOL_INTERLEAVE
для процесса mysqld
. После того, как буферный пул выделен, политика памяти NUMA
возвращена к MPOL_DEFAULT
. Для доступности опции
innodb_numa_interleave
MySQL должен быть собран
на NUMA-системе.
innodb_old_blocks_pct
Формат командной строки | --innodb_old_blocks_pct=# | ||
Системная переменная | Имя |
innodb_old_blocks_pct
| |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 37 | ||
Минимум | 5 | ||
Максимум | 95 |
Определяет приблизительный процент
буферного пула, используемый для
подсписка старых блоков.
Диапазон значений 5-95. Значение по умолчанию 37 (то есть, 3/8 пула). Часто
используется в комбинации с
innodb_old_blocks_time
. См. разделы
16.6.3.4
и 16.6.3.1.
innodb_old_blocks_time
Формат командной строки | --innodb_old_blocks_time=# | ||
Системная переменная | Имя |
innodb_old_blocks_time | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 1000 | ||
Минимум | 0 | ||
Максимум | 2**32-1 |
Ненулевые значения защищают от заполнения буферного пула данными, на которые ссылаются только в течение краткого периода, как во время полного сканирования таблицы . Увеличение этого значения предлагает больше защиты от полного сканирования таблицы, вмешивающегося в данные, кэшируемые в буферном пуле.
Определяет, сколько времени в миллисекундах блок, вставленный в подсписок старых, должен остаться там после первого доступа к нему прежде, чем может быть перемещен в подсписок новых. Если значение 0, блок, вставленный в подсписок старых, немедленно перемещается в подсписок новых, когда к нему в первый раз получают доступ, независимо от того, как скоро после вставки доступ происходит. Если значение больше 0, блоки остаются в старом подсписке, пока доступ не происходит, по крайней мере указанное число миллисекунды после первого доступа. Например, значение 1000 предписывает блокам остаться в старом подсписке в течение 1 секунды после первого доступа прежде, чем они смогут переместиться в новый подсписок.
Значение по умолчанию 1000.
Эта переменная часто используется в комбинации с
innodb_old_blocks_pct
. См. разделы
16.6.3.4 и
16.6.3.1.
innodb_online_alter_log_max_size
Формат командной строки | --innodb_online_alter_log_max_size=# | ||
Системная переменная | Имя |
innodb_online_alter_log_max_size | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 134217728 | ||
Минимум | 65536 | ||
Максимум | 2**64-1 |
Определяет верхний предел на размер временных файлов системного журнала,
используемых во время операций online
DDL. Есть один такой файл системного журнала для каждого создаваемого
индекса или при изменении таблицы. Этот файл системного журнала хранит
данные, вставленные, обновленные или удаленные в таблице во время работы DDL.
Временный файл системного журнала расширен при необходимости значением
innodb_sort_buffer_size
, до максимума, определенного
innodb_online_alter_log_max_size
.
Если какой-либо временный файл системного журнала превышает верхний предел
размера, ALTER TABLE
терпит неудачу, и все нейтральные параллельные операции DML откачены. Таким
образом, большое значение для этой опции позволяет большему количеству DML
происходить во время работы DDL онлайн, но также и вызывает более длинный
период в конце работы DDL, когда таблица заблокирована,
чтобы применить данные журнала.
innodb_open_files
Формат командной строки | --innodb_open_files=# | ||
Системная переменная | Имя |
innodb_open_files | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | -1 (autosized) | ||
Минимум | 10 | ||
Максимум | 4294967295 |
Эта переменная релевантна, только если Вы используете много
табличных пространств.
Это определяет максимальное количество файлов
.ibd
,
которые MySQL может сохранить открытыми одновременно. Минимальное
значение 10. Значение по умолчанию 300, если
innodb_file_per_table
не включен, иначе выше 300 и
table_open_cache
.
Описатели файла, используемые для .ibd
, только для таблиц.
Они независимы от определенных
--open-files-limit
и не затрагивают работу табличного кэша.
innodb_optimize_fulltext_only
Формат командной строки | --innodb_optimize_fulltext_only=# | ||
Системная переменная | Имя |
innodb_optimize_fulltext_only | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Изменяет путь, которым OPTIMIZE
TABLE
воздействует на таблицы. Предназначен, чтобы быть включенным
временно, во время операций обслуживания для
таблиц с индексами FULLTEXT
.
По умолчанию OPTIMIZE TABLE
реорганизует данные в
кластеризируемом индексе
таблицы. Когда эта опция включена, OPTIMIZE TABLE
пропускает эту перестройку табличных данных, а вместо этого обрабатывают
недавно добавленные, удаленные и обновленные маркерные данные для индекса
FULLTEXT
. См. раздел
16.8.9.
innodb_page_cleaners
Формат командной строки | --innodb_page_cleaners=# | ||
Системная переменная | Имя |
innodb_page_cleaners | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 4 | ||
Минимум | 1 | ||
Максимум | 64 |
Число потоков уборщика страницы, которые сбрасывают грязные страницы от
буферных экземпляров. Потоки уборщика страницы выполняют сброс списка и LRU.
Значение по умолчанию 4. Если число потоков уборщика страницы превышает
число буферных экземпляров, innodb_page_cleaners
автоматически установлен в то же самое значение, как
innodb_buffer_pool_instances
.
Если Ваша рабочая нагрузка связана write-IO (сбрасывая грязные страницы от буферных экземпляров в файлы с данными) и если у Ваших системных аппаратных средств есть полезная мощность, увеличение числа потоков уборщика страницы может помочь улучшить пропускную способность.
Мультипоточная поддержка уборщика страницы также расширена на фазы восстановления и завершения работы.
setpriority()
применяется в Linux
(где он поддержан и где пользователь
mysqld
авторизован), чтобы дать page_cleaner
приоритет над другими потоками MySQL/InnoDB, чтобы ускорить сброс страниц
с текущей рабочей нагрузкой. Пользователь для выполнения
mysqld
может быть сконфигурирован в /etc/security/limits.conf
.
Например, если if mysqld
выполнен под пользователем mysql
,
Вы могли бы разрешить mysql
добавляя строки, подобные следующим,
в /etc/security/limits.conf
:
mysqlhardnice -20 mysqlsoftnice -20
innodb_page_size
Формат командной строки | --innodb_page_size=#k | ||
Системная переменная | Имя |
innodb_page_size | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | enumeration | |
Значение по умолчанию | 16384 | ||
Допустимые значения | 4k | ||
8k | |||
16k | |||
32k | |||
64k | |||
4096 | |||
8192 | |||
16384 | |||
32768 | |||
65536 |
Определяет размер страницы
для всех табличных пространств в
экземпляре MySQL.
Вы можете определить размер страницы, используя значения 64k, 32k,
16k
(по умолчанию), 8k
или 4k
.
Альтернативно, Вы можете определить размер страницы в байтах
(65536, 32768, 16384, 8192, 4096).
innodb_page_size
может быть сконфигурирован только до инициализации MySQL и не может быть
изменен позже. Если никакое значение не определено, сервер инициализирован,
используя размер страницы по умолчанию.
Для размеров страницы 32k и 64k максимальная длина строки составляет
приблизительно 16000 байт. ROW_FORMAT=COMPRESSED
не поддержан, когда innodb_page_size
32KB или 64KB. Для
innodb_page_size=32k
размер экстента 2MB. Для
innodb_page_size=64k
размер экстента 4MB.
innodb_log_buffer_size
должен быть установлен по крайней мере в
16M (значение по умолчанию), используя размер страницы 32k или 64k.
Размер страницы по умолчанию 16 КБ и больше является подходящим для широкого диапазона рабочих нагрузок , особенно для запросов, вовлекающих сканирование таблицы и операции DML, вовлекающие оптовые обновления. Меньшие размеры страницы могли бы быть более эффективными для рабочих нагрузок OLTP, вовлекающих много маленьких записей, где утверждение может быть проблемой, когда единственная страница содержит много строк. Меньшие страницы могли бы также быть эффективными с устройствами хранения данных SSD, которые как правило используют маленькие размеры блока. Хранение размера страницы близким к размеру блока устройства хранения данных минимизирует количество неизменных данных, которые переписаны на диск.
Минимальный размер файла для первого системного файла с данными табличного
пространства (ibdata1
) отличается в зависимости от
innodb_page_size
. См.
innodb_data_file_path
.
innodb_print_all_deadlocks
Формат командной строки | --innodb_print_all_deadlocks=# | ||
Системная переменная | Имя |
innodb_print_all_deadlocks | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Когда эта опция включена, информация обо всех
тупиках в
пользовательских транзакциях зарегистрирована в
журнале ошибок.
Иначе Вы видите информацию только о последнем тупике, используя
SHOW ENGINE INNODB STATUS
. Случайный тупик не обязательно
проблема, потому что InnoDB
немедленно обнаруживает условие и откатывает одну из транзакций
автоматически. Вы могли бы использовать эту опцию, чтобы расследовать, почему
тупики происходят, если у приложения нет соответствующей логики обработки
ошибок, чтобы обнаружить откат и повторить ее работу. Большое количество
тупиков могло бы указать на потребность реструктурировать транзакции
DML или SELECT ... FOR
UPDATE
для многих таблиц так, чтобы каждая транзакция получила доступ
к таблицам в том же самом порядке, таким образом избегая условия тупика.
innodb_purge_batch_size
Формат командной строки | --innodb_purge_batch_size=# | ||
Системная переменная | Имя |
innodb_purge_batch_size | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 300 | ||
Минимум | 1 | ||
Максимум | 5000 |
Определяет число страниц журнала отмены, которые производят чистку
в одном пакете списка истории.
В мультипоточной конфигурации чистки поток делится координатором по
innodb_purge_threads
и назначает это число страниц к каждому
потоку чистки. innodb_purge_batch_size
также определяет число
страниц журнала отмены, которые чистка освобождает после каждых 128 итераций
через журналы отмены.
innodb_purge_batch_size
предназначена для усовершенствованной
работы, настраивающей комбинацию с
innodb_purge_threads
. Большинство пользователей MySQL не должно изменять
innodb_purge_batch_size
.
innodb_purge_threads
Формат командной строки | --innodb_purge_threads=# | ||
Системная переменная | Имя |
innodb_purge_threads | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 4 | ||
Минимум | 1 | ||
Максимум | 32 |
Число фоновых потоков, посвященных чистке. Минимальное значение 1 показывает, что работа чистки всегда выполняется фоновым потоком, никогда как часть мастер-потока. Выполнение работы чистки в одном или более фоновых потоках помогает уменьшить внутренние издержки и улучшить масштабируемости. Увеличение значения к большему, чем 1, создает много отдельных потоков чистки, которые могут улучшить эффективность относительно систем, где операции DML выполнены на многих таблицах. Максимум 32.
innodb_purge_threads
по умолчанию 4.
innodb_purge_rseg_truncate_frequency
Формат командной строки | --innodb_purge_rseg_truncate_frequency=#
| ||
Системная переменная | Имя |
innodb_purge_rseg_truncate_frequency | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 128 | ||
Минимум | 1 | ||
Максимум | 128 |
innodb_purge_rseg_truncate_frequency
определяет частоту, с которой система чистки освобождает сегменты отмены.
Табличное пространство отмены не может быть усечено, пока его сегменты отмены
не освобождены. Обычно система чистки освобождает сегменты отмены каждые 128
вызовов. Сокращение innodb_purge_rseg_truncate_frequency
увеличивает частоту, с которой поток чистки освобождает сегменты отмены.
Значение по умолчанию 128.
innodb_purge_rseg_truncate_frequency
предназначен для использования с
innodb_undo_log_truncate
. См.
раздел 16.7.8.
innodb_random_read_ahead
Формат командной строки | --innodb_random_read_ahead=# | ||
Системная переменная | Имя |
innodb_random_read_ahead | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Включает случайный метод
предвыборки, чтобы оптимизировать
InnoDB
I/O.
См. раздел 16.6.3.5 .
innodb_read_ahead_threshold
Формат командной строки | --innodb_read_ahead_threshold=# | ||
Системная переменная | Имя |
innodb_read_ahead_threshold | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 56 | ||
Минимум | 0 | ||
Максимум | 64 |
Управляет чувствительностью линейной
предвыборки, которую
использует InnoDB
, чтобы предварительно принести страницы в
буферный пул. Если
InnoDB
читает по крайней мере
innodb_read_ahead_threshold
страниц последовательно из
экстента (64 страницы), это начинает
асинхронное чтение для всего следующего экстента.
Допустимый диапазон значений от 0 до 64. Значение 0 отключает предвыборку.
Для значения по умолчанию 56 InnoDB
должен считать по крайней
мере 56 страниц последовательно, чтобы начать асинхронное чтение
для следующего экстента.
Знание, сколько страниц считано через этот механизм
и сколько из них выселено из буферного пула без того, чтобы когда-либо к ним
обратились, может быть полезным, чтобы помочь точно настроить
innodb_read_ahead_threshold
.
SHOW ENGINE INNODB STATUS
выводит на экран информацию из
Innodb_buffer_pool_read_ahead
и
Innodb_buffer_pool_read_ahead_evicted
.
Эти переменные указывают на число страниц, принесенных в
буферный пул запросами
предвыборки, и число
вычеркнутых страниц,
которые не понадобились. Эти счетчики обеспечивают глобальные значения,
начиная с последнего перезапуска сервера.
SHOW ENGINE INNODB STATUS
также показывает коэффициент чтения страниц и коэффициент вычеркивания
страниц. Средние числа в секунду основаны на статистических данных, собранных
начиная с последнего запроса SHOW ENGINE INNODB STATUS
и
выведены на экран в разделе BUFFER POOL AND MEMORY
.
См. раздел 16.6.3.5.
innodb_read_io_threads
Формат командной строки | --innodb_read_io_threads=# | ||
Системная переменная | Имя |
innodb_read_io_threads
| |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 4 | ||
Минимум | 1 | ||
Максимум | 64 |
Число потоков ввода/вывода для операций чтения. Значение по умолчанию 4. См. раздел 16.6.6 .
В Linux, выполняя много серверов MySQL (как правило, больше 12) с
настройками по умолчанию для innodb_read_io_threads
,
innodb_write_io_threads
, настройка aio-max-nr
может превысить системные пределы. Идеально увеличить
aio-max-nr
, но как обходное решение, Вы могли бы уменьшить
настройки для одного или обоих из параметров конфигурации MySQL.
Формат командной строки | --innodb_read_only=# | ||
Системная переменная | Имя |
innodb_read_only | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Запустить InnoDB
в режиме read-only.
Для того, чтобы распределить приложения базы данных или наборы данных.
Может также использоваться в хранилищах данных, чтобы совместно
использовать тот же самый каталог данных многими экземплярами. См.
раздел 16.6.2.
Ранее, включение
innodb_read_only
блокировало создание и удаление таблиц только для
InnoDB
. В MySQL 8.0 включение
innodb_read_only
блокирует эти операции для всех механизмов хранения. Табличное создание
и удаление изменяют таблицы словаря данных в системной базе данных
mysql
, но те таблицы используют механизм хранения
InnoDB
и не могут быть изменены, когда включен
innodb_read_only
. Тот же самый принцип относится к другим табличным операциям, которые
требуют изменения таблиц словаря данных:
ANALYZE TABLE
терпит неудачу, потому что это обновляет табличные статистические данные,
которые сохранены в словаре данных.
ALTER TABLE tbl_name
ENGINE=engine_name
терпит неудачу, потому что это обновляет обозначение механизма хранения,
которое сохранено в словаре данных.Кроме того, другие таблицы в системной базе данных mysql
используют механизм хранения InnoDB
в MySQL 8.0.
Перевод тех таблиц в режим только для чтения приводит к ограничениям на
операции, которые изменяют их. Примеры:
Запросы ведения учетных данных
CREATE USER
и
GRANT
терпят неудачу, потому что таблицы используют InnoDB
.
INSTALL PLUGIN
и
UNINSTALL PLUGIN
терпят
неудачу потому что таблица plugin
в InnoDB
.CREATE FUNCTION
и
DROP FUNCTION
терпят
неудачу потому что таблица func
в InnoDB
.
Формат командной строки | --innodb_replication_delay=# | ||
Системная переменная | Имя |
innodb_replication_delay
| |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 0 | ||
Минимум | 0 | ||
Максимум | 4294967295 |
Задержка потока репликации (в ms) на ведомом сервере, если достигнут
innodb_thread_concurrency
.
innodb_rollback_on_timeout
Формат командной строки | --innodb_rollback_on_timeout | ||
Системная переменная | Имя |
innodb_rollback_on_timeout | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
В MySQL 8.0 InnoDB
откатывает
только последний запрос об операционном тайм-ауте по умолчанию. Если
--innodb_rollback_on_timeout
указан, операционный тайм-аут
откатывает всю транзакцию.
innodb_rollback_segments
Формат командной строки | --innodb_rollback_segments=# | ||
Системная переменная | Имя |
innodb_rollback_segments
| |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 128 | ||
Минимум | 1 | ||
Максимум | 128 |
Определяет, сколько из
сегментов отмены в
системном табличном
пространстве используется для
транзакций.
Эта установка все еще допустима, но заменена
innodb_undo_logs
.
innodb_saved_page_number_debug
Формат командной строки | --innodb_saved_page_number_debug=# | ||
Системная переменная | Имя |
innodb_saved_page_number_debug | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 0 | ||
Максимум | 2**23-1 |
Сохраняет номер страницы. Установка
innodb_fil_make_page_dirty_debug
помечает страницу, определенную
innodb_saved_page_number_debug
как грязную. Опция
innodb_saved_page_number_debug
доступна только, если поддержка
отладки собрана с использованием
WITH_DEBUG
в
CMake.
innodb_sort_buffer_size
Формат командной строки | --innodb_sort_buffer_size=# | ||
Системная переменная | Имя |
innodb_sort_buffer_size
| |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 1048576 | ||
Минимум | 65536 | ||
Максимум | 67108864 |
Определяет размер буферов, используемых для того, чтобы сортировать данные
во время создания индекса InnoDB
. Определенный размер определяет
данные, заполняющие память для внутренней сортировки и записанные на диск,
которые могут упоминаться как run.
Во время фазы слияния пары буферов указанного размера читаются
и сливаются. Чем больше установка, тем
меньше runs и слияния.
Эта область используется только для сортировок слиянием во время создания индекса, не во время обслуживания индекса. Буферы освобождены, когда создание индекса завершается.
Значение этой опции также управляет на сколько временный файл системного журнала расширен, чтобы сделать запись параллельного DML во время операций online DDL.
Прежде, чем эта установка была сделана конфигурируемой, размер был 1048576 байт (1MB), это значение остается значением по умолчанию.
Во время ALTER TABLE
или
CREATE TABLE
, которые
создают индекс, 3 буфера выделено, каждый с размером, определенным этой
опцией. Дополнительно вспомогательные указатели выделены строкам в буфере
сортировки так, чтобы сортировка могла работать на указателях (в
противоположность перемещаемым строкам).
Для типичной работы сортировки может использоваться такая формула, чтобы оценить потребление памяти:
(6 /*FTS_NUM_AUX_INDEX*/ * (3*@@global.innodb_sort_buffer_size) + 2 * number_of_partitions * number_of_secondary_indexes_created * (@@global.innodb_sort_buffer_size/dict_index_get_min_size(index)*/) * 8 /*64-bit sizeof *buf->tuples*/")
@@global.innodb_sort_buffer_size/dict_index_get_min_size(index)
указывает на максимальные проводимые кортежи. 2 *
(@@global.innodb_sort_buffer_size/*dict_index_get_min_size(index)*/)
* 8 /*64-bit size of *buf->tuples*/
указывает на вспомогательные выделенные указатели.
Для 32-bit множитель 4 вместо 8.
Для параллельных сортировок на полнотекстовом индексе множитель
innodb_ft_sort_pll_degree
:
(6 /*FTS_NUM_AUX_INDEX*/ * @@global.innodb_ft_sort_pll_degree)
innodb_spin_wait_delay
Формат командной строки | --innodb_spin_wait_delay=# | ||
Системная переменная | Имя |
innodb_spin_wait_delay
| |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения (32-bit platforms) | Тип | integer | |
Значение по умолчанию | 6 | ||
Минимум | 0 | ||
Максимум | 2**32-1 | ||
Допустимые значения (64-bit platforms) | Тип | integer | |
Значение по умолчанию | 6 | ||
Минимум | 0 | ||
Максимум | 2**64-1 |
Максимальная задержка между опросами для спин-блокировки. Низкоуровневое выполнение этого механизма изменяется в зависимости от комбинации аппаратных средств и операционной системы, таким образом, задержка не соответствует неподвижному временному интервалу. Значение по умолчанию 6. См. раздел 16.6.8 .
innodb_stats_auto_recalc
Формат командной строки | --innodb_stats_auto_recalc=# | ||
Системная переменная | Имя |
innodb_stats_auto_recalc | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | ON |
Автоматически повторно вычислить
постоянную статистику
после того, как данные в таблице изменены существенно. Пороговое значение в
настоящее время 10% строк в таблице. Эта установка относится к таблицам,
составленным при включенном
innodb_stats_persistent
или с STATS_PERSISTENT=1
в
CREATE TABLE
или
ALTER TABLE
.
Объемом данных, выбранным, чтобы произвести статистику, управляет
innodb_stats_persistent_sample_pages
.
См. раздел 16.6.10.1.
innodb_stats_include_delete_marked
Introduced | 8.0.1 | ||
Формат командной строки | --innodb_stats_include_delete_marked=# | ||
Системная переменная | Имя |
innodb_stats_include_delete_marked | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
По умолчанию InnoDB
читает данные,
вычисляя статистику. В случае незавершенной транзакции, которая удаляет
строки из таблицы, InnoDB
исключает записи, помеченные как
удаленные, вычисляя оценки строки и индексную статистику, которая может
привести к неоптимальным планам выполнения относительно других транзакций,
которые воздействуют на таблицу, одновременно используя операционный уровень
изоляции, кроме READ
UNCOMMITTED
. Во избежание этого
innodb_stats_include_delete_marked
может быть включен, чтобы
гарантировать, что InnoDB
включает записи, помеченные как
удаленные, вычисляя постоянную статистику.
Когда
innodb_stats_include_delete_marked
включен,
ANALYZE TABLE
рассматривает
записи, помеченные как удаленные, повторно вычисляя статистику.
innodb_stats_include_delete_marked
глобальная установка, которая
затрагивает все таблицы, и это применимо только к постоянной статистике.
См. раздел 16.6.10.1.
innodb_stats_method
Формат командной строки | --innodb_stats_method=name | ||
Системная переменная | Имя |
innodb_stats_method | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | enumeration | |
Значение по умолчанию | nulls_equal | ||
Допустимые значения | nulls_equal | ||
nulls_unequal | |||
nulls_ignored |
Как сервер обрабатывает NULL
, собирая
статистические данные
о распределении индекса значения для таблиц.
У этой переменной есть три возможных значения: nulls_equal
,
nulls_unequal
и nulls_ignored
. Для
nulls_equal
все индексные значения NULL
считаются равными и формируют единственную группу значения, у которой есть
размер, равный числу значений NULL
. Для
nulls_unequal
значения NULL
считают неравными, и каждое значение NULL
формирует отличную
группу значений размера 1. Для nulls_ignored
значения NULL
проигнорированы.
Метод, который используется для того, чтобы произвести табличную статистику, как оптимизатор выбирает индекс для выполнения запроса, описан в разделе 9.3.7.
innodb_stats_on_metadata
Формат командной строки | --innodb_stats_on_metadata | ||
Системная переменная | Имя |
innodb_stats_on_metadata | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Системная переменная | Имя |
innodb_stats_on_metadata | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Когда эта переменная включена, InnoDB
обновляет
статистику, когда обрабатывает
запросы метаданных, например, SHOW
TABLE STATUS
, или при обращении к таблицам
INFORMATION_SCHEMA.TABLES
или INFORMATION_SCHEMA.STATISTICS
. Эти обновления подобны тому, что происходят для
ANALYZE TABLE
.
Когда отключена, InnoDB
не обновляет статистику во время этих операций. Это может улучшить
скорость доступа для схем, у которых есть большое количество таблиц или
индексов. Это может также улучшить стабильность
планов выполнения
относительно запросов, которые вовлекают таблицы InnoDB
.
Чтобы изменить настройки, сделайте запрос SET GLOBAL
innodb_stats_on_metadata=
,
где mode
mode
ON
или OFF
(1
или 0
).
Изменение этих настроек требует привилегии SUPER
и немедленно затрагивает работу всех соединений.
Эта переменная отключена по умолчанию.
innodb_stats_persistent
Формат командной строки | --innodb_stats_persistent=setting | ||
Системная переменная | Имя |
innodb_stats_persistent | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | ON | ||
Допустимые значения | OFF | ||
ON | |||
0 | |||
1 |
Определяет сохраняет ли InnoDB
индексную статистику на диск.
Иначе статистика может часто повторно вычисляться, что может привести к
изменениям в планах
выполнения запроса. Эта установка сохранена каждой таблицей, когда
таблица составлена. Вы можете установить
innodb_stats_persistent
на глобальном уровне прежде, чем
составить таблицу, или использовать STATS_PERSISTENT
в
CREATE TABLE
и
ALTER TABLE
, чтобы
переопределить установку в масштабе всей системы и сконфигурировать
постоянную статистику для отдельных таблиц.
См. раздел 16.6.10.1.
innodb_stats_persistent_sample_pages
Формат командной строки | --innodb_stats_persistent_sample_pages=#
| ||
Системная переменная | Имя |
innodb_stats_persistent_sample_pages | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 20 |
Число индексных страниц, оценивая
количество элементов и другую
статистику
для индексированного столбца, как вычисленная
ANALYZE TABLE
.
Увеличение значения улучшает точность статистики индекса, которая может
улучшить план выполнения
запроса за счет увеличенного ввода/вывода во время выполнения
ANALYZE TABLE
. Подробности в
разделе 16.6.10.1.
Указание большого значения для
innodb_stats_persistent_sample_pages
может привести к длинному времени выполнения
ANALYZE TABLE
. Чтобы оценить число страниц базы данных, к
которым получат доступ, см.
раздел 16.6.10.3.
Эта опция применяется только, когда включена
innodb_stats_persistent
для таблицы, когда та опция выключена для
таблицы,
innodb_stats_transient_sample_pages
применяется вместо этого.
innodb_stats_transient_sample_pages
Формат командной строки | --innodb_stats_transient_sample_pages=# | ||
Системная переменная | Имя |
innodb_stats_transient_sample_pages | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 8 |
Число индексных страниц для оценки
количества элементов и другой
статистики
для индексированного столбца, такой как вычисленная
ANALYZE TABLE
.
Значение по умолчанию 8. Увеличение значения улучшает точность статистики
индекса, которая может улучшить
план выполнения запроса
, за счет увеличенного ввода/вывода или перевычисления статистики. Для
дополнительной информации см.
раздел 16.6.10.2.
Указание большого значения для
innodb_stats_transient_sample_pages
может увеличить время
работы ANALYZE TABLE
.
Чтобы оценить число страниц базы данных, к которым получают доступ, см.
раздел 16.6.10.3.
Эта опция применяется только, когда выключена
innodb_stats_persistent
для таблицы, когда эта опция включена для
таблицы,
innodb_stats_persistent_sample_pages
применяется вместо этого. См.
раздел 16.6.10.2.
innodb_status_output
Формат командной строки | --innodb_status_output | ||
Системная переменная | Имя |
innodb_status_output | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Включает или отключает периодический вывод
InnoDB
Monitor. Также используется в комбинации с
innodb_status_output_locks
, чтобы включить или отключить
периодический вывод InnoDB
Lock Monitor. См.
раздел 16.16.
innodb_status_output_locks
Формат командной строки | --innodb_status_output_locks | ||
Системная переменная | Имя |
innodb_status_output_locks | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Включает или отключает InnoDB
Lock Monitor. Когда включено,
InnoDB
Lock Monitor печатает дополнительную информацию о
блокировках в SHOW ENGINE INNODB STATUS
и в
периодическом выводе, напечатанном в журнал ошибок MySQL. Периодический
вывод для InnoDB
Lock Monitor напечатан как часть вывода
InnoDB
Monitor. Стандартный InnoDB
Monitor
нужно поэтому включить для InnoDB
Lock Monitor, чтобы напечатать
данные в журнал ошибок MySQL периодически. См.
раздел 16.16.
innodb_strict_mode
Формат командной строки | --innodb_strict_mode=# | ||
Системная переменная | Имя |
innodb_strict_mode | |
Область действия | Global, Session | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | ON |
Когда innodb_strict_mode
= ON
,
InnoDB
возвращает ошибки, а не предупреждения для определенных
условий. Значение по умолчанию ON
.
Строгий режим помогает
принять меры против проигнорированных опечаток и синтаксических ошибок в SQL,
или других непреднамеренных последствий различных комбинаций операционных
режимов и запросов SQL. Когда
innodb_strict_mode
= ON
, InnoDB
поднимает состояния ошибки в определенных случаях, вместо того, чтобы
выпустить предупреждение и продолжить обработку указанного запроса (возможно,
с непреднамеренным поведением). Это походит на
sql_mode
в MySQL,
который управляет тем, что принимает синтаксис SQL MySQL, и определяет,
игнорирует ли это тихо ошибки, или утверждает входной
синтаксис и значения данных.
innodb_strict_mode
затрагивает обработку синтаксических
ошибок для CREATE
TABLE
, ALTER TABLE
,
CREATE INDEX
и
OPTIMIZE TABLE
statements.
innodb_strict_mode
также включает проверку размера записи, чтобы
INSERT
или UPDATE
никогда не терпят неудачу из-за
слишком большой записи для выбранного размера страницы.
Oracle рекомендует включить innodb_strict_mode
, используя
ROW_FORMAT
и KEY_BLOCK_SIZE
в
CREATE TABLE
,
ALTER TABLE
и
CREATE INDEX
. Если
innodb_strict_mode
= OFF
, InnoDB
игнорирует противоречивые параметры и составляет таблицу или индекс только с
предупреждением в журнале сообщения. У получающейся таблицы может быть
не то поведение, чем Вы предназначали, например, отсутствие сжатия, когда Вы
попытались составить сжатую таблицу. Когда
innodb_strict_mode
= ON
,
такие проблемы производят непосредственную ошибку, и таблица или индекс не
создается, избегая сеанса поиска неисправностей позже.
Вы можете переключить innodb_strict_mode
в
ON
или OFF
в командной строке, когда Вы запускаете
mysqld
, или в
конфигурационном файле
my.cnf
или my.ini
.
Вы можете также включить или отключить
innodb_strict_mode
через SET [GLOBAL|SESSION]
innodb_strict_mode=
, где
mode
mode
ON
или OFF
. Изменение GLOBAL
требует привилегию SUPER
и влияет на всех клиентов, которые
впоследствии соединяются. Любой клиент может изменить настройку
SESSION
для innodb_strict_mode
, и установка
затрагивает только этого клиента.
innodb_strict_mode
не применимо к общим табличным пространствам. Управленческие
правила табличного пространства для общих табличных пространств строго
проведены в жизнь, независимо от
innodb_strict_mode
. См. раздел 14.1.16.
innodb_sync_array_size
Формат командной строки | --innodb_sync_array_size=# | ||
Системная переменная | Имя |
innodb_sync_array_size | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 1 | ||
Минимум | 1 | ||
Максимум | 1024 |
Разделяет внутреннюю структуру данных, используемую, чтобы скоординировать потоки, для более высокого параллелизма в рабочих нагрузках с большими количествами потоков ожидания. Эта установка должна быть сконфигурирована, когда экземпляр MySQL стартует и не может быть изменена позже. Увеличение этого значения опции рекомендуется для рабочих нагрузок, которые часто производят большое количество потоков ожидания, как правило, больше 768.
innodb_sync_spin_loops
Формат командной строки | --innodb_sync_spin_loops=# | ||
Системная переменная | Имя |
innodb_sync_spin_loops | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 30 | ||
Минимум | 0 | ||
Максимум | 4294967295 |
Сколько поток ждет InnoDB
mutex, который будет
освобожден перед тем, как поток приостановлен.Значение по умолчанию 30.
innodb_sync_debug
Формат командной строки | --innodb_sync_debug=# | ||
Системная переменная | Имя |
innodb_sync_debug | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Включает синхронизирующую проверку отладки механизма хранения
InnoDB
. Эта опция доступна только, если поддержка отладки
собрана с использованием
WITH_DEBUG
в CMake.
innodb_table_locks
Формат командной строки | --innodb_table_locks | ||
Системная переменная | Имя |
innodb_table_locks | |
Область действия | Global, Session | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | TRUE |
Если autocommit=0
,
InnoDB
учитывает LOCK
TABLES
, MySQL не возвращается из LOCK TABLES ... WRITE
, пока все другие потоки не выпустили все свои блокировки таблицы.
Значение по умолчанию
innodb_table_locks
1, что значит, что
LOCK TABLES
предписывает
InnoDB заблокировать таблицу внутренне, если
autocommit=0
.
В MySQL 8.0
innodb_table_locks = 0
не имеет никакого эффекта для таблиц, заблокированных явно с
LOCK TABLES ... WRITE
.
Это действительно имеет эффект для таблиц, заблокированных для чтения
или записи через LOCK TABLES ... WRITE
неявно (например, через триггеры) или через
LOCK TABLES ... READ
.
innodb_temp_data_file_path
Формат командной строки | --innodb_temp_data_file_path=file | ||
Системная переменная | Имя |
innodb_temp_data_file_path | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | string | |
Значение по умолчанию | ibtmp1:12M:autoextend |
Определяет путь, имя файла и размер файла для временных файлов с данными
табличного пространства. Полный путь к каталогу для файла сформирован,
связывая
innodb_data_home_dir
и путь из
innodb_temp_data_file_path
.
Размер файла определен в КБ, MB, или ГБ (1024 МБ), прилагая
K
, M
или G
к значению размера. Сумма размеров файлов должна быть немного больше 12 МБ.
Если Вы не определяете innodb_temp_data_file_path
,
поведение по умолчанию должно создать единственный автомасштабируемый
временный файл с данными табличного пространства, немного больше 12 МБ,
названный ibtmp1
. Предел размера отдельных файлов определен
Вашей операционной системой. Вы можете установить размер файла больше 4 ГБ на
операционных системах, которые поддерживают большие файлы. Использование
сырого дискового раздела для временных файлов с данными табличного
пространства не поддержано.
Название временного файла с данными табличного пространства не может быть тем же самым как название файла с данными. Любая ошибка создания временного файла с данными табличного пространства обработана как фатальная, и запуск сервера отменяется. У временного табличного табличного пространства есть динамически произведенное ID, пространства, которое может измениться при каждом перезапуске сервера.
Все временные таблицы InnoDB
составлены в совместно используемом временном табличном пространстве.
InnoDB
не поддерживает сжатые временные таблицы.
Метаданные об активных временных таблицах найдены в
INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO
.
innodb_tmpdir
Формат командной строки | --innodb_tmpdir=path | ||
Системная переменная | Имя | innodb_tmpdir
| |
Область действия | Global, Session | ||
Динамическая | Да | ||
Допустимые значения | Тип | directory name | |
Значение по умолчанию | NULL |
Используется, чтобы определить дополнительный каталог для временных
файлов, создаваемых во время онлайн ALTER
TABLE
, которые пересоздают таблицу.
Online ALTER TABLE
, которые
пересоздают таблицу, также создают
промежуточный табличный файл в том же самом каталоге,
как оригинальная таблица. innodb_tmpdir
не применима к промежуточным табличным файлам.
Допустимое значение любой путь к каталогу кроме пути к каталогу данных
MySQL. Если значение NULL (по умолчанию), временные файлы будут в создаваемом
MySQL временном каталоге ($TMPDIR
в Unix, %TEMP%
в
Windows или каталоге, определенном в
--tmpdir
). Если
innodb_tmpdir
каталог определен, существование каталога и
разрешения проверено, только когда innodb_tmpdir
сконфигурирован, используя SET
. Если символьная ссылка обеспечена в строке каталога, символьная ссылка
раскрыта и сохранена как абсолютный путь. Путь не должен превысить 512 байт в
длину. Онлайн ALTER TABLE
сообщает об ошибке, если innodb_tmpdir
установлен в недопустимый
каталог. innodb_tmpdir
переопределяет MySQL
tmpdir
, но только для
онлайн ALTER TABLE
.
Привилегия FILE
требуется для
настройки innodb_tmpdir
.
innodb_tmpdir
была введена, чтобы помочь избежать
переполнения временного каталога, расположенного на файловой системе
tmpfs
. Такие переполнения могли произойти в результате больших
временных файлов, создаваемых во время онлайн
ALTER TABLE
.
В окружающей среде репликации рассмотрите мультиплицирование
innodb_tmpdir
только, если у всех серверов есть та же самая
окружающая среда операционной системы. Иначе мультиплицирование
innodb_tmpdir
может привести к отказу репликации при работе
online ALTER TABLE
. Если
операционные среды сервера отличаются, рекомендуется, чтобы Вы
сконфигурировали innodb_tmpdir
на каждом сервере индивидуально.
innodb_thread_concurrency
Формат командной строки | --innodb_thread_concurrency=# | ||
Системная переменная | Имя |
innodb_thread_concurrency | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 0 | ||
Минимум | 0 | ||
Максимум | 1000 | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 8 | ||
Минимум | 0 | ||
Максимум | 1000 |
InnoDB
пытается сохранить число потоков операционной системы
внутри InnoDB
меньше или равным пределу, заданному этой
переменной (InnoDB
использует потоки ОС, чтобы обработать
пользовательские транзакции). Как только число потоков достигает этого
предела, дополнительные потоки помещены в состояние ожидания в очередь
First In, First Out (FIFO) для выполнения.
Потоки, ждущие блокировок, не посчитаны в числе
параллельного выполнения потоков.
Диапазон этой переменной от 0 до 1000. Значение 0 (значение по умолчанию)
интерпретируется как бесконечный параллелизм (никакой проверки параллелизма).
Отключение проверки параллелизма потока разрешает InnoDB
создать так много потоков, как надо. Значение 0 также отключает
queries inside InnoDB
и queries in queue counters
в
разделе ROW OPERATIONS
вывода
SHOW ENGINE INNODB STATUS
.
Рассмотрите установку этой переменной, если Ваш случай MySQL совместно
использует ресурсы центрального процессора с другими приложениями, или если
Ваша рабочая нагрузка или число параллельных пользователей растут.
Правильная установка зависит от рабочей нагрузки, вычислительной окружающей
среды и версии MySQL. Вы должны будете проверить диапазон значений, чтобы
определить установку, которая обеспечивает лучшую работу.
innodb_thread_concurrency
динамическая переменная, которая
позволяет Вам экспериментировать с различными настройками на живой
испытательной системе. Если особая установка выступает плохо, Вы можете
быстро установить innodb_thread_concurrency
назад в 0.
Используйте следующие советы:
Если число параллельных пользовательских потоков для рабочей
нагрузки меньше 64, innodb_thread_concurrency=0
.
innodb_thread_concurrency=128
и снижайте до
96, 80, 64 и т.д., пока Вы не найдете число потоков, которое обеспечивает
лучшую работу. Например, предположим, что у Вашей системы, как правило, есть
40-50 пользователей, но периодически число увеличивается до 60, 70 или даже
200. Вы находите, что работа устойчива при 80 параллельных пользователях,
но начинает показывать регресс выше этого числа. В этом случае Вы установили
бы innodb_thread_concurrency=80
.innodb_thread_concurrency
к этому числу (или возможно ниже, в
зависимости от исполнительных результатов). Если Ваша цель состоит в том,
чтобы изолировать MySQL от других приложений, Вы можете рассмотреть привязку
mysqld
исключительно к vCPU. Знайте, однако, что исключительная
привязка может привести к неоптимальному использованию аппаратных средств,
если mysqld
не занят непрерывно. В этом случае Вы могли бы
связать mysqld
с vCPU, но также и позволить другим приложениям
использовать некоторых или все vCPU.
С точки зрения операционной системы использовать управленческое решение
для ресурса (при наличии), чтобы определить то, как время центрального
процессора совместно использовано среди приложений, может быть
предпочтительным для привязки mysqld
.
Например, Вы могли назначить 90% времени vCPU
данному приложению, в то время как другой критический процесс
не работает, и вернуть значение к 40%,
когда другие критические процессы работают.
innodb_thread_concurrency
, которые слишком высоки, могут
вызвать исполнительный регресс.
innodb_thread_concurrency
может быть меньше, чем число vCPU.
innodb_thread_concurrency
.
См. раздел 16.6.5.
innodb_trx_purge_view_update_only_debug
Формат командной строки | --innodb_trx_purge_view_update_only_debug=#
| ||
Системная переменная | Имя |
innodb_trx_purge_view_update_only_debug | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Приостанавливает чистку помеченных как удаленные записей, позволяя
обновить обзор чистки. Эта опция искусственно создает ситуацию, в которой
обновлено представление чистки, но чистки еще не были выполнены. Эта опция
доступна только, если поддержка отладки собрана с использованием
WITH_DEBUG
в
CMake.
innodb_trx_rseg_n_slots_debug
Формат командной строки | --innodb_trx_rseg_n_slots_debug=# | ||
Системная переменная | Имя |
innodb_trx_rseg_n_slots_debug | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 0 | ||
Максимум | 1024 |
Устанавливает флаг отладки, который ограничивает
TRX_RSEG_N_SLOTS
к данному значению для функции
trx_rsegf_undo_find_free
, которая ищет свободный слот для
сегмента журнала отмены. Эта опция доступна только, если поддержка отладки
собрана с использованием
WITH_DEBUG
в CMake.
innodb_thread_sleep_delay
Формат командной строки | --innodb_thread_sleep_delay=# | ||
Системная переменная | Имя |
innodb_thread_sleep_delay | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 10000 | ||
Минимум | 0 | ||
Максимум | 1000000 |
Сколько времени потоки спят прежде, чем присоединиться к очереди
InnoDB
, в микросекундах. Значение по умолчанию 10000. Значение 0
отключает сон. Вы можете установить параметр конфигурации
innodb_adaptive_max_sleep_delay
к самому высокому значению, которое
позволено для innodb_thread_sleep_delay
, и InnoDB автоматически
корректирует innodb_thread_sleep_delay
в зависимости от
намечающей текущий поток деятельности. Эта динамическая корректировка
помогает механизму планирования потока работать гладко в течение времен,
когда система слегка загружена и когда это управляет
близкой к полной мощности.
См. раздел 16.6.5.
innodb_undo_directory
Формат командной строки | --innodb_undo_directory=dir_name | ||
Системная переменная | Имя |
innodb_undo_directory | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | имя каталога |
Путь, где InnoDB
создает отдельные табличные пространства для
журналов отмены. Как правило, используется, чтобы поместить журналы отмены
на отдельное устройство хранения данных. Используется в соединении с
innodb_undo_logs
и
innodb_undo_tablespaces
, которые определяют дисковое расположение
журналов отмены вне
системного табличного пространства.
Нет значения по умолчанию (NULL). Если путь не определен, табличные
пространства отмены создаются в каталоге данных MySQL, как определено
datadir
.
См. раздел 16.7.7.
innodb_undo_log_truncate
Формат командной строки | --innodb_undo_log_truncate=# | ||
Системная переменная | Имя |
innodb_undo_log_truncate | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | OFF |
Когда Вы включаете innodb_undo_log_truncate
,
табличные пространства отмены, которые превышают пороговое значение,
определенное
innodb_max_undo_log_size
, отмечены для усечения. Только журналы
отмены, которые находятся в табличных пространствах отмены, могут быть
усеченны. Усечение журналов отмены, которые находятся в системном табличном
пространстве, не поддержано. Для усечения должно быть по крайней мере два
табличных пространства отмены и два журнала отмены, сконфигурированных, чтобы
использовать табличные пространства отмены. Это означает, что
innodb_undo_tablespaces
должен быть установлен в значение, равное
или больше 2, и
innodb_undo_logs
должен быть равен или больше 35.
Опция
innodb_purge_rseg_truncate_frequency
может использоваться, чтобы ускорить усечение журналов отмены.
См. раздел 16.7.8.
innodb_undo_logs
Формат командной строки | --innodb_undo_logs=# | ||
Системная переменная | Имя |
innodb_undo_logs | |
Область действия | Глобальная | ||
Динамическая | Да | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 128 | ||
Минимум | 0 | ||
Максимум | 128 |
Определяет число журналов отмены
(сегментов отмены),
используемых InnoDB
.
innodb_undo_logs
заменяет
innodb_rollback_segments
.
Один журнал отмены всегда назначается на системное табличное
пространство, и 32 журнала отмены сохранены для использования временными
таблицами и размещены во временном табличном пространстве (ibtmp1
). Чтобы выделить дополнительные журналы отмены для изменяющих данные
транзакций, которые производят отчеты отмены, innodb_undo_logs
должен быть установлен в значение больше 33. Если Вы конфигурируете отдельные
табличные пространства отмены, журнал отмены в системном табличном
пространстве неактивен. Каждый журнал отмены может
разместить максимум 1024 транзакции.
Когда innodb_undo_logs
32 или менее, InnoDB
назначает один журнал отмены на системное табличное пространство и 32
временному табличному пространству (ibtmp1
).
Когда innodb_undo_logs
больше 32, InnoDB
назначает один журнал отмены на системное табличное пространство, 32
временному табличному пространству (ibtmp1
) и все
дополнительные журналы отмены на табличные пространства отмены, если они
существуют. Если табличные пространства отмены не существует, дополнительные
журналы отмены назначены на системное табличное пространство.
Хотя Вы можете увеличить или сократить число журналов отмены, используемых
InnoDB
, число журналов отмены, физически существующих в системе,
никогда не уменьшается. Таким образом, Вы могли бы начать с низкого значения
этого параметра и постепенно увеличивать его, чтобы избежать выделять журналы
отмены, которые не требуются. Если
innodb_undo_logs
не установлен, это принимает значение по
умолчанию 128. Для общего количества доступных журналов отмены, а не числа
активных, см.
Innodb_available_undo_logs
.
innodb_undo_tablespaces
Формат командной строки | --innodb_undo_tablespaces=# | ||
Системная переменная | Имя |
innodb_undo_tablespaces | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 0 | ||
Минимум | 0 | ||
Максимум | 95 |
Число файлов табличного
пространства, между которыми разделены
журналы отмены.
По умолчанию все журналы отмены часть
системного табличного
пространства, и системное табличное пространство всегда содержит одно
табличное пространство отмены в дополнение к сконфигурированным
innodb_undo_tablespaces
.
Поскольку журналы отмены могут стать большими во время продолжительных
транзакций, многократные табличные пространства уменьшают максимальный размер
любого табличного пространства. Файлы табличного пространства отмены
создаются в местоположении, определенном
innodb_undo_directory
с именами в форме
undo
, где N
N
последовательная серия целых чисел (включая начальные нули). Размер по
умолчанию файла табличного пространства отмены 10M.
innodb_undo_tablespaces
может только быть сконфигурирован до
инициализации MySQL и не может быть изменен позже. Если никакое значение не
определено, сервер инициализирован, используя настройку по умолчанию
(0
). Попытка перезапустить InnoDB
с большим числом табличных пространств отмены, чем указано, когда MySQL был
инициализирован, приводит к отказу запуска и ошибке заявляя, что
InnoDB
не нашел ожидаемое число табличных пространств отмены.
32 из 128 журналов отмены сохранены для временных таблиц, как описано в
разделе 16.4.11.1.
Один журнал отмены всегда выделяется системному табличному пространству,
которое оставляет 95 журналов отмены доступными. Это означает, что
максимальный предел
innodb_undo_tablespaces
95.
См. раздел 16.7.7.
innodb_use_native_aio
Формат командной строки | --innodb_use_native_aio=# | ||
Системная переменная | Имя |
innodb_use_native_aio | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | boolean | |
Значение по умолчанию | ON |
Определяет, использовать ли асинхронную подсистему ввода/вывода Linux. Эта переменная относится только к системам Linux и не может быть изменена в то время, как сервер работает. Обычно Вы не должны касаться этой опции, потому что она включена по умолчанию.
Асинхронный I/O,
который InnoDB
имеет на системах Windows, доступен на системах
Linux. Другие подобные Unix системы продолжают использовать синхронный
ввод/вывод. Эта особенность улучшает масштабируемость в большой степени
систем, которые как правило показывают много чтений и записей в выводе
SHOW ENGINE INNODB STATUS\G
.
Выполнение с большим количеством потоков ввода/вывода, а особенно запуск нескольких экземпляров на той же самой машине сервера, могут исчерпать пределы на системах Linux. В этом случае Вы можете получить следующую ошибку:
EAGAIN: The specified maxevents exceeds the user's limit of available events.
Вы можете, как правило, обращаться к этой ошибке при
записи более высокого предела в /proc/sys/fs/aio-max-nr
.
Однако, если проблема с асинхронной подсистемой ввода/вывода в OS не дает
InnoDB
запуститься, Вы можете запустить сервер с
innodb_use_native_aio=0
в файле опции. Эта опция может также быть
выключена автоматически во время запуска, если InnoDB
обнаруживает потенциальную проблему, такую как комбинация
tmpdir
, файловой системы tmpfs
и ядра Linux,
которое не поддерживает AIO на tmpfs
.
innodb_version
Номер версии InnoDB
. В 5.7 отдельная нумерация для
InnoDB
не применяется и это значение то же самое, как
version
.
innodb_write_io_threads
Формат командной строки | --innodb_write_io_threads=# | ||
Системная переменная | Имя |
innodb_write_io_threads | |
Область действия | Глобальная | ||
Динамическая | Нет | ||
Допустимые значения | Тип | integer | |
Значение по умолчанию | 4 | ||
Минимум | 1 | ||
Максимум | 64 |
Число потоков ввода/вывода для записи в InnoDB
.
Значение по умолчанию 4. Его аналог для потоков чтения
innodb_read_io_threads
. См.
раздел 16.6.6
.
В Linux, выполняя много серверов MySQL (как правило, больше 12) с
настройками по умолчанию для
innodb_read_io_threads
, innodb_write_io_threads
и параметр Linux aio-max-nr
могут превысить системные пределы.
Идеально увеличить aio-max-nr
,
как обходное решение, Вы могли бы уменьшить настройки для одного или обоих
параметров конфигурации MySQL.
Вы должны также учесть значение
sync_binlog
,
которое управляет синхронизацией двоичного журнала с диском.
Этот раздел предоставляет информацию и примеры использования для таблиц
InnoDB
INFORMATION_SCHEMA
.
Таблицы InnoDB
INFORMATION_SCHEMA
обеспечивают метаданные, информацию о статусе и статистику о различных
аспектах механизма хранения InnoDB
. Вы можете смотреть список
таблиц InnoDB
INFORMATION_SCHEMA
с помощью
SHOW TABLES
в базе
данных INFORMATION_SCHEMA
:
mysql> SHOW TABLES FROM INFORMATION_SCHEMA LIKE 'INNODB%';
Для табличных определений см.
раздел 22.30. Для общей информации относительно базы данных
MySQL
INFORMATION_SCHEMA
см.
главу 22.
Есть две пары таблиц InnoDB
INFORMATION_SCHEMA
о сжатии, которые могут обеспечить понимание, как хорошо сжатие работает:
INNODB_CMP
и INNODB_CMP_RESET
содержат информацию о числе операций сжатия и количестве времени,
проведенного, выполняя сжатие.
INNODB_CMPMEM
и
INNODB_CMP_RESET
содержат информацию о способе, которым память выделена для сжатия.
INNODB_CMP
и
INNODB_CMP_RESET
содержат информацию о статусе операций, связанных со сжатыми таблицами,
которые описаны в разделе 16.9.
PAGE_SIZE
сообщает о сжатом
размере страницы.
У этих двух таблиц есть идентичное содержание, но чтение изж
INNODB_CMP_RESET
сбрасывает статистику по операциям сжатия. Например, если Вы архивируете
вывод INNODB_CMP_RESET
каждые 60 минут, Вы видите статистику в течение каждого почасового периода.
Если Вы контролируете вывод
INNODB_CMP
(никогда не читая
INNODB_CMP_RESET
), Вы видите накопленную статистику
с момента старта InnoDB.
См. раздел 22.30.5.
INNODB_CMPMEM
и
INNODB_CMPMEM_RESET
содержат информацию о сжатых страницах, которые находятся в буферном пуле.
Пожалуйста, консультируйтесь с
разделом 16.9 для дополнительной информации о сжатых таблицах и
использовании буферного пула.
INNODB_CMP
и
INNODB_CMP_RESET
должны обеспечить более полезную статистику по сжатию.
InnoDB
использует систему
распределителя, чтобы
управлять памятью, выделенной
страницам различных размеров,
от 1KB до 16KB. Каждая строка этих двух таблиц, описанных здесь,
соответствует единственному размеру страницы.
INNODB_CMPMEM
и
INNODB_CMPMEM_RESET
имеют идентичное содержание, но чтение
INNODB_CMPMEM_RESET
сбрасывает статистику по операциям перемещения. Например, если каждые 60
минут Вы заархивировали вывод
INNODB_CMPMEM_RESET
, это показало бы почасовую статистику. Если Вы никогда не читаете
INNODB_CMPMEM_RESET
и читаете вывод INNODB_CMPMEM
, вместо этого, это показжет накопленную статистику с момента
запуска InnoDB
.
См. раздел 22.30.6.
Пример 16.10. Использование информации о сжатии
Следующее типовой вывод базы данных, которая содержит сжатые таблицы (см.
compressed tables (see раздел 16.9
, INNODB_CMP
,
INNODB_CMP_PER_INDEX
и INNODB_CMPMEM
).
Следующая таблица показывает содержание
INFORMATION_SCHEMA.INNODB_CMP
при легкой рабочей нагрузке
. Единственный сжатый размер страницы, который содержит буферный пул,
составляет 8K. Сжатие страниц потребляло меньше секунды времени,
статистические данные были сброшены, потому что столбцы
COMPRESS_TIME
и UNCOMPRESS_TIME
= 0.
Размер страницы | compress ops | compress ops ok | compress time | uncompress ops | uncompress time |
---|---|---|---|---|---|
1024 | 0 | 0 | 0 | 0 | 0 |
2048 | 0 | 0 | 0 | 0 | 0 |
4096 | 0 | 0 | 0 | 0 | 0 |
8192 | 1048 | 921 | 0 | 61 | 0 |
16384 | 0 | 0 | 0 | 0 | 0 |
Согласно INNODB_CMPMEM
, есть 6169 сжатых страницы по 8 КБ в
буферном пуле.
Единственный другой выделенный размер блока составляет 64 байта. Самый
маленький PAGE_SIZE
в
INNODB_CMPMEM
используется для описателей блока тех сжатых страниц, для которых никакая
несжатая страница не существует в буферном пуле. Мы видим, что есть 5910
таких страниц. Косвенно мы видим, что 259 (6169-5910) сжатых страниц также
существуют в буферном пуле в несжатой форме.
Следующая таблица показывает содержание
INFORMATION_SCHEMA.INNODB_CMPMEM
при легкой
рабочей нагрузке.
Некоторая память непригодна из-за фрагментации распределителя памяти
для сжатых страниц: SUM(PAGE_SIZE*PAGES_FREE)=6784
.
Это потому что маленькие запросы распределения памяти выполнены, разделяя
большие блоки, начиная с 16K блоков, которые выделены из основного буферного
пула, используя систему распределения. Фрагментация низкая потому, что
некоторые выделенные блоки были перемещены (скопированы), чтобы сформировать
большие смежные свободные блоки. Это копирование
SUM(PAGE_SIZE*RELOCATION_OPS)
байт
потребляло меньше секунды (SUM(RELOCATION_TIME)=0)
.
Размер страницы | Страниц занято | Страниц свободно | relocation ops | relocation time |
---|---|---|---|---|
64 | 5910 | 0 | 2436 | 0 |
128 | 0 | 1 | 0 | 0 |
256 | 0 | 0 | 0 | 0 |
512 | 0 | 1 | 0 | 0 |
1024 | 0 | 0 | 0 | 0 |
2048 | 0 | 1 | 0 | 0 |
4096 | 0 | 1 | 0 | 0 |
8192 | 6169 | 0 | 5 | 0 |
16384 | 0 | 0 | 0 | 0 |
Этот раздел описывает информацию о блокировке, предоставленную таблицами
Performance Schema data_locks
и
data_lock_waits
, которые заменяют INFORMATION_SCHEMA
INNODB_LOCKS
и
INNODB_LOCK_WAITS
в MySQL 8.0. Для подобного обсуждения, написанного с точки зрения более
старых таблиц INFORMATION_SCHEMA
, см.
InnoDB INFORMATION_SCHEMA Transaction and Locking Information
в
MySQL 5.7 Reference Manual.
Одна таблица INFORMATION_SCHEMA
и две таблицы Performance
Schema позволяют Вам контролировать транзакции и диагностируют
потенциальные проблемы блокировки:
INNODB_TRX
:
Эта таблица содержит информацию о каждой транзакции, в настоящее время
выполняющейся внутри InnoDB
, включая операционное состояние
(например, работает ли это или ждет блокировки), когда транзакция запускалась
и запрос SQL, который транзакция выполняет.
data_locks
:
Эта таблица содержит содержит строку для каждой блокировки и каждого запроса
блокировки, который стоит, ожидая блокировки, которая будет выпущена:
Есть одна строка для каждой проводимой блокировки, безотносительно
статуса транзакции, которая держит блокировку
(INNODB_TRX.TRX_STATE
может быть
RUNNING
, LOCK WAIT
,
ROLLING BACK
или COMMITTING
).
INNODB_TRX.TRX_STATE
= LOCK
WAIT
) заблокирована точно одним запросом блокировки. Это запрос
блокировки для строки или табличной блокировки, проводимой другой транзакцией
в несовместимом режиме. У запроса блокировки всегда есть режим, который
является несовместимым с режимом проводимой блокировки, которая блокирует
запрос (чтение против записи, совместно
использованный против исключительного).
Заблокированная транзакция не может продолжиться, пока другая транзакция
не завершится, таким образом выпуская требуемую блокировку. Для каждой
заблокированной транзакции
data_locks
содержит одну строку, которая описывает каждую
блокировку, которую транзакция просила, и которую это ждет.
data_lock_waits
: Эта таблица показывает, какие транзакции ждут данной блокировки,
или которой блокировки данная транзакция ждет. Эта таблица содержит одну или
более строк для каждой заблокированной транзакции, указывая на блокировку,
которую это просило и любые блокировки, которые блокируют этот запрос.
REQUESTING_ENGINE_LOCK_ID
обращается к блокировке, которую
требует транзакция, а BLOCKING_ENGINE_LOCK_ID
обращается к
блокировке (проводимой другой транзакцией), которая препятствует тому, чтобы
первая транзакция продолжилась. Для любой данной заблокированной транзакции
все строки в
data_lock_waits
имеют то же самое значение для
REQUESTING_ENGINE_LOCK_ID
и различные значения для
BLOCKING_ENGINE_LOCK_ID
.
См. разделы 22.30.28, 23.9.12.1 и 23.9.12.2.
Этот раздел описывает информацию о блокировке как выдано таблицами
data_locks
и
data_lock_waits
,
которые заменяют INFORMATION_SCHEMA
INNODB_LOCKS
и
INNODB_LOCK_WAITS
в MySQL 8.0.
Иногда полезно идентифицировать, какая транзакция блокирует другую. Таблицы, которые содержат информацию о транзакции и блокировке данных, позволяют Вам определить, какая транзакция ждет другую и какой ресурс требует. Для описаний этих таблиц см. раздел 16.14.2 .
Предположите, что три сеанса работают одновременно. Каждый сеанс соответствует потоку MySQL и выполняет одну транзакцию за другой. Рассмотрите состояние системы, когда эти сеансы сделали следующие запросы, но ни один еще не передал свою транзакцию:
Session A:
BEGIN; SELECT a FROM t FOR UPDATE; SELECT SLEEP(100);
SELECT b FROM t FOR UPDATE;
SELECT c FROM t FOR UPDATE;
Используйте следующий запрос, чтобы видеть, какие транзакции ждут, а какие транзакции блокируют их:
SELECT r.trx_id waiting_trx_id, r.trx_mysql_thread_id waiting_thread, r.trx_query waiting_query, b.trx_id blocking_trx_id, b.trx_mysql_thread_id blocking_thread, b.trx_query blocking_query FROM performance_schema.data_lock_waits w INNER JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_engine_transaction_id INNER JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_engine_transaction_id;
Или, более просто, используйте представление
innodb_lock_waits
в схеме sys
:
SELECT waiting_trx_id, waiting_pid, waiting_query, blocking_trx_id, blocking_pid, blocking_query FROM sys.innodb_lock_waits;
waiting trx id | waiting thread | waiting query | blocking trx id | blocking thread | blocking query |
---|---|---|---|---|---|
A4 | 6 |
SELECT b FROM t FOR UPDATE | A3 |
5 | SELECT SLEEP(100) |
A5 | 7 |
SELECT c FROM t FOR UPDATE | A3 |
5 | SELECT SLEEP(100) |
A5 | 7 |
SELECT c FROM t FOR UPDATE | A4 |
6 | SELECT b FROM t FOR UPDATE
|
В предыдущей таблице Вы можете идентифицировать сеансовые столбцы waiting query или blocking query:
Session B (trx id A4
, поток 6
) и
Session C (trx id A5
, поток 7
) оба ждут
Session A (trx id A3
, поток 5
).
Вы можете видеть основные данные в
INFORMATION_SCHEMA
INNODB_TRX
и
Performance Schema data_locks
и
data_lock_waits
.
Следующая таблица показывает некоторое типовое содержание таблицы
INNODB_TRX
.
trx id | trx state | trx started | trx requested lock id | trx wait started | trx weight | trx mysql thread id | trx query |
---|---|---|---|---|---|---|---|
A3 | RUNNING |
2008-01-15 16:44:54 | NULL |
NULL | 2 | 5 |
SELECT SLEEP(100) |
A4 | LOCK WAIT |
2008-01-15 16:45:09 | A4:1:3:2 |
2008-01-15 16:45:09 | 2 |
6 | SELECT b FROM t FOR UPDATE |
A5 | LOCK WAIT |
2008-01-15 16:45:14 | A5:1:3:2 |
2008-01-15 16:45:14 | 2 |
7 | SELECT c FROM t FOR UPDATE
|
Следующая таблица показывает некоторое типовое содержание таблицы
data_locks
.
lock id | lock trx id | lock mode | lock type | lock schema | lock table | lock index | lock data |
---|---|---|---|---|---|---|---|
A3:1:3:2 | A3 |
X | RECORD | test |
t | PRIMARY | 0x0200
|
A4:1:3:2 | A4 |
X | RECORD | test |
t | PRIMARY | 0x0200
|
A5:1:3:2 | A5 |
X | RECORD | test |
t | PRIMARY | 0x0200
|
Следующая таблица показывает некоторое типовое содержание таблицы
data_lock_waits
.
requesting trx id | requested lock id | blocking trx id | blocking lock id |
---|---|---|---|
A4 | A4:1:3:2 |
A3 | A3:1:3:2 |
A5 | A5:1:3:2 |
A3 | A3:1:3:2 |
A5 | A5:1:3:2 |
A4 | A4:1:3:2 |
Иногда полезно коррелировать внутреннюю информацию блокировок
InnoDB
с информацией на уровне сеанса MySQL.
Например, Вам могло бы понадобиться знать для данного ID транзакции
соответствующий MySQL session ID и название сеанса, который может держать
блокировку, и таким образом блокировать другие транзакции.
Следующий вывод INFORMATION_SCHEMA
INNODB_TRX
и
Performance Schema data_locks
и
data_lock_waits
взят от загруженной системы. Как может быть
замечено, есть несколько транзакций.
Следующие таблицы data_locks
и
data_lock_waits
показывают, что:
Транзакция 77F
(выполняет
INSERT
) ждет транзакции
77E
, 77D
и 77B
.
77E
(выполняет
INSERT
) ждет транзакции
77D
и 77B
.77D
(выполняет
INSERT
) ждет транзакцию
77B
.77B
(выполняет
INSERT
) ждет транзакцию
77A
.77A
работает, в настоящее время выполняя
SELECT
.E56
(выполняет
INSERT
) ждет транзакцию
E55
.E55
(выполняет
INSERT
) ждет транзакцию
19C
.19C
работает, в настоящее время выполняя
INSERT
.Могут быть несогласованности между запросами, показанными в таблицах
INFORMATION_SCHEMA
PROCESSLIST
и
INNODB_TRX
. См.
раздел 16.14.2.3
.
Следующая таблица показывает содержание таблицы
PROCESSLIST
для системы, выполняющей тяжелую
рабочую нагрузку.
ID | USER | HOST | DB | COMMAND | TIME | STATE | INFO |
---|---|---|---|---|---|---|---|
384 | root |
localhost | test |
Query | 10 |
update | INSERT INTO t2 VALUES ...
|
257 | root |
localhost | test |
Query | 3 | update
| INSERT INTO t2 VALUES Б─╕ |
130 | root |
localhost | test | Query
| 0 | update |
INSERT INTO t2 VALUES Б─╕ |
61 | root |
localhost | test | Query
| 1 | update |
INSERT INTO t2 VALUES Б─╕ |
8 | root |
localhost | test | Query
| 1 | update |
INSERT INTO t2 VALUES Б─╕ |
4 | root |
localhost | test |
Query | 0 |
preparing | SELECT * FROM PROCESSLIST
|
2 | root |
localhost | test |
Sleep | 566 |
|
NULL |
Следующая таблица показывает содержание
INNODB_TRX
для системы, выполняющей тяжелую
рабочую нагрузку.
trx id | trx state | trx started | trx requested lock id | trx wait started | trx weight | trx mysql thread id | trx query |
---|---|---|---|---|---|---|---|
77F | LOCK WAIT |
2008-01-15 13:10:16 | 77F |
2008-01-15 13:10:16 | 1 |
876 | INSERT INTO t09 (D, B, C) VALUES ...
|
77E | LOCK WAIT |
2008-01-15 13:10:16 | 77E |
2008-01-15 13:10:16 | 1 |
875 | INSERT INTO t09 (D, B, C) VALUES ...
|
77D | LOCK WAIT |
2008-01-15 13:10:16 | 77D |
2008-01-15 13:10:16 | 1 |
874 | INSERT INTO t09 (D, B, C) VALUES ...
|
77B | LOCK WAIT |
2008-01-15 13:10:16 | 77B:733:12:1 |
2008-01-15 13:10:16 | 4 |
873 | INSERT INTO t09 (D, B, C) VALUES ...
|
77A | RUNб╜NING |
2008-01-15 13:10:16 | NULL |
NULL | 4 | 872 |
SELECT b, c FROM t09 WHERE Б─╕ |
E56 | LOCK WAIT |
2008-01-15 13:10:06 | E56:743:6:2 |
2008-01-15 13:10:06 | 5 |
384 | INSERT INTO t2 VALUES ... |
E55 | LOCK WAIT |
2008-01-15 13:10:06 | E55:743:38:2 |
2008-01-15 13:10:13 | 965 |
257 | INSERT INTO t2 VALUES Б─╕ |
19C | RUNб╜NING |
2008-01-15 13:09:10 | NULL |
NULL | 2900 | 130 |
INSERT INTO t2 VALUES Б─╕ |
E15 | RUNNING |
2008-01-15 13:08:59 | NULL |
NULL | 5395 | 61 |
INSERT INTO t2 VALUES Б─╕ |
51D | RUNб╜NING |
2008-01-15 13:08:47 | NULL |
NULL | 9807 | 8 |
INSERT INTO t2 VALUES Б─╕ |
Следующая таблица показывает содержание
data_lock_waits
для системы, выполняющей тяжелую
рабочую нагрузку.
requesting trx id | requested lock id | blocking trx id | blocking lock id |
---|---|---|---|
77F | 77F:806 |
77E | 77E:806 |
77F | 77F:806 |
77D | 77D:806 |
77F | 77F:806 |
77B | 77B:806 |
77E | 77E:806 |
77D | 77D:806 |
77E | 77E:806 |
77B | 77B:806 |
77D | 77D:806 |
77B | 77B:806 |
77B | 77B:733:12:1 |
77A | 77A:733:12:1 |
E56 | E56:743:6:2 |
E55 | E55:743:6:2 |
E55 | E55:743:38:2 |
19C | 19C:743:38:2 |
Следующая таблица показывает содержание
data_locks
для системы, выполняющей тяжелую
рабочую нагрузку.
lock id | lock trx id | lock mode | lock type | lock schema | lock table | lock index | lock data |
---|---|---|---|---|---|---|---|
77F:806 | 77F |
AUTO_INC | TABLE | test |
t09 | NULL | NULL |
77E:806 | 77E | AUTO_INC
| TABLE | test |
t09 | NULL | NULL |
77D:806 | 77D | AUTO_INC
| TABLE | test |
t09 | NULL | NULL |
77B:806 | 77B | AUTO_INC
| TABLE | test |
t09 | NULL | NULL |
77B:733:12:1 | 77B | X
| RECORD | test |
t09 | PRIMARY | supremum pseudo-record
|
77A:733:12:1 | 77A | X
| RECORD | test |
t09 | PRIMARY | supremum pseudo-record
|
E56:743:6:2 | E56 | S
| RECORD | test |
t2 | PRIMARY | 0, 0 |
E55:743:6:2 | E55 | X
| RECORD | test |
t2 | PRIMARY | 0, 0 |
E55:743:38:2 | E55 | S
| RECORD | test |
t2 | PRIMARY | 1922, 1922 |
19C:743:38:2 | 19C | X
| RECORD | test |
t2 | PRIMARY | 1922, 1922 |
Этот раздел описывает информацию о блокировке как выставлено таблицами
Performance Schema data_locks
и
data_lock_waits
, которые заменяют
supersede the INFORMATION_SCHEMA
INNODB_LOCKS
и
INNODB_LOCK_WAITS
в MySQL 8.0.
Когда транзакция обновляет строку в таблице или блокирует ее с
SELECT FOR UPDATE
, InnoDB
составляет список или очередь блокировок этой строки. Точно так же
InnoDB
поддерживает список для блокировок на уровне таблицы.
Если вторая транзакция хочет обновить строку или заблокировать таблицу, уже
заблокированную предшествующей транзакцией в несовместимом режиме,
InnoDB
добавляет запрос блокировки строки в соответствующую
очередь. Для блокировки, которая будет приобретена транзакцией, все
несовместимые запросы блокировки ранее вступившие в очередь блокировки для
той строки или таблицы, должны быть удалены.
У транзакции может быть любое число запросов блокировки о различных
строках или таблицах. В любой момент времени, транзакция может просить
блокировку, которая проводится другой транзакцией, тогда это заблокировано
той другой транзакцией. Если транзакция не ждет блокировки, она находится в
в состоянии RUNNING
. Если транзакция ждет блокировки, это
находится в состоянии LOCK WAIT
. INFORMATION_SCHEMA
INNODB_TRX
показывает значения статуса транзакций.
Performance Schema
data_locks
содержит одну или более строк для каждой транзакции
LOCK WAIT
, указывая на любые запросы блокировки, которые
предотвращают ее продвижение. Эта таблица также содержит одну строку,
описывающую каждую блокировку в очереди блокировок, ожидающих для данной
строки или таблицы. Performance Schema
data_lock_waits
показывает, которые блокировки, уже проводимые транзакцией, блокируют
блокировки, которые требуют другие транзакции.
Этот раздел описывает информацию о блокировке как выставлено
Performance Schema data_locks
и
data_lock_waits
, которые заменяют INFORMATION_SCHEMA
INNODB_LOCKS
и
INNODB_LOCK_WAITS
в MySQL 8.0.
Данные, выставленные транзакцией и таблицами блокировки
(INFORMATION_SCHEMA
INNODB_TRX
, Performance Schema
data_locks
и
data_lock_waits
)
представляют быстро изменяющиеся данные. Это не походит на пользовательские
таблицы, где данные изменяются только, когда происходят обновления в
приложении. Основные данные это внутренние управляемые системой данные, они
могут измениться очень быстро:
Данные не могли бы быть последовательными между таблицами
INNODB_TRX
,
data_locks
и
data_lock_waits
.
data_locks
и
data_lock_waits
выставляют живые данные от механизма хранения InnoDB
,
чтобы обеспечить информацию о блокировках и транзакциях в таблице
INNODB_TRX
.
Данные, полученные от таблиц блокировки, существуют, когда выполняется
SELECT
, но могут измениться к тому
времени, когда результат запроса потребляется клиентом.
Объединение data_locks
с data_lock_waits
может показать строки в
data_lock_waits
,
это идентифицирует родительскую строку в
data_locks
,
которая больше не существует или еще не существует.
INFORMATION_SCHEMA
PROCESSLIST
или
Performance Schema threads
.
Например, Вы должны быть осторожными, сравнивая данные в
таблицах транзакций и блокировок с данными в
PROCESSLIST
.
Даже если Вы выпускаете один SELECT
(например, объединяя
INNODB_TRX
и
PROCESSLIST
),
контент тех таблиц вообще не последователен. Для возможно
INNODB_TRX
ссылаться
на строки, которые не присутствуют в
PROCESSLIST
или для транзакции в настоящее время выполняющегося запроса SQL, показанной в
or for the INNODB_TRX.TRX_QUERY
отличаться от связанных данных в
PROCESSLIST.INFO
.
Вы можете извлечь метаданные об объектах схемы, которыми управляет
InnoDB
, используя системные таблицы InnoDB
INFORMATION_SCHEMA
. Эта информация прибывает из
внутренних системных таблиц InnoDB
(словарь данных),
который не может быть запрошен непосредственно, как обычные таблицы.
Традиционно Вы получили бы этот тип информации, используя методы из
раздела 16.16, настраивая
мониторинг и парсинг вывода
SHOW ENGINE INNODB STATUS
. Таблицы INFORMATION_SCHEMA
позволяют Вам запрашивать эти данные, используя SQL.
За исключением
INNODB_SYS_TABLESTATS
, для которого нет никакой соответствующей
внутренней системной таблицы, системные таблицы INFORMATION_SCHEMA
заполнены чтением данных непосредственно от внутренних
системных таблиц, а не от метаданных, которые кэшируются в памяти.
Системные таблицы INFORMATION_SCHEMA
включают упомянутые ниже таблицы.
INNODB_SYS_DATAFILES
и
INNODB_SYS_TABLESPACES
были включены с введением поддержки
параметра DATA DIRECTORY='
в
directory
'CREATE TABLE
, который
позволяет создавать табличные пространства
file-per-table
(файлы .ibd
) вне каталога данных MySQL.
mysql> SHOW TABLES FROM INFORMATION_SCHEMA LIKE 'INNODB_SYS%'; +--------------------------------------------+ | Tables_in_information_schema (INNODB_SYS%) | +--------------------------------------------+ | INNODB_SYS_DATAFILES | | INNODB_SYS_TABLESTATS | | INNODB_SYS_FOREIGN | | INNODB_SYS_COLUMNS | | INNODB_SYS_INDEXES | | INNODB_SYS_FIELDS | | INNODB_SYS_TABLESPACES | | INNODB_SYS_FOREIGN_COLS | | INNODB_SYS_TABLES | +--------------------------------------------+
Имена таблиц показательны из типа обеспеченных данных:
INNODB_SYS_TABLES
обеспечивает метаданные о таблицах,
эквивалентные информации в SYS_TABLES
в словаре данных.
INNODB_SYS_COLUMNS
обеспечивает метаданные о столбцах таблицы, эквивалентные
информации в SYS_COLUMNS
в словаре данных.INNODB_SYS_INDEXES
обеспечивает метаданные об индексах, эквивалентные информации в
SYS_INDEXES
в словаре данных.INNODB_SYS_FIELDS
обеспечивает метаданные о ключевых столбцах (полях) индексов,
эквивалентные информации в SYS_FIELDS
.
INNODB_SYS_TABLESTATS
обеспечивает представление низкоуровневой
информации о статусе о таблицах, который получен из структур данных в памяти.
Нет никакой внутренней передачи системной таблицы.
INNODB_SYS_DATAFILES
предоставляет информацию о пути файла с
данными для file-per-table и общих табличных пространствах,
эквивалентную информации в SYS_DATAFILES
.
INNODB_SYS_TABLESPACES
обеспечивает метаданные о file-per-table и
общих табличных пространствах, эквивалентную информации в
SYS_TABLESPACES
.INNODB_SYS_FOREIGN
обеспечивает метаданные о внешних ключах, определенных на
таблицах, эквивалентную информации в SYS_FOREIGN
.
INNODB_SYS_FOREIGN_COLS
обеспечивает метаданные о столбцах внешних
ключей, которые определены на таблицах, эквивалентную информации в
SYS_FOREIGN_COLS
.Системные таблицы InnoDB
INFORMATION_SCHEMA
могут быть объединены через такие поля, как
TABLE_ID
, INDEX_ID
и SPACE
, позволяя
Вам легко получить все доступные данные для объекта.
Пример 16.11. Системные таблицы InnoDB INFORMATION_SCHEMA
Этот пример использует простую таблицу (t1
) с одним индексом
(i1
), чтобы продемонстрировать тип метаданных, найденных в
системных таблицах INFORMATION_SCHEMA
.
Создайте испытательную базу данных и таблицу
t1
:
mysql> CREATE DATABASE test; mysql> USE test; mysql> CREATE TABLE t1 (col1 INT, col2 CHAR(10), col3 VARCHAR(10)) ENGINE = InnoDB; mysql> CREATE INDEX i1 ON t1(col1);
t1
, запросите
INNODB_SYS_TABLES
, чтобы определить местонахождение метаданных для test/t1
:
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME='test/t1' \G *************************** 1. row *************************** TABLE_ID: 71 NAME: test/t1 FLAG: 1 N_COLS: 6 SPACE: 57 ROW_FORMAT: Compact ZIP_PAGE_SIZE: 0 ...
Таблица t1
имеет TABLE_ID
71. Поле
FLAG
предоставляет информацию о характеристиках хранения и
формате таблицы. Есть шесть столбцов, три из которых являются скрытыми
столбцами, создаваемыми InnoDB
(DB_ROW_ID
,
DB_TRX_ID
и DB_ROLL_PTR
). ID таблицы
SPACE
57 (0 указало бы, что таблица находится в системном
табличном пространстве). ROW_FORMAT
Compact.
ZIP_PAGE_SIZE
относится только к таблицам с
форматом строки Compressed
.
TABLE_ID
information из
INNODB_SYS_TABLES
, запросите
INNODB_SYS_COLUMNS
для информации о столбцах таблицы.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS where TABLE_ID = 71 \G *************************** 1. row *************************** TABLE_ID: 71 NAME: col1 POS: 0 MTYPE: 6 PRTYPE: 1027 LEN: 4 *************************** 2. row *************************** TABLE_ID: 71 NAME: col2 POS: 1 MTYPE: 2 PRTYPE: 524542 LEN: 10 *************************** 3. row *************************** TABLE_ID: 71 NAME: col3 POS: 2 MTYPE: 1 PRTYPE: 524303 LEN: 10
В дополнение к TABLE_ID
и столбцу NAME
INNODB_SYS_COLUMNS
обеспечивает порядковую позицию (POS
) каждого столбца
(с 0 и постепенно увеличивающуюся последовательно), MTYPE
или
main type столбца (6 = INT, 2 = CHAR, 1 = VARCHAR),
PRTYPE
или precise type
(двоичное значение с битами, которые представляют тип данных MySQL, код
набора символов и null) и длину столбца (LEN
).
TABLE_ID
из
INNODB_SYS_TABLES
еще раз, запросите
INNODB_SYS_INDEXES
для информации об индексе, связанном с таблицей
t1
.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_INDEXES WHERE TABLE_ID = 71 \G *************************** 1. row *************************** INDEX_ID: 111 NAME: GEN_CLUST_INDEX TABLE_ID: 71 TYPE: 1 N_FIELDS: 0 PAGE_NO: 3 SPACE: 57 MERGE_THRESHOLD: 50 *************************** 2. row *************************** INDEX_ID: 112 NAME: i1 TABLE_ID: 71 TYPE: 0 N_FIELDS: 1 PAGE_NO: 4 SPACE: 57 MERGE_THRESHOLD: 50
INNODB_SYS_INDEXES
возвращает данные о двух индексах. Первый индекс
GEN_CLUST_INDEX
, который является кластеризируемым,
создается InnoDB
, если у таблицы нет определяемого
пользователем кластеризуемого индекса. Второй индекс (i1
) это
определяемый пользователем вторичный индекс.
INDEX_ID
идентификатор для индекса, который уникален для
всех баз данных сервера. TABLE_ID
идентифицирует таблицу, с
которой связан индекс. Значение индекса TYPE
указывает тип
индекса (1 = Кластеризируемый, 0 = Вторичный). N_FILEDS
число полей, которые включает индекс. PAGE_NO
номер страницы
корня индекса B-tree, SPACE
ID табличного пространства, где
индекс находится. Ненулевое значение указывает, что индекс не находится в
системном табличном пространстве. MERGE_THRESHOLD
определяет пороговое значение процента для объема данных в индексной
странице. Если объем данных в индексной странице падает ниже этого значения
(по умолчанию составляет 50%), когда строка удалена или когда строка
сокращена работой обновления, InnoDB
пытается
слить индексную страницу с соседней индексной страницей.
INDEX_ID
из
INNODB_SYS_INDEXES
, запросите
INNODB_SYS_FIELDS
для информации о полях индекса i1
.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FIELDS where INDEX_ID = 112 \G *************************** 1. row *************************** INDEX_ID: 112 NAME: col1 POS: 0
INNODB_SYS_FIELDS
обеспечивает NAME
из индексированной области и ее
порядковую позицию в пределах индекса. Если индекс (i1) был определен на
несукольких полях,
INNODB_SYS_FIELDS
обеспечил бы метаданные для каждой
из индексированных областей.
SPACE
из
INNODB_SYS_TABLES
, запросите
INNODB_SYS_TABLESPACES
для информации о
табличном пространстве таблицы.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES WHERE SPACE = 57 \G *************************** 1. row *************************** SPACE: 57 NAME: test/t1 FLAG: 0 ROW_FORMAT: Compact or Redundant PAGE_SIZE: 16384 ZIP_PAGE_SIZE: 0
В дополнение к SPACE
ID табличного пространства и
NAME
из связанной таблицы,
INNODB_SYS_TABLESPACES
обеспечивает данные FLAG
табличного пространства, которые являются разрядной информацией о формате
табличного пространства и характеристиках хранения. Также обеспечены
параметры табличного пространства ROW_FORMAT
,
PAGE_SIZE
и ZIP_PAGE_SIZE
(ZIP_PAGE_SIZE
применим к табличным пространствам с
форматом строки Compressed
).
SPACE
из
INNODB_SYS_TABLES
, запросите
INNODB_SYS_DATAFILES
для местоположения файла с
данными табличного пространства.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_DATAFILES WHERE SPACE = 57 \G *************************** 1. row *************************** SPACE: 57 PATH: ./test/t1.ibd
Файл данных расположен в подкаталоге test
каталога
MySQL data
. Если табличное пространство
file-per-table
создавалось в местоположении вне каталога данных MySQL, используя
DATA DIRECTORY
в CREATE
TABLE
, PATH
был бы полным путем к каталогу.
t1
(TABLE_ID = 71
) и рассмотрите данные в
INNODB_SYS_TABLESTATS
. Данные в этой таблице используются оптимизатором, чтобы
вычислить, который индекс использовать, запрашивая таблицу.
mysql> INSERT INTO t1 VALUES(5, 'abc', 'def'); Query OK, 1 row affected (0.06 sec) mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS where TABLE_ID = 71 \G *************************** 1. row *************************** TABLE_ID: 71 NAME: test/t1 STATS_INITIALIZED: Initialized NUM_ROWS: 1 CLUST_INDEX_SIZE: 1 OTHER_INDEX_SIZE: 0 MODIFIED_COUNTER: 1 AUTOINC: 0 REF_COUNT: 1
Поле STATS_INITIALIZED
указывает, были ли статистические
данные собраны для таблицы. NUM_ROWS
текущее число строк в
таблице. Поля CLUST_INDEX_SIZE
и OTHER_INDEX_SIZE
сообщают о числе страниц на диске, которые хранят кластеризируемый и
вторичный индексы для таблицы, соответственно. MODIFIED_COUNTER
показывает число строк, измененных операциями DML и каскадными операциями от
внешних ключей. AUTOINC
следующее число, которое будет выпущено
для любой основанной на автоинкременте работы. Нет никаких столбцов
автоприращения, определенных в таблице t1
, так что это всегда 0.
REF_COUNT
счетчик. Когда счетчик достигает 0, он показывает, что
табличные метаданные могут быть вычеркнуты из табличного кэша.
Пример 16.12. Системные таблицы Foreign Key INFORMATION_SCHEMA
INNODB_SYS_FOREIGN
и
INNODB_SYS_FOREIGN_COLS
обеспечивают данные об отношениях внешнего
ключа. Этот пример использует родительскую таблицу и дочернюю таблицу с
отношениями внешнего ключа, чтобы продемонстрировать данные, найденные в
INNODB_SYS_FOREIGN
и
INNODB_SYS_FOREIGN_COLS
.
Создайте испытательную базу данных с родительскими и дочерними таблицами:
mysql> CREATE DATABASE test; mysql> USE test; mysql> CREATE TABLE parent (id INT NOT NULL, -> PRIMARY KEY (id)) ENGINE=INNODB; mysql> CREATE TABLE child (id INT, parent_id INT, -> INDEX par_ind (parent_id), CONSTRAINT fk1 -> FOREIGN KEY (parent_id) REFERENCES parent(id) -> ON DELETE CASCADE) ENGINE=INNODB;
INNODB_SYS_FOREIGN
и определите местонахождение данных о внешнем ключе для
test/child
и test/parent
:
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN \G *************************** 1. row *************************** ID: test/fk1 FOR_NAME: test/child REF_NAME: test/parent N_COLS: 1 TYPE: 1
Метаданные включают внешний ключ ID
(fk1
),
который назван по имени CONSTRAINT
, был определен на дочерней
таблице. FOR_NAME
название дочерней таблицы, где внешний ключ
определен. REF_NAME
название родительской таблицы
(referenced таблица). N_COLS
число столбцов во внешнем ключе индекса. TYPE
численное
значение, представляющее разрядные флаги, которые обеспечивают
дополнительную информацию о столбце внешнего ключа. В этом случае
TYPE
= 1, который указывает, что опция ON DELETE CASCADE
была определена для внешнего ключа. См. опередение таблицы
INNODB_SYS_FOREIGN
для получения дополнительной информации о TYPE
.
ID
, запросите
INNODB_SYS_FOREIGN_COLS
, чтобы просмотреть данные о
столбцах внешнего ключа.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN_COLS WHERE ID = 'test/fk1' \G *************************** 1. row *************************** ID: test/fk1 FOR_COL_NAME: parent_id REF_COL_NAME: id POS: 0
FOR_COL_NAME
название столбца внешнего ключа в дочерней
таблице, а REF_COL_NAME
название столбца, на который ссылаются,
в родительской таблице. POS
порядковая позиция поля ключа в
пределах индекса внешнего ключа, начиная с 0.
Пример 16.13. Объединение системных таблиц INFORMATION_SCHEMA
Этот пример демонстрирует присоединение трех системных таблиц
InnoDB
INFORMATION_SCHEMA
(INNODB_SYS_TABLES
,
INNODB_SYS_TABLESPACES
и
INNODB_SYS_TABLESTATS
), чтобы собрать формат файла, формат строки, размер страницы и
информацию о размере индекса о таблицах в базе данных.
Следующие псевдонимы имени таблицы используются, чтобы сократить строку запроса:
IF()
используется, чтобы составлять сжатые таблицы. Если таблица сжата,
размер индекса вычислен, используя ZIP_PAGE_SIZE
вместо
PAGE_SIZE
. CLUST_INDEX_SIZE
и
OTHER_INDEX_SIZE
, о которых сообщают в байтах, разделены на
1024*1024
чтобы обеспечить размеры индекса в мегабайтах (MB).
Значения MB округлены, используя функцию
ROUND()
.
mysql> SELECT a.NAME, a.ROW_FORMAT, @page_size := IF (a.ROW_FORMAT='Compressed', b.ZIP_PAGE_SIZE, b.PAGE_SIZE) AS page_size, ROUND((@page_size * c.CLUST_INDEX_SIZE) /(1024*1024)) AS pk_mb, ROUND((@page_size * c.OTHER_INDEX_SIZE) /(1024*1024)) AS secidx_mb FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES a INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES b on a.NAME = b.NAME INNER JOIN INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS c on b.NAME = c.NAME WHERE a.NAME LIKE 'employees/%' ORDER BY a.NAME DESC; +------------------------+------------+-----------+-------+-----------+ | NAME | ROW_FORMAT | page_size | pk_mb | secidx_mb | +------------------------+------------+-----------+-------+-----------+ | employees/titles | Dynamic | 16384 | 20 | 11 | | employees/salaries | Dynamic | 16384 | 93 | 34 | | employees/employees | Dynamic | 16384 | 15 | 0 | | employees/dept_manager | Dynamic | 16384 | 0 | 0 | | employees/dept_emp | Dynamic | 16384 | 12 | 10 | | employees/departments | Dynamic | 16384 | 0 | 0 | +------------------------+------------+-----------+-------+-----------+
Следующие таблицы хранят метаданные для FULLTEXT
:
mysql> SHOW TABLES FROM INFORMATION_SCHEMA LIKE 'INNODB_FT%'; +-------------------------------------------+ | Tables_in_INFORMATION_SCHEMA (INNODB_FT%) | +-------------------------------------------+ | INNODB_FT_CONFIG | | INNODB_FT_BEING_DELETED | | INNODB_FT_DELETED | | INNODB_FT_DEFAULT_STOPWORD | | INNODB_FT_INDEX_TABLE | | INNODB_FT_INDEX_CACHE | +-------------------------------------------+
INNODB_FT_CONFIG
: Метаданные об индексе FULLTEXT
и связанная обработка для таблицы.
INNODB_FT_BEING_DELETED
: Обеспечивает снимок таблицы
INNODB_FT_DELETED
, которая используется только во время
OPTIMIZE TABLE
.
При работе OPTIMIZE TABLE
INNODB_FT_BEING_DELETED
освобождена, и DOC_ID удалены из
INNODB_FT_DELETED
. Поскольку содержание
INNODB_FT_BEING_DELETED
, как правило, хранится мало, эта
таблица является ограниченной утилитой для контроля или отладки. Для
информации о выполнении OPTIMIZE TABLE
на таблицах с FULLTEXT
см.
раздел 13.9.6.INNODB_FT_DELETED
: Строки записей, которые удалены из FULLTEXT
.
Чтобы избежать дорогой перестройки индекса во время операций DML для
FULLTEXT
, информация о недавно удаленных словах хранится
отдельно, фильтруется из результатов поиска, когда Вы выполняете текстовый
поиск и удаляется из основного индекса только, когда Вы выполняете
OPTIMIZE TABLE
.
INNODB_FT_DEFAULT_STOPWORD
: Хранит список
стоп-слов, которые используются
по умолчанию, создавая FULLTEXT
.
См. раздел 13.9.4.
INNODB_FT_INDEX_TABLE
: Содержит данные об инвертированном
индексе, используемом, чтобы обработать
текстовые поиски в FULLTEXT
.
INNODB_FT_INDEX_CACHE
: Содержит информацию о маркере о недавно
вставленных строках в FULLTEXT
. Чтобы избежать дорогой
перестройки индекса во время операций DML, информация о недавно
индексированных словах хранится отдельно и объединена с основным поиском
только, когда выполняется OPTIMIZE
TABLE
, сервер закрыт или размер кэша превышает предел,
определенный
innodb_ft_cache_size
или
innodb_ft_total_cache_size
.За исключением
INNODB_FT_DEFAULT_STOPWORD
, Вы должны установить параметр
innodb_ft_aux_table
к названию таблицы
(database_name
/table_name
),
которая содержит индекс FULLTEXT
. Иначе
таблицы INFORMATION_SCHEMA
для индекса
FULLTEXT
окажутся пустыми.
Пример 16.14. InnoDB Таблицы INFORMATION_SCHEMA FULLTEXT
Этот пример использует таблицу с FULLTEXT
, чтобы
продемонстрировать данные, содержавшиеся в таблицах
INFORMATION_SCHEMA
FULLTEXT
.
Составьте таблицу с FULLTEXT
и вставьте некоторые данные:
mysql> CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT (title,body)) ENGINE=InnoDB; INSERT INTO articles (title,body) VALUES ('MySQL Tutorial','DBMS stands for DataBase ...'), ('How To Use MySQL Well','After you went through a ...'), ('Optimizing MySQL','In this tutorial we will show ...'), ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), ('MySQL vs. YourSQL','In the following database comparison ...'), ('MySQL Security','When configured properly, MySQL ...');
innodb_ft_aux_table
к названию таблицы с FULLTEXT
.
Если эта переменная не установлена, INFORMATION_SCHEMA
FULLTEXT
таблицы окажутся пустыми, за исключением
INNODB_FT_DEFAULT_STOPWORD
.
SET GLOBAL innodb_ft_aux_table = 'test/articles';
INNODB_FT_INDEX_CACHE
, которая показывает информацию о недавно
вставленных строках в FULLTEXT
. Чтобы избежать дорогой
перестройки индекса во время операций DML, данные для недавно вставленных
строк остаются в кэше FULLTEXT
до выполнения
OPTIMIZE TABLE
, перезапуска
сервера или пока кэш не закончится.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE LIMIT 5; +------------+--------------+-------------+-----------+--------+----------+ | WORD | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION | +------------+--------------+-------------+-----------+--------+----------+ | 1001 | 5 | 5 | 1 | 5 | 0 | | after | 3 | 3 | 1 | 3 | 22 | | comparison | 6 | 6 | 1 | 6 | 44 | | configured | 7 | 7 | 1 | 7 | 20 | | database | 2 | 6 | 2 | 2 | 31 | +------------+--------------+-------------+-----------+--------+----------+
innodb_optimize_fulltext_only
и выполните
OPTIMIZE TABLE
на таблице, которая содержит FULLTEXT
. Эта работа сбрасывает
кэш FULLTEXT
в индекс FULLTEXT
.
innodb_optimize_fulltext_only
изменяет логику действий
OPTIMIZE TABLE
и предназначены, чтобы быть включенным временно, во время операций
обслуживания таблиц с FULLTEXT
.
mysql> SET GLOBAL innodb_optimize_fulltext_only=ON; Query OK, 0 rows affected (0.00 sec) mysql> OPTIMIZE TABLE articles; +---------------+----------+----------+----------+ | Table | Op | Msg_type | Msg_text | +---------------+----------+----------+----------+ | test.articles | optimize | status | OK | +---------------+----------+----------+----------+
INNODB_FT_INDEX_TABLE
, чтобы рассмотреть информацию о данных в
основном индексе FULLTEXT
, включая информацию о данных,
которые только поступили от кэша.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE LIMIT 5; +------------+--------------+-------------+-----------+--------+----------+ | WORD | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION | +------------+--------------+-------------+-----------+--------+----------+ | 1001 | 5 | 5 | 1 | 5 | 0 | | after | 3 | 3 | 1 | 3 | 22 | | comparison | 6 | 6 | 1 | 6 | 44 | | configured | 7 | 7 | 1 | 7 | 20 | | database | 2 | 6 | 2 | 2 | 31 | +------------+--------------+-------------+-----------+--------+----------+
Таблица
INNODB_FT_INDEX_CACHE
теперь пуста, начиная с выполнения
OPTIMIZE TABLE
.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE LIMIT 5; Empty set (0.00 sec)
test/articles
.
mysql> DELETE FROM test.articles WHERE id < 4; Query OK, 3 rows affected (0.11 sec)
INNODB_FT_DELETED
. Эта таблица делает запись строк, которые
удалены из FULLTEXT
. Чтобы избежать дорогой перестройки индекса
во время операций DML, информация о недавно удаленных записях хранится
отдельно, фильтруется из результатов поиска, когда Вы делаете текстовый
поиск и удалена из основного индекса, когда Вы выполняете
OPTIMIZE TABLE
.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED; +--------+ | DOC_ID | +--------+ | 2 | | 3 | | 4 | +--------+
OPTIMIZE TABLE
, чтобы дкйствительно удалить удаленные запись.
mysql> OPTIMIZE TABLE articles; +---------------+----------+----------+----------+ | Table | Op | Msg_type | Msg_text | +---------------+----------+----------+----------+ | test.articles | optimize | status | OK | +---------------+----------+----------+----------+
Таблица
INNODB_FT_DELETED
должна теперь быть пустой.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED; Empty set (0.00 sec)
INNODB_FT_CONFIG
. Эта таблица содержит метаданные об индексе
FULLTEXT
и связанной обработке:
optimize_checkpoint_limit
число секунд, после
которого остановится OPTIMIZE TABLE
.
synced_doc_id
следующий DOC_ID
.stopword_table_name
имя database/table
определяемой пользователем таблицы стоп-слов. Эта область окажется пустой,
если нет никакой определяемой пользователем таблицы стоп-слов.use_stopword
указывает, используется ли таблица стоп-слов,
которая определена, когда создан FULLTEXT
.mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG; +---------------------------+-------+ | KEY | VALUE | +---------------------------+-------+ | optimize_checkpoint_limit | 180 | | synced_doc_id | 8 | | stopword_table_name | | | use_stopword | 1 | +---------------------------+-------+
Таблицы буферного пула обеспечивают
информацию о статусе и метаданные о страницах в пределах
буферного пула InnoDB
.
Таблицы буферного пула включают:
mysql> SHOW TABLES FROM INFORMATION_SCHEMA LIKE 'INNODB_BUFFER%'; +-----------------------------------------------+ | Tables_in_INFORMATION_SCHEMA (INNODB_BUFFER%) | +-----------------------------------------------+ | INNODB_BUFFER_PAGE_LRU | | INNODB_BUFFER_PAGE | | INNODB_BUFFER_POOL_STATS | +-----------------------------------------------+
INNODB_BUFFER_PAGE
: хранит информацию о каждой странице в
буферном пуле InnoDB
.
INNODB_BUFFER_PAGE_LRU
: хранит информацию о страницах в
буферном пуле в особенности как они упорядочиваются в списке LRU, который
определяет, какие страницы вычеркнуть из буферного пула, когда это становится
полным.
INNODB_BUFFER_PAGE_LRU
имеет те же самые столбцы, как
INNODB_BUFFER_PAGE
, за исключением того, что
INNODB_BUFFER_PAGE_LRU
имеет столбец LRU_POSITION
вместо BLOCK_ID
.
INNODB_BUFFER_POOL_STATS
: обеспечивает информацию о статусе.
Большая часть той же самой информации предоставлена
SHOW ENGINE INNODB STATUS
или может быть получена, используя переменные состояния сервера.
Запросы
INNODB_BUFFER_PAGE
или
INNODB_BUFFER_PAGE_LRU
могут ввести существенную нагрузку. Не запрашивайте эти таблицы на
производственной системе, если Вы не знаете об исполнительном влиянии,
которое Ваш запрос может оказать. Чтобы избежать воздействовать на работу,
воспроизведите проблему, которую Вы хотите исследовать,
на испытательном случае.
Пример 16.15. Запрос системных данных в таблице INNODB_BUFFER_PAGE
Этот запрос предоставляет приблизительное количество страниц, которые
содержат системные данные, за исключением страниц, где
TABLE_NAME
NULL
или включает наклонную черту
/
или точку .
в имени таблицы, которое указывает на
определяемую пользователем таблицу.
SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE WHERE TABLE_NAME IS NULL OR (INSTR(TABLE_NAME, '/') = 0 AND INSTR(TABLE_NAME, '.') = 0); +----------+ | COUNT(*) | +----------+ | 1516 | +----------+
Этот запрос возвращает приблизительное количество страниц, которые содержат системные данные, общее количество страниц буферного пула и приблизительный процент страниц, которые содержат системные данные.
SELECT (SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE WHERE TABLE_NAME IS NULL OR (INSTR(TABLE_NAME, '/') = 0 AND INSTR(TABLE_NAME, '.') = 0)) AS system_pages, (SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE) AS total_pages, (SELECT ROUND((system_pages/total_pages) * 100)) AS system_page_percentage; +--------------+-------------+------------------------+ | system_pages | total_pages | system_page_percentage | +--------------+-------------+------------------------+ | 295 | 8192 | 4 | +--------------+-------------+------------------------+
Тип системных данных в буферном пуле может быть определен, запрашивая
PAGE_TYPE
. Например, следующий запрос возвращает восемь отличных
PAGE_TYPE
среди страниц, которые содержат системные данные:
mysql> SELECT DISTINCT PAGE_TYPE FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE WHERE TABLE_NAME IS NULL OR (INSTR(TABLE_NAME, '/') = 0 AND INSTR(TABLE_NAME, '.') = 0); +-------------------+ | PAGE_TYPE | +-------------------+ | SYSTEM | | IBUF_BITMAP | | UNKNOWN | | FILE_SPACE_HEADER | | INODE | | UNDO_LOG | | ALLOCATED | +-------------------+
Пример 16.16. Запрос пользовательских данных в таблице INNODB_BUFFER_PAGE
Этот запрос предоставляет приблизительное количество страниц, содержащих
пользовательские данные, считая страницы, где
TABLE_NAME
NOT NULL
и
NOT LIKE '%INNODB_SYS_TABLES%'
.
mysql> SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE WHERE TABLE_NAME IS NOT NULL AND TABLE_NAME NOT LIKE '%INNODB_SYS_TABLES%'; +----------+ | COUNT(*) | +----------+ | 7897 | +----------+
Этот запрос возвращает приблизительное количество страниц, которые содержат пользовательские данные, общее количество страниц буферного пула и приблизительный процент страниц, которые содержат пользовательские данные.
mysql> SELECT (SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE WHERE TABLE_NAME IS NOT NULL AND (INSTR(TABLE_NAME, '/') > 0 OR INSTR(TABLE_NAME, '.') > 0)) AS user_pages, (SELECT COUNT(*) FROM information_schema.INNODB_BUFFER_PAGE) AS total_pages, (SELECT ROUND((user_pages/total_pages) * 100)) AS user_page_percentage; +------------+-------------+----------------------+ | user_pages | total_pages | user_page_percentage | +------------+-------------+----------------------+ | 7897 | 8192 | 96 | +------------+-------------+----------------------+
Этот запрос идентифицирует определяемые пользователем таблицы со страницами в буферном пуле:
mysql> SELECT DISTINCT TABLE_NAME FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE WHERE TABLE_NAME IS NOT NULL AND (INSTR(TABLE_NAME, '/') > 0 OR INSTR(TABLE_NAME, '.') > 0) AND TABLE_NAME NOT LIKE '`mysql`.`innodb_%'; +-------------------------+ | TABLE_NAME | +-------------------------+ | `employees`.`salaries` | | `employees`.`employees` | +-------------------------+
Пример 16.17. Запрос индексных данных в таблице INNODB_BUFFER_PAGE
Для информации об индексных страницах запросите столбец INDEX_NAME
, используя название индекса. Например, следующий запрос возвращает
число страниц и полный размер данных страниц для индекса emp_no
,
который определен на таблице employees.salaries
:
mysql> SELECT INDEX_NAME, COUNT(*) AS Pages, ROUND(SUM(IF(COMPRESSED_SIZE = 0, @@global.innodb_page_size, COMPRESSED_SIZE))/1024/1024) AS 'Total Data (MB)' FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE WHERE INDEX_NAME='emp_no' AND TABLE_NAME = '`employees`.`salaries`'; +------------+-------+-----------------+ | INDEX_NAME | Pages | Total Data (MB) | +------------+-------+-----------------+ | emp_no | 1609 | 25 | +------------+-------+-----------------+
Этот запрос возвращает число страниц и полный размер данных страниц для
всех индексов, определенных в таблице employees.salaries
:
mysql> SELECT INDEX_NAME, COUNT(*) AS Pages, ROUND(SUM(IF(COMPRESSED_SIZE = 0, @@global.innodb_page_size, COMPRESSED_SIZE))/1024/1024) AS 'Total Data (MB)' FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE WHERE TABLE_NAME = '`employees`.`salaries`' GROUP BY INDEX_NAME; +------------+-------+-----------------+ | INDEX_NAME | Pages | Total Data (MB) | +------------+-------+-----------------+ | emp_no | 1608 | 25 | | PRIMARY | 6086 | 95 | +------------+-------+-----------------+
Пример 16.18. Запрос данных LRU_POSITION в INNODB_BUFFER_PAGE_LRU
INNODB_BUFFER_PAGE_LRU
содержит информацию о страницах в
буферном пуле, в особенности как он упорядочивается, что определяет, какие
страницы вычеркнуть из буферного пула, когда это становится полным.
Определение для этой страницы то же самое, как и
INNODB_BUFFER_PAGE
, но эта таблица имеет столбец
LRU_POSITION
вместо BLOCK_ID
.
Этот запрос считает число позиций в определенном местоположении в списке
LRU занятых страницами employees.employees
.
mysql> SELECT COUNT(LRU_POSITION) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU WHERE TABLE_NAME='`employees`.`employees`' AND LRU_POSITION < 3072; +---------------------+ | COUNT(LRU_POSITION) | +---------------------+ | 548 | +---------------------+
Пример 16.19. Запрос INNODB_BUFFER_POOL_STATS
INNODB_BUFFER_POOL_STATS
предоставляет информацию, подобную
SHOW ENGINE INNODB
STATUS
и переменным состояния.
mysql> SELECT * FROM information_schema.INNODB_BUFFER_POOL_STATS \G *************************** 1. row *************************** POOL_ID: 0 POOL_SIZE: 8192 FREE_BUFFERS: 1 DATABASE_PAGES: 8173 OLD_DATABASE_PAGES: 3014 MODIFIED_DATABASE_PAGES: 0 PENDING_DECOMPRESS: 0 PENDING_READS: 0 PENDING_FLUSH_LRU: 0 PENDING_FLUSH_LIST: 0 PAGES_MADE_YOUNG: 15907 PAGES_NOT_MADE_YOUNG: 3803101 PAGES_MADE_YOUNG_RATE: 0 PAGES_MADE_NOT_YOUNG_RATE: 0 NUMBER_PAGES_READ: 3270 NUMBER_PAGES_CREATED: 13176 NUMBER_PAGES_WRITTEN: 15109 PAGES_READ_RATE: 0 PAGES_CREATE_RATE: 0 PAGES_WRITTEN_RATE: 0 NUMBER_PAGES_GET: 33069332 HIT_RATE: 0 YOUNG_MAKE_PER_THOUSAND_GETS: 0 NOT_YOUNG_MAKE_PER_THOUSAND_GETS: 0 NUMBER_PAGES_READ_AHEAD: 2713 NUMBER_READ_AHEAD_EVICTED: 0 READ_AHEAD_RATE: 0 READ_AHEAD_EVICTED_RATE: 0 LRU_IO_TOTAL: 0 LRU_IO_CURRENT: 0 UNCOMPRESS_TOTAL: 0 UNCOMPRESS_CURRENT: 0
Для сравнения SHOW ENGINE INNODB
STATUS
и переменные состояния показаны ниже, основанные на том же
самом наборе данных.
См. раздел 16.16.3.
mysql> SHOW ENGINE INNODB STATUS \G ... ---------------------- BUFFER POOL AND MEMORY ---------------------- Total large memory allocated 137428992 Dictionary memory allocated 579084 Buffer pool size 8192 Free buffers 1 Database pages 8173 Old database pages 3014 Modified db pages 0 Pending reads 0 Pending writes: LRU 0, flush list 0, single page 0 Pages made young 15907, not young 3803101 0.00 youngs/s, 0.00 non-youngs/s Pages read 3270, created 13176, written 15109 0.00 reads/s, 0.00 creates/s, 0.00 writes/s No buffer pool page gets since the last printout Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s LRU len: 8173, unzip_LRU len: 0 I/O sum[0]:cur[0], unzip sum[0]:cur[0] ...
См. раздел 6.1.7.
mysql> SHOW STATUS LIKE 'Innodb_buffer%'; +---------------------------------------+-------------+ | Variable_name | Value | +---------------------------------------+-------------+ | Innodb_buffer_pool_dump_status | not started | | Innodb_buffer_pool_load_status | not started | | Innodb_buffer_pool_resize_status | not started | | Innodb_buffer_pool_pages_data | 8173 | | Innodb_buffer_pool_bytes_data | 133906432 | | Innodb_buffer_pool_pages_dirty | 0 | | Innodb_buffer_pool_bytes_dirty | 0 | | Innodb_buffer_pool_pages_flushed | 15109 | | Innodb_buffer_pool_pages_free | 1 | | Innodb_buffer_pool_pages_misc | 18 | | Innodb_buffer_pool_pages_total | 8192 | | Innodb_buffer_pool_read_ahead_rnd | 0 | | Innodb_buffer_pool_read_ahead | 2713 | | Innodb_buffer_pool_read_ahead_evicted | 0 | | Innodb_buffer_pool_read_requests | 33069332 | | Innodb_buffer_pool_reads | 558 | | Innodb_buffer_pool_wait_free | 0 | | Innodb_buffer_pool_write_requests | 11985961 | +---------------------------------------+-------------+
INNODB_METRICS
хранит данные производительности и связанных с ресурсом счетчиков:
Столбцы INNODB_METRICS
показаны в следующем примере. Для описания каждого столбца см.
раздел 22.30.16.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME="dml_inserts" \G *************************** 1. row *************************** NAME: dml_inserts SUBSYSTEM: dml COUNT: 46273 MAX_COUNT: 46273 MIN_COUNT: NULL AVG_COUNT: 492.2659574468085 COUNT_RESET: 46273 MAX_COUNT_RESET: 46273 MIN_COUNT_RESET: NULL AVG_COUNT_RESET: NULL TIME_ENABLED: 2014-11-28 16:07:53 TIME_DISABLED: NULL TIME_ELAPSED: 94 TIME_RESET: NULL STATUS: enabled TYPE: status_counter COMMENT: Number of rows inserted
Вы можете включить, отключить и сбросить счетчики, используя следующие параметры конфигурации:
innodb_monitor_enable
: Включает один или более счетчиков.
SET GLOBAL innodb_monitor_enable = [counter-name|module_name|pattern|all];
innodb_monitor_disable
: Выключает один или более счетчиков.
SET GLOBAL innodb_monitor_disable = [counter-name|module_name|pattern|all];
innodb_monitor_reset
: Сбрасывает в 0 один или более счетчиков.
SET GLOBAL innodb_monitor_reset = [counter-name|module_name|pattern|all];
innodb_monitor_reset_all
: Сбрасывает все значения для одного или
более счетчиков. Счетчик должен быть отключен перед использованием
innodb_monitor_reset_all
.
SET GLOBAL innodb_monitor_reset_all = [counter-name|module_name|pattern|all];
Вы можете также включить счетчик при запуске, используя конфигурационный
файл сервера MySQL. Например, чтобы включить модуль log
и
счетчики metadata_table_handles_opened
и
metadata_table_handles_closed
, введите следующую строку в раздел
[mysqld]
конфигурационного файла my.cnf
.
[mysqld] innodb_monitor_enable = module_recovery,metadata_table_handles_opened,metadata_table_handles_closed
Включая много счетчиков в Вашем конфигурационном файле, Вы должны
определить
innodb_monitor_enable
, сопровождаемый счетчиком, отделенными
запятой, как показано в примере выше. Только
innodb_monitor_enable
может использоваться в Вашем конфигурационном файле. Выключение и
сброс поддержаны только в командной строке.
Поскольку каждый счетчик налагает определенную степень времени выполнения на сервере, как правило, Вы включаете большое количество счетчиков на сервере теста и развития во время экспериментирования и сопоставительного анализа, и позволяете счетчикам на производственных серверах только диагностировать известные проблемы или аспекты, которые, вероятно, будут узкими местами для особого сервера и рабочей нагрузки.
Счетчики, представленные в
INNODB_METRICS
подвержены изменениям, таким образом, для
самого современного списка, запросите рабочий сервер MySQL. Список ниже
перечисляет счетчики, которые доступны с MySQL 8.0.
Счетчики, которые включены по умолчанию, соответствуют используемым
SHOW ENGINE INNODB STATUS
.
Счетчики, используемые SHOW ENGINE INNODB
STATUS
, всегда on на системном уровне,
но Вы можете отключить эти счетчики для
INNODB_METRICS
,
как требуется. Кроме того, состояние не является постоянным. Если не
определено иное, счетчики возвращаются к своему значению по умолчанию,
когда сервер перезапущен.
Если бы Вы выполняете программы, которые были бы затронуты дополнениями
или изменяют INNODB_METRICS
, рекомендуется, чтобы Вы рассмотрели примечания выпусков и
запросили INNODB_METRICS
для нового выпуска до обновления.
mysql> SELECT name, subsystem, status FROM INFORMATION_SCHEMA.INNODB_METRICS ORDER BY NAME; +------------------------------------------+---------------------+----------+ | name | subsystem | status | +------------------------------------------+---------------------+----------+ | adaptive_hash_pages_added | adaptive_hash_index | disabled | | adaptive_hash_pages_removed | adaptive_hash_index | disabled | | adaptive_hash_rows_added | adaptive_hash_index | disabled | | adaptive_hash_rows_deleted_no_hash_entry | adaptive_hash_index | disabled | | adaptive_hash_rows_removed | adaptive_hash_index | disabled | | adaptive_hash_rows_updated | adaptive_hash_index | disabled | | adaptive_hash_searches | adaptive_hash_index | enabled | | adaptive_hash_searches_btree | adaptive_hash_index | enabled | | buffer_data_reads | buffer | enabled | | buffer_data_written | buffer | enabled | | buffer_flush_adaptive | buffer | disabled | | buffer_flush_adaptive_avg_pass | buffer | disabled | | buffer_flush_adaptive_avg_time_est | buffer | disabled | | buffer_flush_adaptive_avg_time_slot | buffer | disabled | | buffer_flush_adaptive_avg_time_thread | buffer | disabled | | buffer_flush_adaptive_pages | buffer | disabled | | buffer_flush_adaptive_total_pages | buffer | disabled | | buffer_flush_avg_page_rate | buffer | disabled | | buffer_flush_avg_pass | buffer | disabled | | buffer_flush_avg_time | buffer | disabled | | buffer_flush_background | buffer | disabled | | buffer_flush_background_pages | buffer | disabled | | buffer_flush_background_total_pages | buffer | disabled | | buffer_flush_batches | buffer | disabled | | buffer_flush_batch_num_scan | buffer | disabled | | buffer_flush_batch_pages | buffer | disabled | | buffer_flush_batch_scanned | buffer | disabled | | buffer_flush_batch_scanned_per_call | buffer | disabled | | buffer_flush_batch_total_pages | buffer | disabled | | buffer_flush_lsn_avg_rate | buffer | disabled | | buffer_flush_neighbor | buffer | disabled | | buffer_flush_neighbor_pages | buffer | disabled | | buffer_flush_neighbor_total_pages | buffer | disabled | | buffer_flush_n_to_flush_by_age | buffer | disabled | | buffer_flush_n_to_flush_requested | buffer | disabled | | buffer_flush_pct_for_dirty | buffer | disabled | | buffer_flush_pct_for_lsn | buffer | disabled | | buffer_flush_sync | buffer | disabled | | buffer_flush_sync_pages | buffer | disabled | | buffer_flush_sync_total_pages | buffer | disabled | | buffer_flush_sync_waits | buffer | disabled | | buffer_LRU_batches_evict | buffer | disabled | | buffer_LRU_batches_flush | buffer | disabled | | buffer_LRU_batch_evict_pages | buffer | disabled | | buffer_LRU_batch_evict_total_pages | buffer | disabled | | buffer_LRU_batch_flush_avg_pass | buffer | disabled | | buffer_LRU_batch_flush_avg_time_est | buffer | disabled | | buffer_LRU_batch_flush_avg_time_slot | buffer | disabled | | buffer_LRU_batch_flush_avg_time_thread | buffer | disabled | | buffer_LRU_batch_flush_pages | buffer | disabled | | buffer_LRU_batch_flush_total_pages | buffer | disabled | | buffer_LRU_batch_num_scan | buffer | disabled | | buffer_LRU_batch_scanned | buffer | disabled | | buffer_LRU_batch_scanned_per_call | buffer | disabled | | buffer_LRU_get_free_loops | buffer | disabled | | buffer_LRU_get_free_search | Buffer | disabled | | buffer_LRU_get_free_waits | buffer | disabled | | buffer_LRU_search_num_scan | buffer | disabled | | buffer_LRU_search_scanned | buffer | disabled | | buffer_LRU_search_scanned_per_call | buffer | disabled | | buffer_LRU_single_flush_failure_count | Buffer | disabled | | buffer_LRU_single_flush_num_scan | buffer | disabled | | buffer_LRU_single_flush_scanned | buffer | disabled | | buffer_LRU_single_flush_scanned_per_call | buffer | disabled | | buffer_LRU_unzip_search_num_scan | buffer | disabled | | buffer_LRU_unzip_search_scanned | buffer | disabled | | buffer_LRU_unzip_search_scanned_per_call | buffer | disabled | | buffer_pages_created | buffer | enabled | | buffer_pages_read | buffer | enabled | | buffer_pages_written | buffer | enabled | | buffer_page_read_blob | buffer_page_io | disabled | | buffer_page_read_fsp_hdr | buffer_page_io | disabled | | buffer_page_read_ibuf_bitmap | buffer_page_io | disabled | | buffer_page_read_ibuf_free_list | buffer_page_io | disabled | | buffer_page_read_index_ibuf_leaf | buffer_page_io | disabled | | buffer_page_read_index_ibuf_non_leaf | buffer_page_io | disabled | | buffer_page_read_index_inode | buffer_page_io | disabled | | buffer_page_read_index_leaf | buffer_page_io | disabled | | buffer_page_read_index_non_leaf | buffer_page_io | disabled | | buffer_page_read_other | buffer_page_io | disabled | | buffer_page_read_system_page | buffer_page_io | disabled | | buffer_page_read_trx_system | buffer_page_io | disabled | | buffer_page_read_undo_log | buffer_page_io | disabled | | buffer_page_read_xdes | buffer_page_io | disabled | | buffer_page_read_zblob | buffer_page_io | disabled | | buffer_page_read_zblob2 | buffer_page_io | disabled | | buffer_page_written_blob | buffer_page_io | disabled | | buffer_page_written_fsp_hdr | buffer_page_io | disabled | | buffer_page_written_ibuf_bitmap | buffer_page_io | disabled | | buffer_page_written_ibuf_free_list | buffer_page_io | disabled | | buffer_page_written_index_ibuf_leaf | buffer_page_io | disabled | | buffer_page_written_index_ibuf_non_leaf | buffer_page_io | disabled | | buffer_page_written_index_inode | buffer_page_io | disabled | | buffer_page_written_index_leaf | buffer_page_io | disabled | | buffer_page_written_index_non_leaf | buffer_page_io | disabled | | buffer_page_written_other | buffer_page_io | disabled | | buffer_page_written_system_page | buffer_page_io | disabled | | buffer_page_written_trx_system | buffer_page_io | disabled | | buffer_page_written_undo_log | buffer_page_io | disabled | | buffer_page_written_xdes | buffer_page_io | disabled | | buffer_page_written_zblob | buffer_page_io | disabled | | buffer_page_written_zblob2 | buffer_page_io | disabled | | buffer_pool_bytes_data | buffer | enabled | | buffer_pool_bytes_dirty | buffer | enabled | | buffer_pool_pages_data | buffer | enabled | | buffer_pool_pages_dirty | buffer | enabled | | buffer_pool_pages_free | buffer | enabled | | buffer_pool_pages_misc | buffer | enabled | | buffer_pool_pages_total | buffer | enabled | | buffer_pool_reads | buffer | enabled | | buffer_pool_read_ahead | buffer | enabled | | buffer_pool_read_ahead_evicted | buffer | enabled | | buffer_pool_read_requests | buffer | enabled | | buffer_pool_size | server | enabled | | buffer_pool_wait_free | buffer | enabled | | buffer_pool_write_requests | buffer | enabled | | compression_pad_decrements | compression | disabled | | compression_pad_increments | compression | disabled | | compress_pages_compressed | compression | disabled | | compress_pages_decompressed | compression | disabled | | ddl_background_drop_indexes | ddl | disabled | | ddl_background_drop_tables | ddl | disabled | | ddl_log_file_alter_table | ddl | disabled | | ddl_online_create_index | ddl | disabled | | ddl_pending_alter_table | ddl | disabled | | ddl_sort_file_alter_table | ddl | disabled | | dml_deletes | dml | enabled | | dml_inserts | dml | enabled | | dml_reads | dml | disabled | | dml_updates | dml | enabled | | file_num_open_files | file_system | enabled | | ibuf_merges | change_buffer | enabled | | ibuf_merges_delete | change_buffer | enabled | | ibuf_merges_delete_mark | change_buffer | enabled | | ibuf_merges_discard_delete | change_buffer | enabled | | ibuf_merges_discard_delete_mark | change_buffer | enabled | | ibuf_merges_discard_insert | change_buffer | enabled | | ibuf_merges_insert | change_buffer | enabled | | ibuf_size | change_buffer | enabled | | icp_attempts | icp | disabled | | icp_match | icp | disabled | | icp_no_match | icp | disabled | | icp_out_of_range | icp | disabled | | index_page_discards | index | disabled | | index_page_merge_attempts | index | disabled | | index_page_merge_successful | index | disabled | | index_page_reorg_attempts | index | disabled | | index_page_reorg_successful | index | disabled | | index_page_splits | index | disabled | | innodb_activity_count | server | enabled | | innodb_background_drop_table_usec | server | disabled | | innodb_checkpoint_usec | server | disabled | | innodb_dblwr_pages_written | server | enabled | | innodb_dblwr_writes | server | enabled | | innodb_dict_lru_count | server | disabled | | innodb_dict_lru_usec | server | disabled | | innodb_ibuf_merge_usec | server | disabled | | innodb_log_flush_usec | server | disabled | | innodb_master_active_loops | server | disabled | | innodb_master_idle_loops | server | disabled | | innodb_master_purge_usec | server | disabled | | innodb_master_thread_sleeps | server | disabled | | innodb_mem_validate_usec | server | disabled | | innodb_page_size | server | enabled | | innodb_rwlock_sx_os_waits | server | enabled | | innodb_rwlock_sx_spin_rounds | server | enabled | | innodb_rwlock_sx_spin_waits | server | enabled | | innodb_rwlock_s_os_waits | server | enabled | | innodb_rwlock_s_spin_rounds | server | enabled | | innodb_rwlock_s_spin_waits | server | enabled | | innodb_rwlock_x_os_waits | server | enabled | | innodb_rwlock_x_spin_rounds | server | enabled | | innodb_rwlock_x_spin_waits | server | enabled | | lock_deadlocks | lock | enabled | | lock_rec_locks | lock | disabled | | lock_rec_lock_created | lock | disabled | | lock_rec_lock_removed | lock | disabled | | lock_rec_lock_requests | lock | disabled | | lock_rec_lock_waits | lock | disabled | | lock_row_lock_current_waits | lock | enabled | | lock_row_lock_time | lock | enabled | | lock_row_lock_time_avg | lock | enabled | | lock_row_lock_time_max | lock | enabled | | lock_row_lock_waits | lock | enabled | | lock_table_locks | lock | disabled | | lock_table_lock_created | lock | disabled | | lock_table_lock_removed | lock | disabled | | lock_table_lock_waits | lock | disabled | | lock_timeouts | lock | enabled | | log_checkpoints | recovery | disabled | | log_lsn_buf_pool_oldest | recovery | disabled | | log_lsn_checkpoint_age | recovery | disabled | | log_lsn_current | recovery | disabled | | log_lsn_last_checkpoint | recovery | disabled | | log_lsn_last_flush | recovery | disabled | | log_max_modified_age_async | recovery | disabled | | log_max_modified_age_sync | recovery | disabled | | log_num_log_io | recovery | disabled | | log_padded | recovery | enabled | | log_pending_checkpoint_writes | recovery | disabled | | log_pending_log_flushes | recovery | disabled | | log_waits | recovery | enabled | | log_writes | recovery | enabled | | log_write_requests | recovery | enabled | | metadata_table_handles_closed | metadata | disabled | | metadata_table_handles_opened | metadata | disabled | | metadata_table_reference_count | metadata | disabled | | os_data_fsyncs | os | enabled | | os_data_reads | os | enabled | | os_data_writes | os | enabled | | os_log_bytes_written | os | enabled | | os_log_fsyncs | os | enabled | | os_log_pending_fsyncs | os | enabled | | os_log_pending_writes | os | enabled | | os_pending_reads | os | disabled | | os_pending_writes | os | disabled | | purge_del_mark_records | purge | disabled | | purge_dml_delay_usec | purge | disabled | | purge_invoked | purge | disabled | | purge_resume_count | purge | disabled | | purge_stop_count | purge | disabled | | purge_undo_log_pages | purge | disabled | | purge_upd_exist_or_extern_records | purge | disabled | | trx_active_transactions | transaction | disabled | | trx_commits_insert_update | transaction | disabled | | trx_nl_ro_commits | transaction | disabled | | trx_rollbacks | transaction | disabled | | trx_rollbacks_savepoint | transaction | disabled | | trx_rollback_active | transaction | disabled | | trx_ro_commits | transaction | disabled | | trx_rseg_current_size | transaction | disabled | | trx_rseg_history_len | transaction | enabled | | trx_rw_commits | transaction | disabled | | trx_undo_slots_cached | transaction | disabled | | trx_undo_slots_used | transaction | disabled | +------------------------------------------+---------------------+----------+ 235 rows in set (0.01 sec)
Имена модуля соответствуют, но не идентичны, значениям столбца
SUBSYSTEM
таблицы
INNODB_METRICS
. Вместо включения, отключения или сброса
счетчиков индивидуально, Вы можете использовать имена модуля, чтобы быстро
включить, отключить или сбросить все счетчики для особой подсистемы.
Например, использовать module_dml
, чтобы
включить все счетчики, связанные с подсистемой dml
.
mysql> SET GLOBAL innodb_monitor_enable = module_dml; mysql> SELECT name, subsystem, status FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem ='dml'; +-------------+-----------+---------+ | name | subsystem | status | +-------------+-----------+---------+ | dml_reads | dml | enabled | | dml_inserts | dml | enabled | | dml_deletes | dml | enabled | | dml_updates | dml | enabled | +-------------+-----------+---------+
Вот значения, для которых Вы можете использовать
module_name
с опцией
innodb_monitor_enable
и связанные параметры конфигурации, наряду с
передачей имен SUBSYSTEM
:
module_adaptive_hash
(subsystem =
adaptive_hash_index
)
module_buffer
(subsystem = buffer
)module_buffer_page
(subsystem = buffer_page_io
)
module_compress
(subsystem = compression
)module_ddl
(subsystem = ddl
)module_dml
(subsystem = dml
)module_file
(subsystem = file_system
)module_ibuf_system
(subsystem = change_buffer
)
module_icp
(subsystem = icp
)module_index
(subsystem = index
)module_innodb
(subsystem = innodb
)module_lock
(subsystem = lock
)module_log
(subsystem = recovery
)module_metadata
(subsystem = metadata
)module_os
(subsystem = os
)module_purge
(subsystem = purge
)module_trx
(subsystem = transaction
)Пример 16.20. Работа с табличными счетчиками INNODB_METRICS
Этот пример демонстрирует включение, отключение, сброс счетчика и запрос
данных счетчика в таблице
INNODB_METRICS
.
Создайте простую таблицу:
mysql> USE test; Database changed mysql> CREATE TABLE t1 (c1 INT) ENGINE=INNODB; Query OK, 0 rows affected (0.02 sec)
dml_inserts
.
mysql> SET GLOBAL innodb_monitor_enable = dml_inserts; Query OK, 0 rows affected (0.01 sec)
Описание dml_inserts
может быть найдено в столбце
COMMENT
таблицы INNODB_METRICS
:
mysql> SELECT NAME, COMMENT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME="dml_inserts"; +-------------+-------------------------+ | NAME | COMMENT | +-------------+-------------------------+ | dml_inserts | Number of rows inserted | +-------------+-------------------------+
INNODB_METRICS
для данных счетчика dml_inserts
.
Поскольку никакие операции DML не были выполнены, значения ноль или NULL.
TIME_ENABLED
и TIME_ELAPSED
указывают, когда счетчик был последний раз включен и сколько секунд
прошло с этого времени.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME="dml_inserts" \G *************************** 1. row *************************** NAME: dml_inserts SUBSYSTEM: dml COUNT: 0 MAX_COUNT: 0 MIN_COUNT: NULL AVG_COUNT: 0 COUNT_RESET: 0 MAX_COUNT_RESET: 0 MIN_COUNT_RESET: NULL AVG_COUNT_RESET: NULL TIME_ENABLED: 2014-12-04 14:18:28 TIME_DISABLED: NULL TIME_ELAPSED: 28 TIME_RESET: NULL STATUS: enabled TYPE: status_counter COMMENT: Number of rows inserted
mysql> INSERT INTO t1 values(1); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO t1 values(2); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO t1 values(3); Query OK, 1 row affected (0.00 sec)
INNODB_METRICS
снова для данных счетчика dml_inserts
.
Много значений теперь постепенно увеличились, включая
COUNT
, MAX_COUNT
, AVG_COUNT
и
COUNT_RESET
. Обратитесь к определению таблицы
INNODB_METRICS
для описаний этих значений.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME="dml_inserts"\G *************************** 1. row *************************** NAME: dml_inserts SUBSYSTEM: dml COUNT: 3 MAX_COUNT: 3 MIN_COUNT: NULL AVG_COUNT: 0.046153846153846156 COUNT_RESET: 3 MAX_COUNT_RESET: 3 MIN_COUNT_RESET: NULL AVG_COUNT_RESET: NULL TIME_ENABLED: 2014-12-04 14:18:28 TIME_DISABLED: NULL TIME_ELAPSED: 65 TIME_RESET: NULL STATUS: enabled TYPE: status_counter COMMENT: Number of rows inserted
dml_inserts
и запросите
INNODB_METRICS
для данных счетчика dml_inserts
. Значения %_RESET
,
о которых сообщили ранее, COUNT_RESET
и MAX_RESET
,
сброшены к нолю. Значения COUNT
, MAX_COUNT
и
AVG_COUNT
, которые кумулятивно собирают данные со времени
включения счетчика, сбросом не затронуты.
mysql> SET GLOBAL innodb_monitor_reset = dml_inserts; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME="dml_inserts"\G *************************** 1. row *************************** NAME: dml_inserts SUBSYSTEM: dml COUNT: 3 MAX_COUNT: 3 MIN_COUNT: NULL AVG_COUNT: 0.03529411764705882 COUNT_RESET: 0 MAX_COUNT_RESET: 0 MIN_COUNT_RESET: NULL AVG_COUNT_RESET: 0 TIME_ENABLED: 2014-12-04 14:18:28 TIME_DISABLED: NULL TIME_ELAPSED: 85 TIME_RESET: 2014-12-04 14:19:44 STATUS: enabled TYPE: status_counter COMMENT: Number of rows inserted
STATUS
в disbaled
.
mysql> SET GLOBAL innodb_monitor_disable = dml_inserts; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME="dml_inserts"\G *************************** 1. row *************************** NAME: dml_inserts SUBSYSTEM: dml COUNT: 3 MAX_COUNT: 3 MIN_COUNT: NULL AVG_COUNT: 0.030612244897959183 COUNT_RESET: 0 MAX_COUNT_RESET: 0 MIN_COUNT_RESET: NULL AVG_COUNT_RESET: 0 TIME_ENABLED: 2014-12-04 14:18:28 TIME_DISABLED: 2014-12-04 14:20:06 TIME_ELAPSED: 98 TIME_RESET: NULL STATUS: disabled TYPE: status_counter COMMENT: Number of rows inserted
Подстановочное соответствие поддержано для счетчика и имен модуля.
Например, вместо того, чтобы определить полное имя dml_inserts
,
Вы можете определить dml_i%
. Вы можете также включить, отключить
или сбросить много счетчиков или модулей, используя подстановочное
соответствие. Например, определите dml_%
для всех счетчиков,
имена которых начинаются на dml_
.
После того, как счетчик отключен, Вы можете сбросить все значения,
используя
innodb_monitor_reset_all
. Все значения установлены в ноль или NULL.
mysql> SET GLOBAL innodb_monitor_reset_all = dml_inserts; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME="dml_inserts"\G *************************** 1. row *************************** NAME: dml_inserts SUBSYSTEM: dml COUNT: 0 MAX_COUNT: NULL MIN_COUNT: NULL AVG_COUNT: NULL COUNT_RESET: 0 MAX_COUNT_RESET: NULL MIN_COUNT_RESET: NULL AVG_COUNT_RESET: NULL TIME_ENABLED: NULL TIME_DISABLED: NULL TIME_ELAPSED: NULL TIME_RESET: NULL STATUS: disabled TYPE: status_counter COMMENT: Number of rows inserted
INNODB_TEMP_TABLE_INFO
предоставляет пользователям снимок активных
временные таблицы. Таблица содержит метаданные обо всех создаваемых
пользователями и системой временных таблицах, которые являются активными в
пределах InnoDB
.
mysql> SHOW TABLES FROM INFORMATION_SCHEMA LIKE 'INNODB_TEMP%'; +---------------------------------------------+ | Tables_in_INFORMATION_SCHEMA (INNODB_TEMP%) | +---------------------------------------------+ | INNODB_TEMP_TABLE_INFO | +---------------------------------------------+
См. раздел 22.30.27.
Пример 16.21. INNODB_TEMP_TABLE_INFO
Этот пример демонстрирует характеристики
INNODB_TEMP_TABLE_INFO
table.
Создайте простую временную таблицу с единственным столбцом:
mysql> CREATE TEMPORARY TABLE t1 (c1 INT PRIMARY KEY) ENGINE=INNODB; Query OK, 0 rows affected (0.00 sec)
INNODB_TEMP_TABLE_INFO
, чтобы рассмотреть
метаданные временной таблицы.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO\G *************************** 1. row *************************** TABLE_ID: 194 NAME: #sql7a79_1_0 N_COLS: 4 SPACE: 182
TABLE_ID
уникальный идентификатор для временной таблицы.
NAME
выводит на экран произведенное системой название временной
таблицы с префиксом #sql. Число столбцов
(N_COLS
) 4 вместо 1, потому что InnoDB
всегда создает три скрытых столбца таблицы (DB_ROW_ID
,
DB_TRX_ID
и DB_ROLL_PTR
).
INNODB_TEMP_TABLE_INFO
.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO\G Empty set (0.00 sec)
Пустой набор возвращен потому, что таблица
INNODB_TEMP_TABLE_INFO
и данные в пределах нее не сохранены на
диск при завершении работы сервера.
mysql> CREATE TEMPORARY TABLE t1 (c1 INT PRIMARY KEY) ENGINE=INNODB; Query OK, 0 rows affected (0.00 sec)
INNODB_TEMP_TABLE_INFO
, чтобы рассмотреть
метаданные временной таблицы.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO\G *************************** 1. row *************************** TABLE_ID: 196 NAME: #sql7b0e_1_0 N_COLS: 4 SPACE: 184
ID SPACE
новый, потому что динамически произведен
при перезапуске сервера.
INFORMATION_SCHEMA.FILES
обеспечивает метаданные обо всех типах табличного пространства, включая
file-per-table,
общие табличные пространства
, системное табличное
пространство,
временные табличные пространства и
табличные пространства отмены
(если есть).
The
INNODB_SYS_TABLESPACES
и
INNODB_SYS_DATAFILES
также обеспечивают метаданные о табличных пространствах, но
данные ограничены file-per-table и общими табличными пространствами.
Этот запрос получает метаданные о системном табличном пространстве от
полей INFORMATION_SCHEMA.FILES
, которые являются подходящими для табличных пространств. Поля
INFORMATION_SCHEMA.FILES
,
которые не подходят, всегда возвращают NULL и исключены из запроса.
mysql> SELECT FILE_ID, FILE_NAME, FILE_TYPE, TABLESPACE_NAME, FREE_EXTENTS, TOTAL_EXTENTS, EXTENT_SIZE, INITIAL_SIZE, MAXIMUM_SIZE, AUTOEXTEND_SIZE, DATA_FREE, STATUS ENGINE FROM INFORMATION_SCHEMA.FILES WHERE TABLESPACE_NAME LIKE 'innodb_system' \G *************************** 1. row *************************** FILE_ID: 0 FILE_NAME: ./ibdata1 FILE_TYPE: TABLESPACE TABLESPACE_NAME: innodb_system FREE_EXTENTS: 0 TOTAL_EXTENTS: 12 EXTENT_SIZE: 1048576 INITIAL_SIZE: 12582912 MAXIMUM_SIZE: NULL AUTOEXTEND_SIZE: 67108864 DATA_FREE: 4194304 ENGINE: NORMAL
Этот запрос получает FILE_ID
(эквивалентный ID пространства)
и FILE_NAME
(который включает информацию о пути) для
file-per-table и общих табличных пространств. У File-per-table и общих
табличных пространств есть расширение файла .ibd
.
mysql> SELECT FILE_ID, FILE_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_NAME LIKE '%.ibd%' ORDER BY FILE_ID; +---------+---------------------------------------+ | FILE_ID | FILE_NAME | +---------+---------------------------------------+ | 2 | ./mysql/plugin.ibd | | 3 | ./mysql/servers.ibd | | 4 | ./mysql/help_topic.ibd | | 5 | ./mysql/help_category.ibd | | 6 | ./mysql/help_relation.ibd | | 7 | ./mysql/help_keyword.ibd | | 8 | ./mysql/time_zone_name.ibd | | 9 | ./mysql/time_zone.ibd | | 10 | ./mysql/time_zone_transition.ibd | | 11 | ./mysql/time_zone_transition_type.ibd | | 12 | ./mysql/time_zone_leap_second.ibd | | 13 | ./mysql/innodb_table_stats.ibd | | 14 | ./mysql/innodb_index_stats.ibd | | 15 | ./mysql/slave_relay_log_info.ibd | | 16 | ./mysql/slave_master_info.ibd | | 17 | ./mysql/slave_worker_info.ibd | | 18 | ./mysql/gtid_executed.ibd | | 19 | ./mysql/server_cost.ibd | | 20 | ./mysql/engine_cost.ibd | | 21 | ./sys/sys_config.ibd | | 23 | ./test/t1.ibd | | 26 | /home/user/test/test/t2.ibd | +---------+---------------------------------------+
Этот запрос получает FILE_ID
и FILE_NAME
для
временных табличных пространств. Временные имена файла табличного
пространства имеют префикс ibtmp
.
mysql> SELECT FILE_ID, FILE_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_NAME LIKE '%ibtmp%'; +---------+-----------+ | FILE_ID | FILE_NAME | +---------+-----------+ | 22 | ./ibtmp1 | +---------+-----------+
Точно так же имена файла табличного пространства отмены имеют префикс
undo
. Следующий запрос возвращает FILE_ID
и
FILE_NAME
для табличных пространств отмены, если отдельные
табличные пространства отмены сконфигурированы.
mysql> SELECT FILE_ID, FILE_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_NAME LIKE '%undo%';
Этот раздел обеспечивает краткое введение в интеграцию с Performance Schema. См. главу 23.
Вы можете профилировать внутренние операции, использующие MySQL Performance Schema. Этот тип настройки прежде всего для опытных пользователей, которые оценивают стратегии оптимизации, чтобы преодолеть исполнительные узкие места. DBA может также использовать эту функцию для планирования мощностей, чтобы видеть, сталкивается ли их типичная рабочая нагрузка с какими-либо исполнительными узкими местами с особой комбинацией центрального процессора, RAM и дискового хранения, и если так, чтобы судить, может ли работа быть улучшена, увеличивая параметры некоторой части системы.
Используйте эту функцию, чтобы исследовать:
Вы должны быть вообще знакомыми с тем, как использовать
Performance Schema.
Например, Вы должны знать, как включают инструменты и потребителей и как
запросить таблицы performance_schema
.
Для вводного краткого обзора см.
раздел 23.1.
InnoDB
. Чтобы посмотреть связанные инструменты, Вы
можете запросить таблицу
setup_instruments
для инструментальных имен,
которые содержат 'innodb
'.
mysql> SELECT * FROM setup_instruments WHERE NAME LIKE '%innodb%'; +------------------------------------------------------+---------+-------+ | NAME | ENABLED | TIMED | +------------------------------------------------------+---------+-------+ | wait/synch/mutex/innodb/commit_cond_mutex | NO | NO | | wait/synch/mutex/innodb/innobase_share_mutex | NO | NO | | wait/synch/mutex/innodb/autoinc_mutex | NO | NO | | wait/synch/mutex/innodb/buf_pool_mutex | NO | NO | | wait/synch/mutex/innodb/buf_pool_zip_mutex | NO | NO | | wait/synch/mutex/innodb/cache_last_read_mutex | NO | NO | | wait/synch/mutex/innodb/dict_foreign_err_mutex | NO | NO | | wait/synch/mutex/innodb/dict_sys_mutex | NO | NO | | wait/synch/mutex/innodb/recalc_pool_mutex | NO | NO | ... | wait/io/file/innodb/innodb_data_file | YES | YES | | wait/io/file/innodb/innodb_log_file | YES | YES | | wait/io/file/innodb/innodb_temp_file | YES | YES | | stage/innodb/alter table (end) | YES | YES | | stage/innodb/alter table (flush) | YES | YES | | stage/innodb/alter table (insert) | YES | YES | | stage/innodb/alter table (log apply index) | YES | YES | | stage/innodb/alter table (log apply table) | YES | YES | | stage/innodb/alter table (merge sort) | YES | YES | | stage/innodb/alter table (read PK and internal sort) | YES | YES | | stage/innodb/buffer pool load | YES | YES | | memory/innodb/buf_buf_pool | NO | NO | | memory/innodb/dict_stats_bg_recalc_pool_t | NO | NO | | memory/innodb/dict_stats_index_map_t | NO | NO | | memory/innodb/dict_stats_n_diff_on_level | NO | NO | | memory/innodb/other | NO | NO | | memory/innodb/row_log_buf | NO | NO | | memory/innodb/row_merge_sort | NO | NO | | memory/innodb/std | NO | NO | | memory/innodb/sync_debug_latches | NO | NO | | memory/innodb/trx_sys_t::rw_trx_ids | NO | NO | ... +------------------------------------------------------+---------+-------+ 155 rows in set (0.00 sec)
Для дополнительной информации об инструментованном объекте Вы можете
запросить
таблицы случаев, которые обеспечивают дополнительную информацию об
инструментованных объектах. Таблицы случая, относящиеся к InnoDB
:
Mutexes и RW-locks имеют отношение к буферному пулу, но не включены в
этот список, то же самое относится к выводу команды
SHOW ENGINE INNODB MUTEX
.
Например, чтобы рассмотреть информацию об инструментованных объектах файлов, запуская инструментовку ввода/вывода файла, Вы могли бы выпустить следующий запрос:
mysql> SELECT * FROM file_instances WHERE EVENT_NAME LIKE '%innodb%'\G *************************** 1. row *************************** FILE_NAME: /path/to/mysql-8.0/data/ibdata1 EVENT_NAME: wait/io/file/innodb/innodb_data_file OPEN_COUNT: 3 *************************** 2. row *************************** FILE_NAME: /path/to/mysql-8.0/data/ib_logfile0 EVENT_NAME: wait/io/file/innodb/innodb_log_file OPEN_COUNT: 2 *************************** 3. row *************************** FILE_NAME: /path/to/mysql-8.0/data/ib_logfile1 EVENT_NAME: wait/io/file/innodb/innodb_log_file OPEN_COUNT: 2 *************************** 4. row *************************** FILE_NAME: /path/to/mysql-8.0/data/mysql/engine_cost.ibd EVENT_NAME: wait/io/file/innodb/innodb_data_file OPEN_COUNT: 3 ...
performance_schema
, которые хранят данные событий.
Таблицы, относящиеся к событиям InnoDB
:
InnoDB
ALTER TABLE
и операции
загрузки буферного пула. См.
раздел 16.15.1
.Если Вы интересуетесь только объектами InnoDB
, используйте
WHERE EVENT_NAME LIKE '%innodb%'
или WHERE NAME LIKE
'%innodb%'
(как требуется), запрашивая эти таблицы.
Вы можете контролировать продвижение
ALTER TABLE
для таблиц InnoDB
,
используя Performance Schema.
Есть семь событий этапа, которые представляют различные фазы
ALTER TABLE
.
Каждый случай этапа сообщает о рабочем общем количестве
WORK_COMPLETED
и WORK_ESTIMATED
для полного
ALTER TABLE
, поскольку это
прогрессирует через свои различные фазы. WORK_ESTIMATED
вычислен, используя формулу, которая принимает во внимание всю работу
ALTER TABLE
,
и может быть пересмотрен во время ALTER
TABLE
. WORK_COMPLETED
и WORK_ESTIMATED
абстрактное представление всей работы, выполненной
ALTER TABLE
.
В порядке возникновения ALTER TABLE
события этапа включают:
stage/innodb/alter table (read PK and internal sort)
:
Этот этап является активным, когда
ALTER TABLE
находится в фазе чтения первичного ключа. Это запускается с
WORK_COMPLETED=0
и WORK_ESTIMATED
, установленному
к предполагаемому числу страниц в первичном ключе. Когда этап завершен,
WORK_ESTIMATED
обновлен к фактическому числу
страниц в первичном ключе.
stage/innodb/alter table (merge sort)
:
Этот этап повторен для каждого индекса, добавленного
ALTER TABLE
.stage/innodb/alter table (insert)
:
Этот этап повторен для каждого индекса, добавленного
ALTER TABLE
.stage/innodb/alter table (log apply index)
:
Этот этап включает применение журнала DML, произведенного в то время,
как работал ALTER TABLE
.stage/innodb/alter table (flush)
:
Прежде, чем этот этап начинается, WORK_ESTIMATED
обновлен с более точной оценкой, основанной на длине списка.stage/innodb/alter table (log apply table)
:
Этот этап включает применение параллельного журнала DML, произведенного в то
время, как работал ALTER TABLE
. Продолжительность этой фазы зависит от степени табличных изменений. Эта
фаза мгновенна, если никакой параллельный DML не был выполнен на таблице.stage/innodb/alter table (end)
:
Включает любую остающуюся работу, которая появилась после фазы сброса,
например, повторное обращение DML, который был выполнен на таблице в то
время, как работал ALTER TABLE
.События этапа ALTER TABLE
в настоящее время не составляют добавление пространственных индексов.
Следующий пример демонстрирует, как включить инструменты этапа событий
stage/innodb/alter table%
и связанные потребительские таблицы,
чтобы контролировать ход ALTER TABLE
. Для информации об исполнительных инструментах этапа Performance
Schema см. раздел 23.9.5
.
Включите инструменты stage/innodb/alter%
:
mysql> UPDATE setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE 'stage/innodb/alter%'; Query OK, 7 rows affected (0.00 sec) Rows matched: 7 Changed: 7 Warnings: 0
events_stages_current
,
events_stages_history
и
events_stages_history_long
.
mysql> UPDATE setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE '%stages%'; Query OK, 3 rows affected (0.00 sec) Rows matched: 3 Changed: 3 Warnings: 0
ALTER TABLE
.
В этом примере столбец middle_name
добавлен к таблице
базы данных образца.
mysql> ALTER TABLE employees.employees ADD COLUMN middle_name varchar(14) AFTER first_name; Query OK, 0 rows affected (9.27 sec) Records: 0 Duplicates: 0 Warnings: 0
ALTER
TABLE
, запросив Performance Schema
events_stages_current
. Показанный случай этапа отличается в зависимости от текущей фазы
ALTER TABLE
. Столбец
WORK_COMPLETED
показывает завершенную работу.
WORK_ESTIMATED
обеспечивает оценку остающейся работы.
mysql> SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED FROM events_stages_current; +------------------------------------------------------+----------------+----------------+ | EVENT_NAME | WORK_COMPLETED | WORK_ESTIMATED | +------------------------------------------------------+----------------+----------------+ | stage/innodb/alter table (read PK and internal sort) | 280 | 1245 | +------------------------------------------------------+----------------+----------------+ 1 row in set (0.01 sec)
events_stages_current
возвращает пустой набор, если
ALTER TABLE
завершилась. В этом случае Вы можете проверить
events_stages_history
, чтобы смотреть данные событий для завершенной работы. Например:
mysql> SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED FROM events_stages_history; +------------------------------------------------------+----------------+----------------+ | EVENT_NAME | WORK_COMPLETED | WORK_ESTIMATED | +------------------------------------------------------+----------------+----------------+ | stage/innodb/alter table (read PK and internal sort) | 886 | 1213 | | stage/innodb/alter table (flush) | 1213 | 1213 | | stage/innodb/alter table (log apply table) | 1597 | 1597 | | stage/innodb/alter table (end) | 1597 | 1597 | | stage/innodb/alter table (log apply table) | 1981 | 1981 | +------------------------------------------------------+----------------+----------------+ 5 rows in set (0.00 sec)
Как показано выше, WORK_ESTIMATED
было пересмотрено во время
ALTER TABLE
. Предполагаемая работа после завершения начальной
стадии 1213. Когда обработка ALTER TABLE
завершалась,
WORK_ESTIMATED
был установлен в фактическое
значение, которое является 1981.
mutex это механизм синхронизации, используемый в коде, чтобы провести в жизнь правило, что только один поток в установленный срок может иметь доступ к общему ресурсу. Когда два или больше потоков в сервере должны получить доступ к тому же самому ресурсу, потоки конкурируют друг против друга. Первый поток, который получит блокировку на mutex, заставляет другие потоки ждать, пока блокировка не выпущена.
Для InnoDB
mutexes, которые инструментованы, mutex waits
может быть проверен, используя Performance Schema.
Данные событий ожидания, собранные в Performance Schema, могут помочь
идентифицировать mutexes с наибольшим ожиданием или самое большое общее
количество времени ожидания.
Следующий пример демонстрирует, как включить инструменты mutex wait, как включить связанных потребителей и запросить данные событий.
Чтобы видеть доступные инструменты mutex wait, запросите
Performance Schema
setup_instruments
. Все инструменты mutex отключены по умолчанию.
mysql> SELECT * FROM performance_schema.setup_instruments -> WHERE NAME LIKE '%wait/synch/mutex/innodb%'; +---------------------------------------------------------+---------+-------+ | NAME | ENABLED | TIMED | +---------------------------------------------------------+---------+-------+ | wait/synch/mutex/innodb/commit_cond_mutex | NO | NO | | wait/synch/mutex/innodb/innobase_share_mutex | NO | NO | | wait/synch/mutex/innodb/autoinc_mutex | NO | NO | | wait/synch/mutex/innodb/autoinc_persisted_mutex | NO | NO | | wait/synch/mutex/innodb/buf_pool_flush_state_mutex | NO | NO | | wait/synch/mutex/innodb/buf_pool_LRU_list_mutex | NO | NO | | wait/synch/mutex/innodb/buf_pool_free_list_mutex | NO | NO | | wait/synch/mutex/innodb/buf_pool_zip_free_mutex | NO | NO | | wait/synch/mutex/innodb/buf_pool_zip_hash_mutex | NO | NO | | wait/synch/mutex/innodb/buf_pool_zip_mutex | NO | NO | | wait/synch/mutex/innodb/cache_last_read_mutex | NO | NO | | wait/synch/mutex/innodb/dict_foreign_err_mutex | NO | NO | | wait/synch/mutex/innodb/dict_persist_dirty_tables_mutex | NO | NO | | wait/synch/mutex/innodb/dict_sys_mutex | NO | NO | | wait/synch/mutex/innodb/recalc_pool_mutex | NO | NO | | wait/synch/mutex/innodb/fil_system_mutex | NO | NO | | wait/synch/mutex/innodb/flush_list_mutex | NO | NO | | wait/synch/mutex/innodb/fts_bg_threads_mutex | NO | NO | | wait/synch/mutex/innodb/fts_delete_mutex | NO | NO | | wait/synch/mutex/innodb/fts_optimize_mutex | NO | NO | | wait/synch/mutex/innodb/fts_doc_id_mutex | NO | NO | | wait/synch/mutex/innodb/log_flush_order_mutex | NO | NO | | wait/synch/mutex/innodb/hash_table_mutex | NO | NO | | wait/synch/mutex/innodb/ibuf_bitmap_mutex | NO | NO | | wait/synch/mutex/innodb/ibuf_mutex | NO | NO | | wait/synch/mutex/innodb/ibuf_pessimistic_insert_mutex | NO | NO | | wait/synch/mutex/innodb/log_sys_mutex | NO | NO | | wait/synch/mutex/innodb/log_sys_write_mutex | NO | NO | | wait/synch/mutex/innodb/mutex_list_mutex | NO | NO | | wait/synch/mutex/innodb/page_zip_stat_per_index_mutex | NO | NO | | wait/synch/mutex/innodb/purge_sys_pq_mutex | NO | NO | | wait/synch/mutex/innodb/recv_sys_mutex | NO | NO | | wait/synch/mutex/innodb/recv_writer_mutex | NO | NO | | wait/synch/mutex/innodb/redo_rseg_mutex | NO | NO | | wait/synch/mutex/innodb/noredo_rseg_mutex | NO | NO | | wait/synch/mutex/innodb/rw_lock_list_mutex | NO | NO | | wait/synch/mutex/innodb/rw_lock_mutex | NO | NO | | wait/synch/mutex/innodb/srv_dict_tmpfile_mutex | NO | NO | | wait/synch/mutex/innodb/srv_innodb_monitor_mutex | NO | NO | | wait/synch/mutex/innodb/srv_misc_tmpfile_mutex | NO | NO | | wait/synch/mutex/innodb/srv_monitor_file_mutex | NO | NO | | wait/synch/mutex/innodb/buf_dblwr_mutex | NO | NO | | wait/synch/mutex/innodb/trx_undo_mutex | NO | NO | | wait/synch/mutex/innodb/trx_pool_mutex | NO | NO | | wait/synch/mutex/innodb/trx_pool_manager_mutex | NO | NO | | wait/synch/mutex/innodb/srv_sys_mutex | NO | NO | | wait/synch/mutex/innodb/lock_mutex | NO | NO | | wait/synch/mutex/innodb/lock_wait_mutex | NO | NO | | wait/synch/mutex/innodb/trx_mutex | NO | NO | | wait/synch/mutex/innodb/srv_threads_mutex | NO | NO | | wait/synch/mutex/innodb/rtr_active_mutex | NO | NO | | wait/synch/mutex/innodb/rtr_match_mutex | NO | NO | | wait/synch/mutex/innodb/rtr_path_mutex | NO | NO | | wait/synch/mutex/innodb/rtr_ssn_mutex | NO | NO | | wait/synch/mutex/innodb/trx_sys_mutex | NO | NO | | wait/synch/mutex/innodb/zip_pad_mutex | NO | NO | | wait/synch/mutex/innodb/master_key_id_mutex | NO | NO | +---------------------------------------------------------+---------+-------+
performance-schema-instrument
к
конфигурационному файлу MySQL:
performance-schema-instrument='wait/synch/mutex/innodb/%=ON'
Если Вы не требуете событий для всех mutexes,
Вы можете отключить определенные инструменты, добавляя дополнительные
правила performance-schema-instrument
к Вашему конфигурационному
файлу MySQL. Например, чтобы отключить инструменты событий, связанные с
полнотекстовым поиском, добавляют следующее правило:
performance-schema-instrument='wait/synch/mutex/innodb/fts%=OFF'
Правила с более длинным префиксом, например,
wait/synch/mutex/innodb/fts%
имеют приоритет перед правилами с более короткими префиксами, например,
wait/synch/mutex/innodb/%
.
После добавления правил performance-schema-instrument
перезапустите сервер. Все InnoDB
mutexes включены,
за исключением связанных с полнотекстовым поиском. Чтобы проверить, запросите
setup_instruments
. Столбцы ENABLED
и TIMED
должны быть
установлены в YES
для инструментов, которым Вы включали.
mysql> SELECT * FROM performance_schema.setup_instruments -> WHERE NAME LIKE '%wait/synch/mutex/innodb%'; +-------------------------------------------------------+---------+-------+ | NAME | ENABLED | TIMED | +-------------------------------------------------------+---------+-------+ | wait/synch/mutex/innodb/commit_cond_mutex | YES | YES | | wait/synch/mutex/innodb/innobase_share_mutex | YES | YES | | wait/synch/mutex/innodb/autoinc_mutex | YES | YES | ... | wait/synch/mutex/innodb/master_key_id_mutex | YES | YES | +-------------------------------------------------------+---------+-------+ 49 rows in set (0.00 sec)
setup_consumers
.
Потребители событий отключены по умолчанию.
mysql> UPDATE performance_schema.setup_consumers SET enabled = 'YES' -> WHERE name like 'events_waits%'; Query OK, 3 rows affected (0.00 sec) Rows matched: 3 Changed: 3 Warnings: 0
Вы можете проверить, что потребители событий включены, запрашивая
setup_consumers
.
Потребителей
events_waits_current
,
events_waits_history
и
events_waits_history_long
нужно включить.
mysql> SELECT * FROM performance_schema.setup_consumers; +----------------------------------+---------+ | NAME | ENABLED | +----------------------------------+---------+ | events_stages_current | NO | | events_stages_history | NO | | events_stages_history_long | NO | | events_statements_current | YES | | events_statements_history | YES | | events_statements_history_long | NO | | events_transactions_current | YES | | events_transactions_history | YES | | events_transactions_history_long | NO | | events_waits_current | YES | | events_waits_history | YES | | events_waits_history_long | YES | | global_instrumentation | YES | | thread_instrumentation | YES | | statements_digest | YES | +----------------------------------+---------+ 15 rows in set (0.00 sec)
shell> ./mysqlslap --auto-generate-sql --concurrency=100 --iterations=10 -> --number-of-queries=1000 --number-char-cols=6 --number-int-cols=6;
events_waits_summary_global_by_event_name
, которая агрегирует
данные в таблицах
events_waits_current
,
events_waits_history
и
events_waits_history_long
.
Данные получены в итоге именем событий (EVENT_NAME
),
которое является названием инструмента, который произвел случай. Полученные в
итоге данные включают:
COUNT_STAR
Число полученных в итоге событий.
SUM_TIMER_WAIT
Общее количество времени событий.
MIN_TIMER_WAIT
Минимум времени события.
AVG_TIMER_WAIT
Среднее время события.
MAX_TIMER_WAIT
Максимум времени события.
Следующий запрос возвращает инструментальное имя
(EVENT_NAME
), число событий (COUNT_STAR
)
и общее время событий для этого инструмента (SUM_TIMER_WAIT
).
Поскольку время рассчитано в пикосекундах по умолчанию, времена разделены на
1000000000, чтобы показать времена в миллисекундах. Данные представлены в
порядке убывания числа полученных событий (COUNT_STAR
).
Вы можете корректировать ORDER BY
, чтобы упорядочить данные
общим количеством времени ожидания.
mysql> SELECT EVENT_NAME, COUNT_STAR, SUM_TIMER_WAIT/1000000000 SUM_TIMER_WAIT_MS -> FROM performance_schema.events_waits_summary_global_by_event_name -> WHERE SUM_TIMER_WAIT > 0 AND EVENT_NAME -> LIKE 'wait/synch/mutex/innodb/%' ORDER BY COUNT_STAR DESC; +---------------------------------------------------------+------------+-------------------+ | EVENT_NAME | COUNT_STAR | SUM_TIMER_WAIT_MS | +---------------------------------------------------------+------------+-------------------+ | wait/synch/mutex/innodb/trx_mutex | 201111 | 23.4719 | | wait/synch/mutex/innodb/fil_system_mutex | 62244 | 9.6426 | | wait/synch/mutex/innodb/redo_rseg_mutex | 48238 | 3.1135 | | wait/synch/mutex/innodb/log_sys_mutex | 46113 | 2.0434 | | wait/synch/mutex/innodb/trx_sys_mutex | 35134 | 1068.1588 | | wait/synch/mutex/innodb/lock_mutex | 34872 | 1039.2589 | | wait/synch/mutex/innodb/log_sys_write_mutex | 17805 | 1526.0490 | | wait/synch/mutex/innodb/dict_sys_mutex | 14912 | 1606.7348 | | wait/synch/mutex/innodb/trx_undo_mutex | 10634 | 1.1424 | | wait/synch/mutex/innodb/rw_lock_list_mutex | 8538 | 0.1960 | | wait/synch/mutex/innodb/buf_pool_free_list_mutex | 5961 | 0.6473 | | wait/synch/mutex/innodb/trx_pool_mutex | 4885 | 8821.7496 | | wait/synch/mutex/innodb/buf_pool_LRU_list_mutex | 4364 | 0.2077 | | wait/synch/mutex/innodb/innobase_share_mutex | 3212 | 0.2650 | | wait/synch/mutex/innodb/flush_list_mutex | 3178 | 0.2349 | | wait/synch/mutex/innodb/trx_pool_manager_mutex | 2495 | 0.1310 | | wait/synch/mutex/innodb/buf_pool_flush_state_mutex | 1318 | 0.2161 | | wait/synch/mutex/innodb/log_flush_order_mutex | 1250 | 0.0893 | | wait/synch/mutex/innodb/buf_dblwr_mutex | 951 | 0.0918 | | wait/synch/mutex/innodb/recalc_pool_mutex | 670 | 0.0942 | | wait/synch/mutex/innodb/dict_persist_dirty_tables_mutex | 345 | 0.0414 | | wait/synch/mutex/innodb/lock_wait_mutex | 303 | 0.1565 | | wait/synch/mutex/innodb/autoinc_mutex | 196 | 0.0213 | | wait/synch/mutex/innodb/autoinc_persisted_mutex | 196 | 0.0175 | | wait/synch/mutex/innodb/purge_sys_pq_mutex | 117 | 0.0308 | | wait/synch/mutex/innodb/srv_sys_mutex | 94 | 0.0077 | | wait/synch/mutex/innodb/ibuf_mutex | 22 | 0.0086 | | wait/synch/mutex/innodb/recv_sys_mutex | 12 | 0.0008 | | wait/synch/mutex/innodb/srv_innodb_monitor_mutex | 4 | 0.0009 | | wait/synch/mutex/innodb/recv_writer_mutex | 1 | 0.0005 | +---------------------------------------------------------+------------+-------------------+
Предыдущий набор результатов включает данные событий, произведенные во
время процесса запуска. Чтобы исключить эти данные, Вы можете усечь
events_waits_summary_global_by_event_name
немедленно после запуска прежде, чем выполнить Вашу рабочую нагрузку. Однако,
само усекание может произвести незначительное количество данных событий.
mysql> TRUNCATE performance_schema.events_waits_summary_global_by_event_name;
Мониторы InnoDB
предоставляют информацию о внутреннем
состоянии. Эта информация полезна для исполнительной настройки.
Есть два типа мониторов InnoDB
:
Стандартный InnoDB
Monitor
выводит на экран следующие типы информации:
Табличные и блокировки записей каждой активной транзакцией.
InnoDB
Lock Monitor печатает дополнительную информацию о
блокировке как часть InnoDB
Monitor.
Когда Вы включаете мониторы для периодического вывода, InnoDB
пишет их вывод в вывод ошибок сервера
mysqld
(stderr
). В этом случае, никакой вывод не посылают клиентам.
Когда включены, мониторы InnoDB
печатают данные о каждых 15
секундах. Вывод сервера обычно направляется к журналу ошибок (см.
раздел 6.4.2). Эти данные полезны в
исполнительной настройке. В Windows запустите сервер из командной строки в
консоли с опцией --console
, если Вы хотите направить вывод в окно, а не в журнал ошибок.
InnoDB
посылает диагностический вывод в
stderr
или к файлам, а не к stdout
или буферам памяти фиксированного размера, чтобы избежать потенциального
переполнения. Как побочный эффект, вывод
SHOW ENGINE INNODB STATUS
написан в файл состояния в каталоге данных MySQL каждые пятнадцать секунд.
Название файла innodb_status.
, где
pid
pid
ID процесса сервера. InnoDB
удаляет этот файл при нормальном завершении работы. Если неправильные
завершения работы произошли, экземпляры этих файлов состояния могут
присутствовать и должны быть удалены вручную. Прежде, чем удалить их, Вы
могли бы исследовать их, чтобы видеть, содержат ли они полезную информацию о
причине неправильных завершений работы. Файл
innodb_status.
создается только, если включен параметр конфигурации
pid
innodb-status-file=1
.
Мониторы InnoDB
нужно включить только, когда Вы фактически
хотите видеть информацию о мониторе, потому что вывод действительно приводит
к некоторому снижению работоспособности. Кроме того, если Вы включаете вывод
монитора, Ваш журнал ошибок может стать довольно большим, если Вы забываете
отключить это позже.
Чтобы помочь с поиском неисправностей, InnoDB
временно включает стандартный InnoDB
Monitor
определенных условиях. Для получения дополнительной информации см.
раздел 16.20.
Вывод монитора InnoDB
начинается с заголовка, содержащего
метку времени и имя монитора. Например:
===================================== 2014-10-16 18:37:29 0x7fc2a95c1700 INNODB MONITOR OUTPUT =====================================
Заголовок для стандартного InnoDB
Monitor
(INNODB MONITOR OUTPUT
) также используется для монитора
блокировки потому, что последний дает тот же самый вывод с добавлением
дополнительной информации о блокировке.
Системные переменные
innodb_status_output
и
innodb_status_output_locks
используются, чтобы включить
стандартный InnoDB
Monitor и InnoDB
Lock Monitor.
Чтобы включать и отключать мониторы InnoDB
нужна привилегия
PROCESS
.
Включите стандартный InnoDB
Monitor, устанавливая
innodb_status_output
в ON
.
set GLOBAL innodb_status_output=ON;
Отключите стандартнычй InnoDB
Monitor, устанавливая
innodb_status_output
в OFF
.
Когда Вы закрываете сервер,
innodb_status_output
установлена в значение по умолчанию OFF
.
Как альтернатива включению стандартного InnoDB
Monitor
для периодического вывода, Вы можете получить вывод стандартного
InnoDB
Monitor по требованию использованием
SHOW ENGINE INNODB STATUS
,
который приносит вывод Вашей программе клиента. Если Вы используете
mysql, вывод
более читаем, если Вы заменяете обычный разделитель запроса,
точку с запятой, на \G
:
mysql> SHOW ENGINE INNODB STATUS\G
SHOW ENGINE INNODB STATUS
также включает данные InnoDB
Lock Monitor, если он включен.
Данные InnoDB
Lock Monitor напечатаны в вывод стандартного
InnoDB
Monitor. Оба монитора нужно включить.
Чтобы включить InnoDB
Lock Monitor, установите
innodb_status_output_locks
в ON
:
set GLOBAL innodb_status_output=ON; set GLOBAL innodb_status_output_locks=ON;
Когда Вы закрываете сервер, переменные
innodb_status_output
и
innodb_status_output_locks
установлены в значение
по умолчанию OFF
.
Чтобы выключить InnoDB
Lock Monitor, установите
innodb_status_output_locks
в OFF
. Установите
innodb_status_output
в OFF, чтобы также отключить
стандартный InnoDB
Monitor.
Чтобы включить InnoDB
Lock Monitor для
SHOW ENGINE INNODB
STATUS
, Вы только включать обязаны
innodb_status_output_locks
.
Lock Monitor то же самое, как Standard Monitor за исключением того, что он включает дополнительную информацию о блокировке. Включение любого монитора для периодического вывода включает тот же самый выходной поток, но поток включает дополнительную информацию, если включен Lock Monitor. Например, если Вы включаете Standard Monitor и Lock Monitor, это включает единственный выходной поток. Поток включает дополнительную информацию о блокировке, пока Вы не отключаете Lock Monitor.
Вывод Standard Monitor ограничен 1 МБ, когда произведен, используя
SHOW ENGINE INNODB STATUS
.
Этот предел не применяется к выводу, написанному в вывод ошибок сервера.
Пример вывода Standard Monitor:
mysql> SHOW ENGINE INNODB STATUS\G *************************** 1. row *************************** Type: InnoDB Name: Status: ===================================== 2014-10-16 18:37:29 0x7fc2a95c1700 INNODB MONITOR OUTPUT ===================================== Per second averages calculated from the last 20 seconds ----------------- BACKGROUND THREAD ----------------- srv_master_thread loops: 38 srv_active, 0 srv_shutdown, 252 srv_idle srv_master_thread log flush and writes: 290 ---------- SEMAPHORES ---------- OS WAIT ARRAY INFO: reservation count 119 OS WAIT ARRAY INFO: signal count 103 Mutex spin waits 0, rounds 0, OS waits 0 RW-shared spins 38, rounds 76, OS waits 38 RW-excl spins 2, rounds 9383715, OS waits 3 RW-sx spins 0, rounds 0, OS waits 0 Spin rounds per wait: 0.00 mutex, 2.00 RW-shared, 4691857.50 RW-excl, 0.00 RW-sx ------------------------ LATEST FOREIGN KEY ERROR ------------------------ 2014-10-16 18:35:18 0x7fc2a95c1700 Transaction: TRANSACTION 1814, ACTIVE 0 sec inserting mysql tables in use 1, locked 1 4 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 3 MySQL thread id 2, OS thread handle 140474041767680, query id 74 localhost root update INSERT INTO child VALUES (NULL, 1) , (NULL, 2) , (NULL, 3) , (NULL, 4) , (NULL, 5) , (NULL, 6) Foreign key constraint fails for table `mysql`.`child`: , CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`) ON DELETE CASCADE ON UPDATE CASCADE Trying to add in child table, in index par_ind tuple: DATA TUPLE: 2 fields; 0: len 4; hex 80000003; asc ;; 1: len 4; hex 80000003; asc ;; But in parent table `mysql`.`parent`, in index PRIMARY, the closest match we can find is record: PHYSICAL RECORD: n_fields 3; compact format; info bits 0 0: len 4; hex 80000004; asc ;; 1: len 6; hex 00000000070a; asc ;; 2: len 7; hex aa0000011d0134; asc 4;; ------------------------ LATEST DETECTED DEADLOCK ------------------------ 2014-10-16 18:36:30 0x7fc2a95c1700 *** (1) TRANSACTION: TRANSACTION 1824, ACTIVE 9 sec starting index read mysql tables in use 1, locked 1 LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s) MySQL thread id 3, OS thread handle 140474041501440, query id 80 localhost root updating DELETE FROM t WHERE i = 1 *** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 35 page no 3 n bits 72 index GEN_CLUST_INDEX of table `mysql`.`t` trx id 1824 lock_mode X waiting Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0 0: len 6; hex 000000000200; asc ;; 1: len 6; hex 00000000071f; asc ;; 2: len 7; hex b80000012b0110; asc + ;; 3: len 4; hex 80000001; asc ;; *** (2) TRANSACTION: TRANSACTION 1825, ACTIVE 29 sec starting index read mysql tables in use 1, locked 1 4 lock struct(s), heap size 1136, 3 row lock(s) MySQL thread id 2, OS thread handle 140474041767680, query id 81 localhost root updating DELETE FROM t WHERE i = 1 *** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 35 page no 3 n bits 72 index GEN_CLUST_INDEX of table `mysql`.`t` trx id 1825 lock mode S Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 0: len 8; hex 73757072656d756d; asc supremum;; Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0 0: len 6; hex 000000000200; asc ;; 1: len 6; hex 00000000071f; asc ;; 2: len 7; hex b80000012b0110; asc + ;; 3: len 4; hex 80000001; asc ;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 35 page no 3 n bits 72 index GEN_CLUST_INDEX of table `mysql`.`t` trx id 1825 lock_mode X waiting Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 0 0: len 6; hex 000000000200; asc ;; 1: len 6; hex 00000000071f; asc ;; 2: len 7; hex b80000012b0110; asc + ;; 3: len 4; hex 80000001; asc ;; *** WE ROLL BACK TRANSACTION (1) ------------ TRANSACTIONS ------------ Trx id counter 1950 Purge done for trx's n:o < 1933 undo n:o < 0 state: running but idle History list length 23 LIST OF TRANSACTIONS FOR EACH SESSION: ---TRANSACTION 421949033065200, not started 0 lock struct(s), heap size 1136, 0 row lock(s) ---TRANSACTION 421949033064280, not started 0 lock struct(s), heap size 1136, 0 row lock(s) ---TRANSACTION 1949, ACTIVE 0 sec inserting mysql tables in use 1, locked 1 8 lock struct(s), heap size 1136, 1850 row lock(s), undo log entries 17415 MySQL thread id 4, OS thread handle 140474041235200, query id 176 localhost root update INSERT INTO `salaries` VALUES (55723,39746,'1997-02-25','1998-02-25'), (55723,40758,'1998-02-25','1999-02-25'),(55723,44559,'1999-02-25','2000-02-25'), (55723,44081,'2000-02-25','2001-02-24'),(55723,44112,'2001-02-24','2001-08-16'), (55724,46461,'1996-12-06','1997-12-06'),(55724,48916,'1997-12-06','1998-12-06'), (55724,51269,'1998-12-06','1999-12-06'),(55724,51932,'1999-12-06','2000-12-05'), (55724,52617,'2000-12-05','2001-12-05'),(55724,56658,'2001-12-05','9999-01-01'), (55725,40000,'1993-01-30','1994-01-30'),(55725,41472,'1994-01-30','1995-01-30'), (55725,45293,'1995-01-30','1996-01-30'),(55725,473 -------- FILE I/O -------- I/O thread 0 state: waiting for completed aio requests (insert buffer thread) I/O thread 1 state: waiting for completed aio requests (log thread) I/O thread 2 state: waiting for completed aio requests (read thread) I/O thread 3 state: waiting for completed aio requests (read thread) I/O thread 4 state: waiting for completed aio requests (read thread) I/O thread 5 state: waiting for completed aio requests (read thread) I/O thread 6 state: waiting for completed aio requests (write thread) I/O thread 7 state: waiting for completed aio requests (write thread) I/O thread 8 state: waiting for completed aio requests (write thread) I/O thread 9 state: waiting for completed aio requests (write thread) Pending normal aio reads: 0 [0, 0, 0, 0] , aio writes: 0 [0, 0, 0, 0] , ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0 Pending flushes (fsync) log: 0; buffer pool: 0 224 OS file reads, 5770 OS file writes, 803 OS fsyncs 0.00 reads/s, 0 avg bytes/read, 264.84 writes/s, 23.05 fsyncs/s ------------------------------------- INSERT BUFFER AND ADAPTIVE HASH INDEX ------------------------------------- Ibuf: size 1, free list len 0, seg size 2, 0 merges merged operations: insert 0, delete mark 0, delete 0 discarded operations: insert 0, delete mark 0, delete 0 Hash table size 4425293, node heap has 444 buffer(s) 68015.25 hash searches/s, 106259.24 non-hash searches/s --- LOG --- Log sequence number 165913808 Log flushed up to 164814979 Pages flushed up to 141544038 Last checkpoint at 130503656 0 pending log flushes, 0 pending chkp writes 258 log i/o's done, 6.65 log i/o's/second ---------------------- BUFFER POOL AND MEMORY ---------------------- Total large memory allocated 2198863872 Dictionary memory allocated 776332 Buffer pool size 131072 Free buffers 124908 Database pages 5720 Old database pages 2071 Modified db pages 910 Pending reads 0 Pending writes: LRU 0, flush list 0, single page 0 Pages made young 4, not young 0 0.10 youngs/s, 0.00 non-youngs/s Pages read 197, created 5523, written 5060 0.00 reads/s, 190.89 creates/s, 244.94 writes/s Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000 Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s LRU len: 5720, unzip_LRU len: 0 I/O sum[0]:cur[0], unzip sum[0]:cur[0] ---------------------- INDIVIDUAL BUFFER POOL INFO ---------------------- ---BUFFER POOL 0 Buffer pool size 65536 Free buffers 62412 Database pages 2899 Old database pages 1050 Modified db pages 449 Pending reads 0 Pending writes: LRU 0, flush list 0, single page 0 Pages made young 3, not young 0 0.05 youngs/s, 0.00 non-youngs/s Pages read 107, created 2792, written 2586 0.00 reads/s, 92.65 creates/s, 122.89 writes/s Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000 Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s LRU len: 2899, unzip_LRU len: 0 I/O sum[0]:cur[0], unzip sum[0]:cur[0] ---BUFFER POOL 1 Buffer pool size 65536 Free buffers 62496 Database pages 2821 Old database pages 1021 Modified db pages 461 Pending reads 0 Pending writes: LRU 0, flush list 0, single page 0 Pages made young 1, not young 0 0.05 youngs/s, 0.00 non-youngs/s Pages read 90, created 2731, written 2474 0.00 reads/s, 98.25 creates/s, 122.04 writes/s Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000 Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s LRU len: 2821, unzip_LRU len: 0 I/O sum[0]:cur[0], unzip sum[0]:cur[0] -------------- ROW OPERATIONS -------------- 0 queries inside InnoDB, 0 queries in queue 0 read views open inside InnoDB Process ID=35909, Main thread ID=140471692396288, state: sleeping Number of rows inserted 1526363, updated 0, deleted 3, read 11 52671.72 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s ---------------------------- END OF INNODB MONITOR OUTPUT ============================
Для описания каждой метрики, о которой сообщает Standard Monitor см. раздел Metrics в Oracle Enterprise Manager for MySQL Database User's Guide.
Status
Этот раздел показывает timestamp, имя монитора и число секунд, на котором основаны средние числа. Число секунд время, прошедшее между текущим временем и выводом монитора в прошлый раз.
BACKGROUND THREAD
Строки srv_master_thread
показывают работу, сделанную
основным фоновым потоком.
SEMAPHORES
Этот раздел сообщает о потоках, ждущих семафора, и статистику по тому,
сколько раз потоки нуждались в mutex или rw-lock.
Большое количество потоков, ждущих семафоров, может быть результатом
дискового ввода/вывода или проблемами внутри InnoDB
.
Это может произойти из-за тяжелого параллелизма запросов или проблем в
планировании потока операционной системы. Установка
innodb_thread_concurrency
меньше значения по умолчанию, могло бы
помочь в таких ситуациях. Строка Spin rounds per wait
показывает число спин-блокировки на ожидание OS mutex.
Метрики Mutex сообщает
SHOW ENGINE INNODB MUTEX
.
LATEST FOREIGN KEY ERROR
Этот раздел предоставляет информацию о новой ошибке ограничения внешнего ключа. Это не присутствует, если никакая такая ошибка не произошла. Содержание включает запрос, который потерпел неудачу, информацию об ограничении, которое потерпело неудачу и таблицах.
LATEST DETECTED DEADLOCK
Этот раздел предоставляет информацию о новом тупике. Это не присутствует, если никакой тупик не произошел. Показывает, какие транзакции вовлечены, запросы, которые каждая пыталась выполнить, блокировки, которые они имеют и нуждаются, и которая транзакция откатывается, чтобы найти выход из тупика. Режимы блокировки в этом разделе, объяснены в разделе 16.5.1.
TRANSACTIONS
Если этот раздел сообщает об ожидании блокировок, у Ваших приложений могло бы быть утверждение блокировки. Вывод может также помочь проследить причины операционных тупиков.
FILE I/O
Этот раздел предоставляет информацию о потоках, которые
InnoDB
использует, чтобы выполнить различные типы ввода/вывода.
Первые из них посвящены общей обработке InnoDB
.
Содержание также выводит на экран информацию для операций ввода/вывода в
ожидании и статистику для работы ввода/вывода.
Числом этих потоков управляют
innodb_read_io_threads
и
innodb_write_io_threads
. См.
раздел 16.13.
INSERT BUFFER AND ADAPTIVE HASH INDEX
Этот раздел показывает состояние буфер вставки (также называемого буфером изменений) и адаптивный хеш индекса.
LOG
Этот раздел выводит на экран информацию о журнале. Содержание включает
текущий порядковый номер журнала, как давно журнал сброшен на диск и позицию,
в которой InnoDB
последний раз взял контрольную точку. См.
раздел 16.11.3.
Раздел также выводит на экран информацию об ожидании записи и
исполнительную статистику записей.
BUFFER POOL AND MEMORY
Этот раздел дает Вам статистику по чтению и записи страниц. Вы можете вычислить от этих чисел, сколько операций ввода/вывода файла с данными Ваши запросы в настоящее время делают.
Для описаний статистики буферного пула см. раздел 16.6.3.9. Для дополнительной информации о работе буферного пула см. раздел 16.6.3.1.
ROW OPERATIONS
Этот раздел показывает то, что основной поток делает, включая число и исполнительный уровень для каждого типа работы строки.
Ключ к безопасному управлению базой данных это регулярные резервные копии. В зависимости от Вашего объема данных, числа серверов MySQL и рабочей нагрузки базы данных, Вы можете использовать эти методы, один или в комбинации: hot backup с MySQL Enterprise Backup; cold backup, копируя файлы в то время, как сервер MySQL закрыт, физическое резервное копирование для быстрой работы (специально для восстановления), логическое резервное копирование с mysqldump для малых объемов данных или чтобы сделать запись структуры объектов схемы.
mysqlbackup, компонент MySQL Enterprise
Backup, позволяет Вам поддерживать рабочий сервер MySQL, включая таблицы
InnoDB
и
MyISAM
, с минимальными проблемами, производя последовательный
снимок базы данных. Когда mysqlbackup
копирует таблицы InnoDB
, чтения и записи таблиц
InnoDB
и MyISAM
продолжаются.
Во время копирования MyISAM
чтения (но не записи) тех таблиц
разрешены. Резервное копирование MySQL Enterprise может также создать сжатые
резервные файлы и поддержать подмножества таблиц и баз данных. В соединении с
двоичным журналом MySQL, пользователи могут выполнить восстановление момента
времени. Резервное копирование MySQL Enterprise это часть подписки MySQL
Enterprise. Для большего количества деталей см.
раздел 27.2.
Если Вы можете закрыть свой сервер MySQL, Вы можете сделать двоичное
резервное копирование, которое состоит из всех файлов, используемых
InnoDB
. Используйте следующую процедуру:
Сделайте медленное завершение работы сервера MySQL и удостоверьтесь, что он останавливается без ошибок.
InnoDB
(ibdata
и .ibd
) в безопасное место.InnoDB
(ib_logfile
).В дополнение к созданию двоичных резервных копий как только что описано,
регулярно делайте дампы своих таблиц с помощью
mysqldump.
Двоичный файл мог бы быть поврежден незаметно. Выведенные таблицы сохранены в
текстовые файлы, которые удобочитаемы, так табличное повреждение становится
легче найти. Кроме того, потому что формат более прост, шанс серьезного
повреждения данных меньше.
mysqldump также имеет опцию
--single-transaction
для того, чтобы сделать последовательный
снимок без блокировки других клиентов. См.
раздел 8.3.1.
Репликация работает с таблицами InnoDB
, таким образом, Вы можете использовать способности репликации MySQL
сохранить копию Вашей базы данных на серверах базы данных,
требующих высокой доступности.
Чтобы вернуть базу данных к состоянию, в котором было сделано резервное копирование, Вы должны выполнить свой сервер MySQL с включенным двоичным журналированием прежде, чем взять резервное копирование. Чтобы достигнуть восстановления момента времени после восстановления резервного копирования, Вы можете применить изменения от двоичного журнала, которые произошли после того, как резервное копирование было сделано. См. раздел 8.5.
Чтобы оправиться от катастрофического отказа Вашего сервера MySQL,
единственное требование это его перезапустить.
InnoDB
автоматически проверяет журналы и выполняет откат вперёд
базы данных. InnoDB
автоматически откатывает до прежнего уровня
нейтральные транзакции, которые присутствовали во время катастрофического
отказа. Во время восстановления
mysqld выводит что-то вроде этого:
InnoDB: Database was not shut down normally. InnoDB: Starting recovery from log files... InnoDB: Starting log scan based on checkpoint at InnoDB: log sequence number 0 13674004 InnoDB: Doing recovery: scanned up to log sequence number 0 13739520 InnoDB: Doing recovery: scanned up to log sequence number 0 13805056 InnoDB: Doing recovery: scanned up to log sequence number 0 13870592 InnoDB: Doing recovery: scanned up to log sequence number 0 13936128 ... InnoDB: Doing recovery: scanned up to log sequence number 0 20555264 InnoDB: Doing recovery: scanned up to log sequence number 0 20620800 InnoDB: Doing recovery: scanned up to log sequence number 0 20664692 InnoDB: 1 uncommitted transaction(s) which must be rolled back InnoDB: Starting rollback of uncommitted transactions InnoDB: Rolling back trx no 16745 InnoDB: Rolling back of trx no 16745 completed InnoDB: Rollback of uncommitted transactions completed InnoDB: Starting an apply batch of log records to the database... InnoDB: Apply batch completed InnoDB: Started mysqld: ready for connections
Если Ваша база данных становится поврежденной, или дисковый отказ происходит, Вы должны выполнить восстановление, используя резервное копирование. В случае повреждения сначала найдите резервную копию, которая не повреждено. После восстановления основной копии сделайте восстановление момента времени после двоичных файлов системного журнала, используя mysqlbinlog и mysql , чтобы восстановить изменения, которые произошли после того, как резервное копирование было сделано.
В некоторых случаях повреждения базы данных достаточно только вывести,
удалить и обновить одну или несколько поврежденных таблиц. Вы можете
использовать CHECK TABLE
,
чтобы проверить, повреждена ли таблица, хотя
CHECK TABLE
не может обнаружить каждый
возможный вид повреждения.
В некоторых случаях очевидное повреждение страницы базы данных происходит
фактически из-за операционной системы, повреждающей ее собственный кэш файла,
и данные на диске могут быть в норме. Лучше всего попытаться перезапустить
Ваш компьютер. Это может устранить ошибки, которые, казалось, были
повреждением страницы базы данных. Если MySQL все еще испытывает затруднения,
запуска из-за проблемы последовательности InnoDB
, см.
раздел 16.20.2 для шагов,
чтобы запустить случай в диагностическом режиме, где Вы
можете вывести данные.
InnoDB
восстановление катастрофического отказа состоит из нескольких шагов:
Применение журнала redo:
Это первый шаг во время инициализации прежде, чем принять любые соединения.
Если все изменения сброшены из
буферного пула в табличные
пространства (файлы ibdata*
и *.ibd
)
во время завершения работы или катастрофического отказа, применение журнала
redo может быть пропущено. Если файлы системного журнала отсутствуют при
запуске, InnoDB
пропустит этот шаг.
Текущее максимальное значение счетчика auto-increment
записано в журнал redo каждый раз при изменении значения, что делает это
безопасным от катастрофического отказа. Во время восстановления
InnoDB
сканирует журнал, чтобы собрать изменения значений.
См. раздел 16.8.5.
InnoDB
пишет
флаг повреждения в журнал redo, который делает флаг повреждения безопасным от
катастрофического отказа. InnoDB
также пишет данные о флаге
повреждения в памяти механизма на каждой контрольной точке. Во время
восстановления InnoDB
читает флаги повреждения от местоположений
и от результатов слияний прежде, чем отметить таблицу и
индекс как поврежденные.innodb_fast_shutdown
, установленной в 0
или 1
.
Откат до прежнего уровня неполных транзакций: Любые транзакции, которые были активными во время катастрофического отказа или быстрого завершения работы . Время, которое требуется, чтобы удалить неполную транзакцию, может быть в три или четыре раза больше времени, которое транзакция была активной прежде, чем это будет прервано, в зависимости от загрузки сервера.
Вы не можете отменить транзакции, которые находятся в процессе того, чтобы
быть откаченными до прежнего уровня. В крайних случаях, когда откат до
прежнего уровня транзакций, как ожидают, исключительно займет много времени,
может быть быстрее запустить InnoDB
с
innodb_force_recovery
= 3
или выше. См.
раздел 16.20.2.
Шаги не зависят от журнала redo (кроме того, чтобы зарегистрировать запись) и выполнены параллельно с нормальной обработкой. Из них только отмена неполных транзакций является особенной. Буферное слияние вставки и чистка выполнены во время нормальной обработки.
После применения журнала redo InnoDB
пытается
принять соединения как можно раньше, уменьшить время простоя. Как часть
восстановления катастрофического отказа, InnoDB
откатывает любые транзакции, которые не были переданы или в статусе XA
PREPARE
, когда сервер отказал. Отмена выполнена фоновым потоком,
выполненным параллельно с транзакциями от новых соединений. Пока работа
отмены не завершена, новые соединения могут столкнуться с конфликтами
блокировки с восстановленными транзакциями.
В большинстве ситуаций, даже если сервер MySQL был неожиданно уничтожен в
середине тяжелой деятельности, процесс восстановления происходит
автоматически, и никакое действие не требуется. Если отказ аппаратных средств
или серьезная системная ошибка повредили данные InnoDB
, MySQL
мог бы отказаться запуститься. В этом случае см.
раздел 16.20.2.
См. раздел 6.4.4.
Если во время восстановления катастрофического отказа InnoDB
находит журналы redo, записанные после последней контрольной точки, журналы
должны быть применены к затронутым табличным пространствам. Процесс, который
идентифицирует затронутые табличные пространства, упоминается как
открытие табличного пространства.
Открытие табличного пространства идентифицирует затронутые табличные
пространства, использующие на уровне файла записи MLOG_FILE_NAME
журнала redo, которые написаны в журнал, когда страница табличного
пространства изменена. MLOG_FILE_NAME
содержит
space_id
табличного пространства и имя файла.
На запуске InnoDB
открывает системное табличное пространство
и журнал. Если в журнале redo есть записи, начиная с последней контрольной
точки, затронутые файлы табличного пространства открыты и восстановлены,
исходя из записей MLOG_FILE_NAME
.
Записи MLOG_FILE_NAME
внесены для всех постоянных типов
табличного пространства, включая табличные пространства file-per-table,
общее табличное пространство, системное табличное пространство и табличные
пространства журнала отмены.
Если записи MLOG_FILE_NAME
для системного табличного
пространства не соответствуют конфигурации сервера, затрагивающей системные
имена файла с данными табличного пространства, восстановление терпит неудачу
с ошибкой прежде, чем журналы redo применены.
Во время восстановления журнал считан от последней контрольной точки до обнаруженного логического конца журнала. Если файлы табличного пространства, на которые ссылаются в просмотренной части журнала, отсутствуют, запуск не происходит.
Возможно использовать репликацию в случае, где механизм хранения на
ведомом устройстве не тот же самый, как оригинальный механизм хранения на
ведущем устройстве. Например, Вы можете копировать модификации таблиц
InnoDB
ведущего сервера в таблицы MyISAM
на ведомом.
См. раздел 19.1.2.6 и 19.1.2.5.
Чтобы сделать новое ведомое устройство, не снимая ведущее устройство или существующее ведомое устройство, используйте MySQL Enterprise Backup.
Транзакции, которые терпят неудачу на ведущем устройстве, не затрагивают репликацию вообще. Репликация MySQL основана на двоичном журнале, где MySQL пишет запросы SQL, которые изменяют данные. Транзакция, которая терпит неудачу (например, из-за нарушения внешнего ключа или потому что она откатилась до прежнего уровня) не написана в двоичный журнал, таким образом, ее не посылают в ведомые устройства. См. раздел 14.3.1.
Репликация и CASCADE.
Расположенные каскадом действий для InnoDB
на ведущем устройстве копируются на ведомом устройстве
только, если таблицы, совместно использующие отношение
внешнего ключа, используют на ведущем и на ведомом устройствах. Это истина,
используете ли Вы основанную на запросе или на строке репликацию.
Предположите, что Вы запустили репликацию и затем составляете две таблицы на
ведущем устройстве, используя следующий
CREATE TABLE
:
CREATE TABLE fc1 (i INT PRIMARY KEY, j INT) ENGINE = InnoDB; CREATE TABLE fc2 (m INT PRIMARY KEY, n INT, FOREIGN KEY ni (n) REFERENCES fc1 (i) ON DELETE CASCADE) ENGINE = InnoDB;
Предположите, что ведомое устройство не имеет поддержки
InnoDB
. Если это верно, тогда таблицы на ведомом устройстве
составлены, но они используют MyISAM
, опция
FOREIGN KEY
проигнорирована. Теперь мы вставляем некоторые
строки в таблицы на ведущем устройстве:
master> INSERT INTO fc1 VALUES (1, 1), (2, 2); Query OK, 2 rows affected (0.09 sec) Records: 2 Duplicates: 0 Warnings: 0 master> INSERT INTO fc2 VALUES (1, 1), (2, 2), (3, 1); Query OK, 3 rows affected (0.19 sec) Records: 3 Duplicates: 0 Warnings: 0
В этот момент на ведущем и ведомом устройствах таблица
fc1
содержит 2 строки, а fc2
3:
master> SELECT * FROM fc1; +---+---+ | i | j | +---+---+ | 1 | 1 | | 2 | 2 | +---+---+ 2 rows in set (0.00 sec) master> SELECT * FROM fc2; +---+---+ | m | n | +---+---+ | 1 | 1 | | 2 | 2 | | 3 | 1 | +---+---+ 3 rows in set (0.00 sec) slave> SELECT * FROM fc1; +---+---+ | i | j | +---+---+ | 1 | 1 | | 2 | 2 | +---+---+ 2 rows in set (0.00 sec) slave> SELECT * FROM fc2; +---+---+ | m | n | +---+---+ | 1 | 1 | | 2 | 2 | | 3 | 1 | +---+---+ 3 rows in set (0.00 sec)
Теперь предположите, что Вы выполняете следующий запрос
DELETE
на ведущем:
master> DELETE FROM fc1 WHERE i=1; Query OK, 1 row affected (0.09 sec)
Из-за каскада таблица fc2
на ведущем устройстве теперь содержит только 1 строку:
master> SELECT * FROM fc2; +---+---+ | m | n | +---+---+ | 2 | 2 | +---+---+ 1 row in set (0.00 sec)
Однако, каскад не размножается на ведомом устройстве потому, что на
ведомом устройстве DELETE
для
fc1
не удаляет строки из fc2
.
Копия ведомого устройства fc2
все еще содержит все строки,
которые были первоначально вставлены:
slave> SELECT * FROM fc2; +---+---+ | m | n | +---+---+ | 1 | 1 | | 3 | 1 | | 2 | 2 | +---+---+ 3 rows in set (0.00 sec)
Это различие следствие того, что расположеные каскадом удаления обработаны
внутренне InnoDB
, что означает, что ни одно из
изменений не зарегистрировано.
Плагин InnoDB
memcached
(daemon_memcached
) обеспечивает интегрированный демон
memcached, который автоматически хранит и
получает данные от InnoDB
таблицы, превращая сервер MySQL в
быстрое хранилище значений ключа.
Вместо того, чтобы формулировать запросы в SQL, Вы можете использовать
простые операции get
, set
и incr
,
которые избегают работы, связанной с парсингом SQL и построения плана
оптимизации запроса. Вы можете также получить доступ к тем же самым
таблицам InnoDB
через SQL для удобства сложных запросов.
Этот NoSQL-стиль интерфейса использует
memcached API, чтобы ускорить операции базы
данных, позволяя InnoDB
кэширование памяти дескриптора,
используя буферный пул.
Данные, изменные посредством команд memcached,
таких как add
, set
и incr
,
сохранены на диск в таблицы InnoDB
.
Комбинация простоты memcached с
надежностью и последовательностью InnoDB
предоставляют пользователям лучший вариант, как объяснено в
разделе 16.19.1. Для
краткого архитектурного обзора см.
раздел 16.19.2.
Этот раздел способствует пониманию плагина
daemon_memcached
. Комбинация
InnoDB
таблиц и memcached
предлагает значительные преимущества.
Прямой доступ к InnoDB
избегает
парсинга и планирования SQL.
InnoDB
,
не проходя MySQL уровень SQL. Вы можете управлять частотой записи, чтобы
достигнуть более высокой сырой производительности,
обновляя некритические данные.InnoDB
,
не проходя MySQL уровень SQL.InnoDB
.InnoDB
может обработать создание и разложение многократных
значений столбцов в единственное значение
memcached, уменьшая количество строкового
парсинга и связи, требуемой в Вашем приложении. Например, Вы можете сохранить
строковое значение 2|4|6|8
в
memcached, потом
разделить значение, основанное на символе разделителя, и сохраните результат
в четырех числовых столбцах.daemon_memcached
на
главном сервере
в комбинации с репликацией MySQL.Интеграция memcached с MySQL
обеспечивает способ сделать данные в памяти постоянными, таким образом, Вы
можете использовать это для более существенных видов данных. Вы можете
использовать больше add
, incr
и подобных
операций записи в Вашем приложении без беспокойства, что данные могли быть
потеряны. Вы можете остановить и запустить
memcached не теряя обновления, сделанные к
кэшируемым данным. Чтобы принять меры против неожиданных отключений
электричества, Вы можете использовать в своих интересах
восстановление катастрофического отказа, репликацию и резервирование.
AVG()
и MAX()
на данных
memcached.
Все эти операции дороги или сложны при использовании
memcached отдельно.InnoDB
,
Вы не должны волноваться о несвежих данных
memcached или логике отступления, чтобы
запросить базу данных в случае недостающего ключа.Плагин InnoDB
memcached
осуществляет memcached как плагин MySQL, к
которому получает доступ механизм хранения InnoDB
, обходя
MySQL-уровень SQL.
Следующая диаграмма иллюстрирует данные о доступе приложения через
плагин daemon_memcached
по сравнению с SQL.
Особенности плагина daemon_memcached
:
memcached как плагин mysqld. mysqld и memcached выполнены в том же самом пространстве процесса с очень низким временем ожидания доступа к данным.
InnoDB
, обходя анализатор SQL,
оптимизатор и даже уровень API.daemon_memcached
проходит все 55
тестов совместимости memcapable.InnoDB
, разрешая MySQL управлять кэшированием
в памяти, используя буферный пул
. Настройки по умолчанию представляют комбинацию высокой надежности и
наименьшего количества неожиданностей для приложений базы данных. Например,
настройки по умолчанию избегают нейтральных данных на стороне базы данных или
возврата устаревших данных
для memcached get
.InnoDB
.Управление тем, как часто данные передаются через опции
innodb_api_bk_commit_interval
,
daemon_memcached_r_batch_size
и
daemon_memcached_w_batch_size
. Пакетное значение опций размера по
умолчанию 1 для максимальной надежности.
daemon_memcached_option
. Например, Вы можете изменить порт, на
котором слушает memcached,
уменьшить максимальное количество одновременных соединений, изменить
максимальный размер памяти для пары ключа/значения или позволить отладочные
сообщения для журнала ошибок.
innodb_api_trx_level
управляет операционным
уровнем изоляции
запросов, обработанных memcached. Хотя у
memcached нет никакого понятия
транзакций,
Вы можете использовать эту опцию, чтобы управлять, как скоро
memcached видит изменения, вызванные запросами
SQL, сделанными на таблице, используемой плагином
daemon_memcached. По умолчанию
innodb_api_trx_level
=
READ UNCOMMITTED
.
innodb_api_enable_mdl
может использоваться, чтобы заблокировать
таблицу на уровне MySQL, чтобы отображенная таблица не могла быть удалена или
изменена DDL через интерфейс SQL. Без
блокировки таблица может быть исключена из уровня MySQL, но удержана
InnoDB
до тех пор, пока
memcached или некоторый другой пользователь не
прекратит использовать это.Вы можете уже быть знакомы с использованием
memcached с MySQL, см.
раздел 18.2.
Этот раздел описывает как особенности интегрированного плагина
InnoDB
memcached
отличаются от традиционного memcached
.
Установка: библиотека идет с сервером MySQL, делая
установку относительно легкой. Установка вовлекает выполнение скрипта
innodb_memcached_config.sql
, чтобы создать таблицу
demo_test
, чтобы использовать запрос
INSTALL PLUGIN
, чтобы
включить плагин daemon_memcached
и добавить опции
memcached к конфигурационному файлу MySQL.
Вы могли бы все еще установить традиционный
memcached для дополнительных утилит, таких как
memcp, memcat и
memcapable.
Для сравнения с традиционным memcached см. раздел 18.2.1.
daemon_memcached
, однако, вовлекает меньшее число умеренных или
мощных серверов, которые уже выполняют MySQL. Выгода этой конфигурации
в улучшении эффективности отдельных серверов базы данных вместо того, чтобы
эксплуатировать неиспользованную память или распределить поиски через большие
количества серверов. В конфигурации по умолчанию очень небольшая память
используется для memcached, поиски в памяти
поданы от буферного пула,
который автоматически кэширует последние и часто используемые данные. Как
с традиционным случаем сервера MySQL, сохраните значение опции
innodb_buffer_pool_size
столь высоким, как можно (не вызывая
оповещение на уровне OS), чтобы такая большая работа насколько возможно
была выполнена в памяти.innodb_only
), последние данные от таблицы InnoDB
всегда возвращаются, таким образом, опции истечения не имеют никакого
практического эффекта. Если Вы изменяете политику кэширования на
caching
или cache-only
,
работа опций истечения идет как обычно, но запрошенные данные могут быть
несвежими, если обновлены в основной таблице прежде, чем
выдохнутся в кэш-памяти.daemon_memcached
позволяет Вам
использовать подобные соглашения о присвоении имен для ключей, с одним
дополнением. Ключевые имена в формате
@@table_id
.key
.
table_id
расшифрованы, чтобы сослаться на определенную
таблица, используя отображающиеся данные от таблицы
innodb_memcache.containers
. key
ищется в указанной таблице.
Нотация @@
работает на отдельных вызовах
get
, add
и set
,
но не других функций, например, incr
или delete
.
Чтобы определять таблицу значения по умолчанию для последующих действий
memcached в пределах сеанса, выполните
get
, используя нотацию @@
с
, но без ключевой части. Например:
table_id
get @@table_id
Последующие get
, set
,
incr
, delete
и другие операции используют таблицу,
определяемую
в столбце
table_id
innodb_memcache.containers.name
.
innodb_only
, является подходящей для
традиционной конфигурации развертывания, где все данные доступны на всех
серверах, таких как ряд ведомых серверов репликации.
Если Вы физически делите данные, как в конфигурации sharded, Вы можете
разделить данные на несколько машин, работающих с плагином
daemon_memcached
, и использовать традиционный хеширующий
механизм memcached, чтобы направить запросы к
особой машине. На стороне MySQL Вы, как правило, позволяли бы всем данным
быть вставленными запросом add
в
memcached, чтобы соответствующие значения были
сохранены в базе данных по соответствующему серверу.
innodb_only
) memcached
передает информацию таблицам InnoDB
и буферный пул обрабатывает
поиски дескрипторов в памяти вместо роста и сокращения использования памяти
memcached. Относительно маленькая память
используется на стороне memcached.
Если ереключить логику на caching
или
cache-only
, нормальные правила использования памяти
memcached применяются. Память для
значений данных memcached выделена с точки
зрения плит. Вы можете управлять размером плиты и
максимальной памятью, используемой для memcached
.
Так или иначе, Вы можете контролировать и исследовать плагин
daemon_memcached
, используя знакомую систему
статистики,
к которой получают доступ через стандартный протокол, по сеансу
telnet.
Дополнительные утилиты не включены в плагин
daemon_memcached
. Вы можете использовать скрипт
memcached-tool
, чтобы установить полную версию memcached
.
stderr
, опции -v
, -vv
и
-vvv
используются для того, чтобы зарегистрировать вывод
в журнал ошибок MySQL.get
, set
, add
и delete
,
доступны. Преобразование в последовательную форму (то есть, точный строковый
формат, представляющий сложные структуры данных), зависит
от языкового интерфейса.InnoDB
memcached. Интегрированный демон
memcached
улучшает потребительские свойства, и наличие передачи дескриптора данных
между памятью и диском упрощают логику приложения.libmemcached
,
но не дополнительные утилиты командной строки. Чтобы использовать такие
команды, как memcp,
memcat и
memcapable, устанавливают полную версию
memcached. Когда
memrm и memflush
удаляют элементы из кэша, элементы также удалены из основной таблицы.
daemon_memcached
, используя все поддержанные языки:
C и C++,
Java,
Perl,
Python,
PHP и
Ruby.
Определите имя узла сервера и порт как с традиционным
memcached. По умолчанию
daemon_memcached
слушает на порту 11211
.
Вы можете использовать
текст и протоколы двоичной синхронной передачи данных.
Вы можете настроить
логику
of memcached во время выполнения.
Преобразование в последовательную форму (то есть, точный строковый формат,
представляющий сложные структуры данных) зависит от языкового интерфейса.
См. раздел 18.2.5.
Этот раздел описывает, как настроить daemon_memcached
на сервере MySQL. Поскольку memcached
плотно объединен с сервером MySQL, чтобы избежать сетевого трафика и
минимизировать время ожидания, Вы выполняете этот процесс на каждом сервере
MySQL, который использует эту функцию.
Перед установкой плагина, изучите раздел 16.19.5, чтобы понять меры безопасности и предотвратить несанкционированный доступ.
Плагин daemon_memcached
поддержан только на
Linux, Solaris и OS X. Другие операционные системы не поддержаны.
-DWITH_INNODB_MEMCACHED=ON
. Это производит две совместно
используемых библиотеки в каталоге плагина MySQL
(plugin_dir
),
которые нужны для плагина daemon_memcached
:
libmemcached.so
: плагин
memcached для MySQL.
innodb_engine.so
: плагин InnoDB
API для memcached.libevent
должна быть.
Если Вы не создавали MySQL из исходных текстов, библиотека
libevent
не включена в Вашу установку. Используйте метод
установки для своей операционной системы, чтобы установить
libevent
1.4.12 или выше. Например, в зависимости от
операционной системы, Вы могли бы использовать apt-get
,
yum
или port install
. В Ubuntu Linux:
sudo apt-get install libevent-dev
libevent
1.4.12 связана с пакетом и расположена на верхнем
уровне каталога исходного кода MySQL. Если Вы используете связанную версию
libevent
, этого достаточно. Если Вы хотите использовать местную
системную версию libevent
, Вы должны собрать MySQL с
опцией -DWITH_LIBEVENT
, установленной в значение
system
или yes
.Сконфигурируйте плагин daemon_memcached
таким образом, что это может взаимодействовать с таблицами
InnoDB
. Запустите скрипт
innodb_memcached_config.sql
в
. Скрипт установит
базу жанных MYSQL_HOME
/shareinnodb_memcache
с тремя необходимыми таблицами
(cache_policies
, config_options
и
containers
). Это также устанавливает типовую таблицу
demo_test
в базу данных test
.
mysql> source MYSQL_HOME
/share/innodb_memcached_config.sql
Запуск скрипта innodb_memcached_config.sql
это
одноразовая работа. Таблицы остаются в указанном месте, если Вы позже
удаляете и повторно устанавливаете плагин daemon_memcached
.
mysql> USE innodb_memcache; mysql> SHOW TABLES; +---------------------------+ | Tables_in_innodb_memcache | +---------------------------+ | cache_policies | | config_options | | containers | +---------------------------+ mysql> USE test; mysql> SHOW TABLES; +----------------+ | Tables_in_test | +----------------+ | demo_test | +----------------+
Из этих таблиц innodb_memcache.containers
является самой важной. Записи в containers
обеспечивают отображение на столбцы таблицы InnoDB
. Каждая
таблица InnoDB
, используемая с daemon_memcached
,
требует записи в containers
.
Скрипт innodb_memcached_config.sql
вставляет единственную
запись в containers
, которая обеспечивает отображение для
таблицы demo_test
. Это также вставляет единственную строку
данных в demo_test
. Эти данные позволяют Вам немедленно
проверить установку после того, как она завершена.
mysql> SELECT * FROM innodb_memcache.containers\G *************************** 1. row *************************** name: aaa db_schema: test db_table: demo_test key_columns: c1 value_columns: c2 flags: c3 cas_column: c4 expire_time_column: c5 unique_idx_name_on_key: PRIMARY mysql> SELECT * FROM test.demo_test; +----+------------------+------+------+------+ | c1 | c2 | c3 | c4 | c5 | +----+------------------+------+------+------+ | AA | HELLO, HELLO | 8 | 0 | 0 | +----+------------------+------+------+------+
Подробнее про таблицы innodb_memcache
и
demo_test
см.
раздел 16.19.8.
daemon_memcached
командой
INSTALL PLUGIN
:
mysql> INSTALL PLUGIN daemon_memcached soname "libmemcached.so";
Как только плагин установлен, он автоматически активирован каждый раз, когда сервер MySQL перезапущен.
Чтобы проверить плагин daemon_memcached
,
используйте сеанс telnet, чтобы выпустить
команды memcached. По умолчанию
memcached слушает порт 11211.
Получите данные от таблицы test.demo_test
.
Единственная строка данных в demo_test
имеет ключ
AA
.
telnet localhost 11211 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. get AA VALUE AA 8 12 HELLO, HELLO END
set
.
set BB 10 0 16 GOODBYE, GOODBYE STORED
здесь:
set
команда, чтобы сохранить значение.
BB
ключ.10
флаг для работы, проигнорирован
memcached, но может использоваться клиентом,
чтобы указать на любой тип информации, определите 0
,
если не использован.0
время истечения срока (TTL), определите 0
,
если не использован.16
длина поставляемого блока значения в байтах.GOODBYE, GOODBYE
значение, которое сохранено.
Проверьте, что вставленные данные хранятся в MySQL, соединяясь с
сервером MySQL и запрашивая таблицу test.demo_test
.
mysql> SELECT * FROM test.demo_test; +----+------------------+----+----+----+ | c1 | c2 | c3 | c4 | c5 | +----+------------------+----+----+----+ | AA | HELLO, HELLO | 8 | 0 | 0 | | BB | GOODBYE, GOODBYE | 10 | 1 | 0 | +----+------------------+----+----+----+
BB
.
get BB VALUE BB 10 16 GOODBYE, GOODBYE END quit
Если Вы закроете сервер MySQL, который также отключает интегрированный сервер memcached, то дальнейшие попытки получить доступ к memcached потерпят неудачу с ошибкой соединения. Обычно данные memcached также исчезают, и Вы потребовали бы, чтобы логика приложения загрузила данные назад в память, когда memcached перезапущен. Однако, плагин memcached автоматизирует этот процесс для Вас.
Когда Вы перезапускаете MySQL, операции get
возвращают пары ключа/значения, которые Вы сохранили ранее в сессии
memcached. Когда ключ требуют, и связанное
значение уже не находится в кэш-памяти, значение автоматически запрошено от
MySQL-таблицы test.demo_test
.
Этот пример показывает как установить таблицу с
плагином daemon_memcached
.
Создайте таблицу InnoDB
.
У таблицы должен быть ключевой столбец с уникальным индексом. Ключевой
столбец таблицы city_id
определен как первичный ключ. Таблица
должна также включать столбцы для значений flags
,
cas
и expiry
. Могут быть один или более столбцов
значений. Таблица city
имеет три столбца значений
(name
, state
, country
).
Нет никакого особого требования относительно имен столбцов, поскольку
допустимое отображение добавлено к таблице
innodb_memcache.containers
.
mysql> CREATE TABLE city (city_id VARCHAR(32), name VARCHAR(1024), -> state VARCHAR(1024), country VARCHAR(1024), -> flags INT, cas BIGINT UNSIGNED, expiry INT, -> primary key(city_id)) ENGINE=InnoDB;
innodb_memcache.containers
, чтобы
плагин daemon_memcached
знал, как получить доступ
к таблице InnoDB
. Запись должна удовлетворить
определению innodb_memcache.containers
. Для описания каждого
поля см. раздел 16.19.8.
mysql> DESCRIBE innodb_memcache.containers; +------------------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------------------+--------------+------+-----+---------+-------+ | name | varchar(50) | NO | PRI | NULL | | | db_schema | varchar(250) | NO | | NULL | | | db_table | varchar(250) | NO | | NULL | | | key_columns | varchar(250) | NO | | NULL | | | value_columns | varchar(250) | YES | | NULL | | | flags | varchar(250) | NO | | 0 | | | cas_column | varchar(250) | YES | | NULL | | | expire_time_column | varchar(250) | YES | | NULL | | | unique_idx_name_on_key | varchar(250) | NO | | NULL | | +------------------------+--------------+------+-----+---------+-------+
Запись в таблице innodb_memcache.containers
для таблицы определена как:
mysql> INSERT INTO `innodb_memcache`.`containers` ( -> `name`, `db_schema`, `db_table`, `key_columns`, `value_columns`, -> `flags`, `cas_column`, `expire_time_column`, `unique_idx_name_on_key`) -> VALUES ('default', 'test', 'city', 'city_id', 'name|state|country', -> 'flags','cas','expiry','PRIMARY');
default
определен для столбца
containers.name
, чтобы сконфигурировать таблицу
city
как таблицу InnoDB
по умолчанию,
которая будет использоваться с daemon_memcached
.
InnoDB
(name
, state
, country
)
отображены на containers.value_columns
с помощью разделителя
|.flags
, cas_column
и
expire_time_column
таблицы
innodb_memcache.containers
являются, как правило, не
существенными в приложениях, используя daemon_memcached
.
Однако, определяемый столбец таблицы InnoDB
требуется для каждого. Вставляя данные, определите 0
для этих столбцов, если они не использованы.После обновления innodb_memcache.containers
перезапустите daemon_memcache
, чтобы применить изменения.
mysql> UNINSTALL PLUGIN daemon_memcached; mysql> INSTALL PLUGIN daemon_memcached soname "libmemcached.so";
city
,
используя команду set
.
telnet localhost 11211 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. set B 0 0 22 BANGALORE|BANGALORE|IN STORED
test.city
, чтобы проверить, что
данные, которые Вы вставили, были сохранены.
mysql> SELECT * FROM test.city; +---------+-----------+-----------+---------+-------+-----+--------+ | city_id | name | state | country | flags | cas | expiry | +---------+-----------+-----------+---------+-------+-----+--------+ | B | BANGALORE | BANGALORE | IN | 0 | 3 | 0 | +---------+-----------+-----------+---------+-------+-----+--------+
test.city
.
mysql> INSERT INTO city VALUES ('C','CHENNAI','TAMIL NADU','IN', 0, 0 ,0); mysql> INSERT INTO city VALUES ('D','DELHI','DELHI','IN', 0, 0, 0); mysql> INSERT INTO city VALUES ('H','HYDERABAD','TELANGANA','IN', 0, 0, 0); mysql> INSERT INTO city VALUES ('M','MUMBAI','MAHARASHTRA','IN', 0, 0, 0);
Рекомендуется, чтобы Вы определили значение
0
для полей flags
, cas_column
и
expire_time_column
, если они не использованы.
Используя telnet, выполните команду
memcached get
,
чтобы получить данные, которые Вы вставили с использованием MySQL.
get H VALUE H 0 22 HYDERABAD|TELANGANA|IN END
Традиционные параметры конфигурации memcached
могут быть определены в конфигурационном файле MySQL или стартовой строке
mysqld,
закодированной в параметре
daemon_memcached_option
. Параметры конфигурации
memcached
вступают в силу, когда плагин загружен, что происходит
каждый раз, когда сервер MySQL запущен.
Например, чтобы заставить memcached
слушать на порту 11222 вместо порта значения по умолчанию 11211, определите
-p11222
как параметр
daemon_memcached_option
:
mysqld .... --daemon_memcached_option="-p11222"
Другие опции memcached могут быть
закодированы в
daemon_memcached_option
. Например, Вы можете определить опции,
чтобы уменьшить максимальное количество одновременных соединений, изменить
максимальный размер памяти для пары ключа/значения или включить отладочные
сообщения для журнала ошибок.
Есть также параметры конфигурации, определенные для
плагина daemon_memcached
:
daemon_memcached_engine_lib_name
:
Определяет совместно используемую библиотеку, которая осуществляет плагин
memcached. Настройка по умолчанию
innodb_engine.so
.
daemon_memcached_engine_lib_path
:
Путь каталога, содержащего совместно используемую библиотеку, которая
осуществляет плагин memcached. Настройка по
умолчанию NULL, представляя каталог плагинов.
daemon_memcached_r_batch_size
: Определяет размер пакета передачи
для операций чтения (get
). Это определяет число операций чтения
memcached после которых происходит
commit.
daemon_memcached_r_batch_size
установлен в 1 по умолчанию так,
чтобы каждый get
запрашивал доступ к последним переданным данным
в таблице InnoDB
, были ли данные обновлены через
memcached или SQL. Когда значение больше 1,
счетчик для операций чтения постепенно увеличен с каждым вызовом
get
. Вызов flush_all
сбросит
счетчики чтения и записи.
daemon_memcached_w_batch_size
: Определяет размер пакета передачи
для операций записи (set
, replace
,
append
, prepend
,
incr
, decr
и т.п.).
daemon_memcached_w_batch_size
установлен в 1 по умолчанию, чтобы
никакие нейтральные данные не были потеряны в случае отключения
электричества, а запросы SQL на основной таблице получили доступ к новым
данным. Когда значение больше 1, счетчик постепенно увеличен для каждой
операции. Вызов flush_all
сбросит счетчики чтения и записи.
По умолчанию, Вы не должны изменить
daemon_memcached_engine_lib_name
или
daemon_memcached_engine_lib_path
. Вы могли бы сконфигурировать эти
опции, если, например, Вы хотите использовать иной механизм хранения для
memcached (например, NDB
memcached).
Параметры плагина daemon_memcached
могут быть определены в конфигурационном файле MySQL или в строке запуска
mysqld.
Они вступают в силу, когда Вы загружаете daemon_memcached
.
Производя изменения в настройке daemon_memcached
,
перезагрузите плагин, чтобы применить изменения. Чтобы сделать так,
сделайте следующие запросы:
mysql> UNINSTALL PLUGIN daemon_memcached; mysql> INSTALL PLUGIN daemon_memcached soname "libmemcached.so";
Настройки конфигурации, требуемые таблицы и данные сохранены, когда плагин перезапущен.
Подробности о плагинах см. в разделе 6.6.2.
С MySQL 8.0.0 плагин daemon_memcached
поддерживает
множественные операции get (забирающие многократные пары
ключа/значения в единственном запросе memcached
) и запросах диапазона.
Способность забрать многократные пары ключа/значения в единственном
запросе memcached
улучшает работу чтения, уменьшая коммуникационный трафик между клиентом и
сервером. Для InnoDB
это означает меньше транзакций и
операций открытия таблицы.
Следующий пример демонстрирует это. Пример использует таблицу
test.city
, описанную
выше.
mysql> USE test; mysql> SELECT * FROM test.city; +---------+-----------+-------------+---------+-------+-----+--------+ | city_id | name | state | country | flags | cas | expiry | +---------+-----------+-------------+---------+-------+-----+--------+ | B | BANGALORE | BANGALORE | IN | 0 | 1 | 0 | | C | CHENNAI | TAMIL NADU | IN | 0 | 0 | 0 | | D | DELHI | DELHI | IN | 0 | 0 | 0 | | H | HYDERABAD | TELANGANA | IN | 0 | 0 | 0 | | M | MUMBAI | MAHARASHTRA | IN | 0 | 0 | 0 | +---------+-----------+-------------+---------+-------+-----+--------+
Выполните команду get
, чтобы получить все значения от
таблицы city
. Результаты возвращены в последовательности
пар ключа/значения.
telnet 127.0.0.1 11211 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. get B C D H M VALUE B 0 22 BANGALORE|BANGALORE|IN VALUE C 0 21 CHENNAI|TAMIL NADU|IN VALUE D 0 14 DELHI|DELHI|IN VALUE H 0 22 HYDERABAD|TELANGANA|IN VALUE M 0 21 MUMBAI|MAHARASHTRA|IN END
Получая многократные значения в одной команде get
,
Вы можете переключить таблицы (с использованием формата
@@
),
чтобы получить значение для первого ключа, но Вы не можете переключить
таблицы для последующих ключей. Например, табличный переключатель в
этом примере допустим:
containers.name
get @@aaa.AA BB VALUE @@aaa.AA 8 12 HELLO, HELLO VALUE BB 10 16 GOODBYE, GOODBYE END
Попытка переключить таблицы снова в том же самом запросе get
,
чтобы получить значение ключа от другой таблицы не поддержана.
Для запросов диапазона плагин daemon_memcached
поддерживает следующие операторы сравнения:
<
, >
, <=
, >=
.
Оператор должен предваряться символом @
.
Когда запрос диапазона находит многократные соответствия пар ключа/значения,
результаты возвращены в последовательности пар ключа/значения.
Следующие примеры демонстрируют поддержку запроса диапазона. Примеры
используют описанную ранее таблицу test.city
.
mysql> SELECT * FROM test.city; +---------+-----------+-------------+---------+-------+-----+--------+ | city_id | name | state | country | flags | cas | expiry | +---------+-----------+-------------+---------+-------+-----+--------+ | B | BANGALORE | BANGALORE | IN | 0 | 1 | 0 | | C | CHENNAI | TAMIL NADU | IN | 0 | 0 | 0 | | D | DELHI | DELHI | IN | 0 | 0 | 0 | | H | HYDERABAD | TELANGANA | IN | 0 | 0 | 0 | | M | MUMBAI | MAHARASHTRA | IN | 0 | 0 | 0 | +---------+-----------+-------------+---------+-------+-----+--------+
Откройте сессию telnet:
telnet 127.0.0.1 11211 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'.
Получить все значения, больше B
:
get @>B VALUE C 0 21 CHENNAI|TAMIL NADU|IN VALUE D 0 14 DELHI|DELHI|IN VALUE H 0 22 HYDERABAD|TELANGANA|IN VALUE M 0 21 MUMBAI|MAHARASHTRA|IN END
Получить все значения меньше M
:
get @<M VALUE B 0 22 BANGALORE|BANGALORE|IN VALUE C 0 21 CHENNAI|TAMIL NADU|IN VALUE D 0 14 DELHI|DELHI|IN VALUE H 0 22 HYDERABAD|TELANGANA|IN END
Получить все значения меньше чем и включая M
:
get @<=M VALUE B 0 22 BANGALORE|BANGALORE|IN VALUE C 0 21 CHENNAI|TAMIL NADU|IN VALUE D 0 14 DELHI|DELHI|IN VALUE H 0 22 HYDERABAD|TELANGANA|IN VALUE M 0 21 MUMBAI|MAHARASHTRA|IN
Получить значения, больше чем B
но меньше M
:
get @>B@<M VALUE C 0 21 CHENNAI|TAMIL NADU|IN VALUE D 0 14 DELHI|DELHI|IN VALUE H 0 22 HYDERABAD|TELANGANA|IN END
Максимум двух операторов сравнения может быть разобран, один являющийся
любым 'меньше чем' (@<
) или 'меньше чем или равный'
(@<=
), другой являющийся любым 'больше чем'
(@>
) или или 'больше чем или равный' (@>=
).
Любые дополнительные операторы, как предполагается, являются частью ключа.
Например, если выполняете get
с тремя операторами, третий
оператор (@>C
) обработан как часть ключа, и get
будет искать значения, меньшие чем M
, но больше
B@>C
.
get @<M@>B@>C VALUE C 0 21 CHENNAI|TAMIL NADU|IN VALUE D 0 14 DELHI|DELHI|IN VALUE H 0 22 HYDERABAD|TELANGANA|IN
Консультируйтесь с этим разделом прежде, чем развернуть
daemon_memcached
на производственном сервере или даже на
тестовом сервере, если MySQL содержит уязвимые данные.
Поскольку memcached
не использует механизм аутентификации по умолчанию, и дополнительная
аутентификация SASL не столь же сильна, как традиционная безопасность системы
управления базами данных, сохраните только несекретные данные в случае MySQL,
который использует daemon_memcached
, и отгородите любые серверы,
которые используют эту конфигурацию, от потенциальных злоумышленников. Не
позволяйте доступ к этим серверам из Интернета,
позвольте доступ только изнутри интранет-сети, идеально от подсети, членство
в которой Вы можете ограничить.
Поддержка SASL обеспечивает способность защитить Вашу базу данных MySQL от
незаверенного доступа к memcached.
Этот раздел объясняет, как включить SASL с daemon_memcached
.
Шаги почти идентичны включению SASL для традиционного
memcached.
SASL это стандарт для того, чтобы добавить поддержку аутентификации основанным на соединении протоколам. memcached добавил поддержку SASL в версии 1.4.3.
Аутентификация SASL поддержана только с протоколом двоичной синхронной передачи данных.
Клиенты memcached в состоянии только
получить доступ к таблицам, которые зарегистрированы в
innodb_memcache.containers
.
Даже при том, что DBA может установить ограничения доступа для таких таблиц,
доступом через memcached нельзя управлять.
Поэтому поддержка SASL оказана, чтобы управлять доступом к
таблицам, связанным с daemon_memcached
.
Этот раздел показхывает, как создать, включить и проверить
SASL daemon_memcached
.
По умолчанию SASL daemon_memcached
не включен в пакеты
выпуска MySQL. SASL-daemon_memcached
требует
сборки memcached с библиотеками SASL.
Чтобы включить поддержку SASL, загрузите исходный текст MySQL и пересоздайте
плагин daemon_memcached
после загрузки библиотек SASL:
Установите SASL и служебные библиотеки. Например, на Ubuntu используйте apt-get:
sudo apt-get -f install libsasl2-2 sasl2-bin libsasl2-2 libsasl2-dev libsasl2-modules
ENABLE_MEMCACHED_SASL=1
к опциям
cmake. memcached
также оказывает simple cleartext password support,
которая облегчает тестирование. Чтобы включить простую поддержку пароля
открытого текста, определите ENABLE_MEMCACHED_SASL_PWDB=1
в
cmake.
В резюме, добавьте следующие три опции cmake:
cmake ... -DWITH_INNODB_MEMCACHED=1 \ -DENABLE_MEMCACHED_SASL=1 \ -DENABLE_MEMCACHED_SASL_PWDB=1
daemon_memcached
согласно
разделу 16.19.3.В файле создайте пользователя testname
и определите пароль как testpasswd
:
echo "testname:testpasswd:::::::" >/home/jy/memcached-sasl-db
MEMCACHED_SASL_PWDB
, чтобы
сообщить memcached
имя файла пользователей и паролей:
export MEMCACHED_SASL_PWDB=/home/jy/memcached-sasl-db
memcached
, что используется
пароль открытого текста:
echo "mech_list: plain" > /home/jy/work2/msasl/clients/memcached.conf export SASL_CONF_PATH=/home/jy/work2/msasl/clients
Включите SASL, перезапуская сервер MySQL с опцией
memcached -S
, закодированной в
параметре конфигурации
daemon_memcached_option
:
mysqld ... --daemon_memcached_option="-S"
memcp --servers=localhost:11211 --binary --username=testname --password=testpasswd myfile.txt memcat --servers=localhost:11211 --binary --username=testname --password=testpasswd myfile.txt
Если Вы определяете неправильное имя пользователя или пароль, работа
отклонена с ошибкой memcache error AUTHENTICATION FAILURE
.
В этом случае исследуйте пароль открытого текста в файле
memcached-sasl-db
, чтобы проверить, что он правилен.
Есть другие методы, чтобы проверить аутентификацию SASL с memcached, но метод, описанный выше, является самым прямым.
Написание приложений для плагина
InnoDB
memcached
вовлекает определенную степень приспосабливания существующего кода, который
использует MySQL или memcached API.
С плагином daemon_memcached
вместо многих
традиционных серверов memcached, работающих на
маломощных машинах, у Вас будет то же самое число серверов
memcached, как серверов MySQL,
работающих на относительно мощных машинах с существенным диском и памятью. Вы
могли бы снова использовать некоторый существующий код, который работает с
memcached API, но адаптация, вероятно,
требуется из-за различной конфигурации сервера.
daemon_memcached
,
в столбцы VARCHAR
,
TEXT
или
BLOB
, должны быть преобразованы,
чтобы сделать числовые операции. Вы можете выполнить преобразование на
стороне приложения или при использовании CAST()
в запросах.InnoDB
memcached.
Исполнительное улучшение для записи, как правило, больше, чем для чтений,
таким образом, Вы могли бы сосредоточиться на том, чтобы приспосабливать код,
который выполняет журналирование или делает запись интерактивного выбора
на веб-сайте.Следующие разделы исследуют эти пункты более подробно.
Полагайте, что эти аспекты memcached,
адаптируя существующую схему MySQL или приложение используют
плагин daemon_memcached
:
Ключи memcached
не могут содержать пробелы или новые строки, потому что эти символы
используются в качестве разделителей в протоколе ASCII. Если Вы используете
значения, которые содержат пробелы, преобразуйте или хешируйте их в значения
без пробелов перед использованием их как ключи в add()
,
set()
, get()
и т.п.
Хотя теоретически эти символы позволены в ключах в программах, которые
используют протокол двоичной синхронной передачи данных, Вы должны ограничить
символы, используемые в ключах, чтобы гарантировать совместимость с
широким диапазоном клиентов.
InnoDB
, используйте это в качестве уникального ключа поиска для
memcached,
преобразовывая целое число в строковое значение. Если
сервер memcached используется для многих
приложений, или больше, чем с одной таблицей InnoDB
,
полагайте, что изменение имени гарантирует, что это уникально. Например,
предварительно ожидайте имя таблицы или имя базы данных и имя таблицы
перед числовым значением.
Плагин daemon_memcached
поддерживает вставляют и чтение на отображенных таблицах
InnoDB
, которые имеют INTEGER
,
определенный как первичный ключ.
Вы не можете использовать разделенную таблицу с использованием memcached.
InnoDB
, чтобы осуществить счетчики, которые могут использоваться
в функциях SQL, например, SUM()
или AVG()
, надо:
Используйте столбцы VARCHAR
со многими символами, чтобы сохранить все цифры самого большого
ожидаемого числа (и дополнительные символы, если надо для знака минус,
десятичной запятой или обоих).
CAST()
, чтобы преобразовать значения от
строки до целого числа, или к некоторому другому числовому типу. Например:
-- Alphabetic entries are returned as zero. select cast(c2 as unsigned integer) from demo_test; -- Since there could be numeric values of 0, can't disqualify them. -- Test the string values to find the ones that are integers, and average only those. select avg(cast(c2 as unsigned integer)) from demo_test where c2 between '0' and '9999999999'; -- Views let you hide the complexity of queries. The results are already converted; -- no need to repeat conversion functions and WHERE clauses each time. create view numbers as select c1 key, cast(c2 as unsigned integer) val from demo_test where c2 between '0' and '9999999999'; select sum(val) from numbers;
Любые алфавитные значения в наборе результатов преобразованы в 0
вызовом CAST()
. Используя функции вроде AVG()
,
которые зависят от числа строк в наборе результатов, включают
WHERE
, чтобы отфильтровать нечисловые значения.
Если столбец, используемый в качестве ключа, может иметь значения больше 250 байт, надо хешировать значение меньше, чем к 250 байтам.
daemon_memcached
, определите запись для этого в
innodb_memcache.containers
.
Чтобы сделать эту таблицу значением по умолчанию для всех запросов
memcached, определите значение
default
в столбце name
, затем перезапустите сервер
MySQL, чтобы изменения вступили в силу. Если Вы используете многократные
таблицы для различных классов данных
memcached, настройте много записей в
innodb_memcache.containers
с подходящим значением
name
, затем выпустите запрос
memcached в форме
get @@name
или
set @@name
в пределах приложения, чтобы
определить таблицу, которая будет использоваться для
последующих запросов memcached.
Для примера использования таблицы кроме предопределенной
test.demo_test
см.
пример 16.22.
Для необходимого табличного расположения см.
раздел 16.19.8.
value_columns
записи innodb_memcache.containers
для таблицы InnoDB
. Например, определите
col1,col2,col3
или col1|col2|col3
в
поле value_columns
.
Свяжите значения столбцов в единственную строку, используя символ канала в
качестве разделителя прежде, чем передать строку функциям
memcached add
или
set
. Строка распакована автоматически в правильный столбец.
Каждый вызов get
возвращает единственную строку, содержащую
значения столбцов, которые также разграничены символом канала. Вы можете
распаковать значения, используя соответствующий
языковой синтаксис приложения.
Пример 16.22. Использование Вашей собственной таблицы с InnoDB memcached
Этот пример показывает, как использовать Вашу собственную таблицу с
типовым приложением на Python, которое использует memcached
.
Пример предполагает что плагин daemon_memcached
уставновлен в
соответствии с разделом 16.19.3
. Это также предполагает, что Ваша система сконфигурирована, чтобы
выполнить скрипт модуля python-memcache
.
Создайте таблицу multicol
, которая хранит
информацию страны включая население, область и данные о водительской стороне
('R'
для правой и 'L'
для левой).
mysql> USE test; mysql> CREATE TABLE `multicol` ( -> `country` varchar(128) NOT NULL DEFAULT '', -> `population` varchar(10) DEFAULT NULL, -> `area_sq_km` varchar(9) DEFAULT NULL, -> `drive_side` varchar(1) DEFAULT NULL, -> `c3` int(11) DEFAULT NULL, -> `c4` bigint(20) unsigned DEFAULT NULL, -> `c5` int(11) DEFAULT NULL, -> PRIMARY KEY (`country`)) ENGINE=InnoDB -> DEFAULT CHARSET=latin1;
innodb_memcache.containers
так, чтобы
плагин daemon_memcached
мог получить доступ к multicol
.
mysql> INSERT INTO innodb_memcache.containers -> (name,db_schema,db_table,key_columns,value_columns,flags, -> cas_column,expire_time_column,unique_idx_name_on_key) -> VALUES -> ('bbb','test','multicol','country', -> 'population,area_sq_km,drive_side','c3','c4','c5','PRIMARY'); mysql> COMMIT;
Запись в innodb_memcache.containers
для
multicol
определяет для name
значение
'bbb'
, которое является табличным идентификатором.
Если одна таблица InnoDB
используется для всех
приложений, name
может быть установлено в default
,
чтобы избежать использования @@
, чтобы переключить таблицы.
Столбец db_schema
установлен в test
,
название базы данных, где находится таблица multicol
.
db_table
установлен в multicol
,
имя таблицы InnoDB
.key_columns
установлен в уникальный столбец
country
. Столбец country
определен как
первичный ключ в multicol
.InnoDB
, чтобы держать сложное
значение, данные разделены среди трех столбцов таблицы
(population
, area_sq_km
и drive_side
).
Чтобы приспособить много столбцов значений, список разделенных запятой
значений столбцов определен в поле value_columns
.
Столбцы, определенные в value_columns
это столбцы, используемые,
храня или получая значения.flags
, expire_time
и
cas_column
основаны на значениях, используемых в таблице
demo.test
. Эти поля являются, как правило, не существенными в
приложениях, которые используют daemon_memcached
,
потому что MySQL сохраняет данные синхронизированными, и нет никакой
потребности волноваться об истечении данных или несвежем статусе.unique_idx_name_on_key
установлено в
PRIMARY
, что ссылается на первичный индекс, определенный на
уникальном столбце country
таблицы multicol
.
Скопируйте типовое приложение Питона в файл. В этом примере типовой
скрипт скопирован к файлу multicol.py
.
Типовое приложение Питона вставляет данные в таблицу
multicol
и получает данные для всех ключей, демонстрируя, как
получить доступ к таблице InnoDB
через
плагин daemon_memcached
.
import sys, os import memcache def connect_to_memcached(): memc = memcache.Client(['127.0.0.1:11211'], debug=0); print "Connected to memcached." return memc def banner(message): print print "=" * len(message) print message print "=" * len(message) country_data = [("Canada","34820000","9984670","R"), ("USA","314242000","9826675","R"), ("Ireland","6399152","84421","L"), ("UK","62262000","243610","L"), ("Mexico","113910608","1972550","R"), ("Denmark","5543453","43094","R"), ("Norway","5002942","385252","R"), ("UAE","8264070","83600","R"), ("India","1210193422","3287263","L"), ("China","1347350000","9640821","R"),] def switch_table(memc,table): key = "@@" + table print "Switching default table to '" + table + "' by issuing GET for '" + key + "'." result = memc.get(key) def insert_country_data(memc): banner("Inserting initial data via memcached interface") for item in country_data: country = item[0] population = item[1] area = item[2] drive_side = item[3] key = country value = "|".join([population,area,drive_side]) print "Key = " + key print "Value = " + value if memc.add(key,value): print "Added new key, value pair." else: print "Updating value for existing key." memc.set(key,value) def query_country_data(memc): banner("Retrieving data for all keys (country names)") for item in country_data: key = item[0] result = memc.get(key) print "Here is the result retrieved from the database for key " + key + ":" print result(m_population, m_area, m_drive_side) = result.split("|") print "Unpacked population value: " + m_population print "Unpacked area value : " + m_area print "Unpacked drive side value: " + m_drive_side if __name__ == '__main__': memc = connect_to_memcached() switch_table(memc,"bbb") insert_country_data(memc) query_country_data(memc) sys.exit(0)
Типовые указания по применению Питона:
Никакое разрешение базы данных не обязано запускать приложение, так как манипуляция данных выполнена через интерфейс memcached. Единственная запрошенная информация этономер порта на местной системе, где слушает memcached.
multicol
, вызвана функция switch_table()
,
которая выполняет get
или set
, используя форму
@@
. Значение name
в запросе bbb
,
которое является табличным идентификатором multicol
,
определенным в поле innodb_memcache.containers.name
.
Более описательное значение name
могло бы использоваться в
приложении реального мира. Этот пример просто иллюстрирует, что табличный
идентификатор определен, а не имя таблицы в get @@...
.
add
или set
и как распаковать отделенные от канала значения, возвращенные
get
. Эта дополнительная обработка требуется только, когда идет
отображение единственного значения memcached
на несколько столбцов таблицы в MySQL.Запустите типовое приложение Питона.
shell> python multicol.py
В случае успеха пример приложения возвращает этот вывод:
Connected to memcached. Switching default table to 'bbb' by issuing GET for '@@bbb'. ============================================== Inserting initial data via memcached interface ============================================== Key = Canada Value = 34820000|9984670|R Added new key, value pair. Key = USA Value = 314242000|9826675|R Added new key, value pair. Key = Ireland Value = 6399152|84421|L Added new key, value pair. Key = UK Value = 62262000|243610|L Added new key, value pair. Key = Mexico Value = 113910608|1972550|R Added new key, value pair. Key = Denmark Value = 5543453|43094|R Added new key, value pair. Key = Norway Value = 5002942|385252|R Added new key, value pair. Key = UAE Value = 8264070|83600|R Added new key, value pair. Key = India Value = 1210193422|3287263|L Added new key, value pair. Key = China Value = 1347350000|9640821|R Added new key, value pair. ============================================ Retrieving data for all keys (country names) ============================================ Here is the result retrieved from the database for key Canada: 34820000|9984670|R Unpacked population value: 34820000 Unpacked area value : 9984670 Unpacked drive side value: R Here is the result retrieved from the database for key USA: 314242000|9826675|R Unpacked population value: 314242000 Unpacked area value : 9826675 Unpacked drive side value: R Here is the result retrieved from the database for key Ireland: 6399152|84421|L Unpacked population value: 6399152 Unpacked area value : 84421 Unpacked drive side value: L Here is the result retrieved from the database for key UK: 62262000|243610|L Unpacked population value: 62262000 Unpacked area value : 243610 Unpacked drive side value: L Here is the result retrieved from the database for key Mexico: 113910608|1972550|R Unpacked population value: 113910608 Unpacked area value : 1972550 Unpacked drive side value: R Here is the result retrieved from the database for key Denmark: 5543453|43094|R Unpacked population value: 5543453 Unpacked area value : 43094 Unpacked drive side value: R Here is the result retrieved from the database for key Norway: 5002942|385252|R Unpacked population value: 5002942 Unpacked area value : 385252 Unpacked drive side value: R Here is the result retrieved from the database for key UAE: 8264070|83600|R Unpacked population value: 8264070 Unpacked area value : 83600 Unpacked drive side value: R Here is the result retrieved from the database for key India: 1210193422|3287263|L Unpacked population value: 1210193422 Unpacked area value : 3287263 Unpacked drive side value: L Here is the result retrieved from the database for key China: 1347350000|9640821|R Unpacked population value: 1347350000 Unpacked area value : 9640821 Unpacked drive side value: R dtprice@ubuntu:~$
innodb_memcache.containers
, чтобы рассмотреть
запись, которую Вы вставили ранее для multicol
.
Первый отчет это типовая запись для таблицы demo_test
, которая
составлена во время начальной установки daemon_memcached
.
Второй отчет это запись, которую Вы вставили для multicol
.
mysql> SELECT * FROM innodb_memcache.containers\G *************************** 1. row *************************** name: aaa db_schema: test db_table: demo_test key_columns: c1 value_columns: c2 flags: c3 cas_column: c4 expire_time_column: c5 unique_idx_name_on_key: PRIMARY *************************** 2. row *************************** name: bbb db_schema: test db_table: multicol key_columns: country value_columns: population,area_sq_km,drive_side flags: c3 cas_column: c4 expire_time_column: c5 unique_idx_name_on_key: PRIMARY
multicol
, чтобы рассмотреть данные, вставленные
типовым приложением Питона. Данные доступны для
запроса MySQL,
который демонстрирует, как к тем же самым данным можно получить доступ,
используя SQL или через приложения (использующуя соответствующий
MySQL Connector или API).
mysql> SELECT * FROM test.multicol; +---------+------------+------------+------------+------+------+------+ | country | population | area_sq_km | drive_side | c3 | c4 | c5 | +---------+------------+------------+------------+------+------+------+ | Canada | 34820000 | 9984670 | R | 0 | 11 | 0 | | China | 1347350000 | 9640821 | R | 0 | 20 | 0 | | Denmark | 5543453 | 43094 | R | 0 | 16 | 0 | | India | 1210193422 | 3287263 | L | 0 | 19 | 0 | | Ireland | 6399152 | 84421 | L | 0 | 13 | 0 | | Mexico | 113910608 | 1972550 | R | 0 | 15 | 0 | | Norway | 5002942 | 385252 | R | 0 | 17 | 0 | | UAE | 8264070 | 83600 | R | 0 | 18 | 0 | | UK | 62262000 | 243610 | L | 0 | 14 | 0 | | USA | 314242000 | 9826675 | R | 0 | 12 | 0 | +---------+------------+------------+------------+------+------+------+
Всегда используйте достаточный размер, чтобы держать необходимые цифры,
десятичные запятые, символы знака, начальные нули и так далее, определяя
длину для столбцов, которые обработаны как числа. Слишком длинные значения в
строковом столбце, такие как VARCHAR
, являются усеченными,
удаляя некоторые символы, которые могли произвести
бессмысленные числовые значения.
Произвольно, выполненный тип отчета запрашивает из таблицы
InnoDB
, которая хранит данные
memcached.
Вы можете представить доклады через запросы SQL, выполняя вычисления и
тесты через любые столбцы, не только country
.
Поскольку следующие примеры используют данные только из нескольких стран,
числа только в целях иллюстрации. Следующие запросы возвращают среднее
население стран, где люди управляют справа, и средний размер стран, имена
которых начинаются на U:
mysql> SELECT AVG(population) FROM multicol WHERE drive_side = 'R'; +-------------------+ | avg(population) | +-------------------+ | 261304724.7142857 | +-------------------+ mysql> SELECT SUM(area_sq_km) FROM multicol WHERE country LIKE 'U%'; +-----------------+ | sum(area_sq_km) | +-----------------+ |10153885 | +-----------------+
Поскольку population
и area_sq_km
хранят символьные, а не числовые данные, функции
AVG()
и SUM()
работают, преобразовывая каждое
значение в число сначала. Этот подход
не работает на операторах
<
или >
,
например, сравнивая символьно-ориентированные значения,
9 > 1000
, которые не ожидаются от такого запроса, как
ORDER BY population DESC
. Для самого точного обращения типа,
выполните запросы для представлений, которые приводят числовые столбцы к
соответствующим типам. Этот метод позволяет Вам использовать простые запросы
SELECT *
от приложений базы данных, гарантируя, что
фильтр и упорядочивание правильны. Следующий пример показывает представление,
которое может быть запрошено, чтобы найти лучшие три страны в порядке
убывания населения, с результатами, отражающими
последние данные в multicol
:
mysql> CREATE VIEW populous_countries AS -> SELECT country, cast(population as unsigned integer) population, -> cast(area_sq_km as unsigned integer) area_sq_km, -> drive_side FROM multicol -> ORDER BY CAST(population as unsigned integer) DESC LIMIT 3; mysql> SELECT * FROM populous_countries; +---------+------------+------------+------------+ | country | population | area_sq_km | drive_side | +---------+------------+------------+------------+ | China | 1347350000 |9640821 | R | | India | 1210193422 |3287263 | L | | USA | 314242000 |9826675 | R | +---------+------------+------------+------------+ mysql> DESC populous_countries; +------------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+---------------------+------+-----+---------+-------+ | country | varchar(128) | NO | | | | | population | bigint(10) unsigned | YES | | NULL | | | area_sq_km | int(9) unsigned | YES | | NULL | | | drive_side | varchar(1) | YES | | NULL | | +------------+---------------------+------+-----+---------+-------+
Рассмотрите эти аспекты MySQL и таблиц InnoDB
, адаптируя
существующие приложения memcached, чтобы
использовать плагин daemon_memcached
:
Если есть значения ключа больше чем несколько байтов, может быть
более эффективно использовать числовой столбец auto-increment в качестве
primary key таблицы
InnoDB
и создать уникальный
вторичный индекс
на столбце, который содержит значения ключа memcached
. Поэтому InnoDB
выступает лучше всего для
крупномасштабных вставок, если значения первичного ключа добавлены в
сортированном порядке (как со значениями auto-increment).
Значения первичного ключа включены во вторичный индекс, который занимает
ненужное место, если первичный ключ длинное строковое значение.
InnoDB
для каждого типа данных. Определите
дополнительные табличные идентификаторы в
innodb_memcache.containers
и используйте форму
@@table_id
.key
,
чтобы сохранить и получить элементы от различных таблиц. Физически деление
различных типов информации позволяет Вам настраивать характеристики каждой
таблицы для оптимального использования пространства, работы и надежности.
Например, Вы могли бы включить
сжатие для таблицы, которая содержит сообщения в блоге, но не для
таблицы, которая содержит изображения миниатюр. Вы могли бы резервировать
одну таблицу более часто, чем другую потому, что она содержит критические
данные. Вы могли бы создать дополнительный
вторичный индекс
на таблицах, которые часто используются, чтобы произвести
отчеты, используя SQL.innodb_memcache.containers
вступают в силу, когда
innodb_memcache.containers
запрошена в следующий раз.
Записи в таблице контейнеров обработаны при запуске и проверяются всякий раз,
когда непризнанный табличный идентификатор (как определено в
containers.name
) требуется, используя форму @@
.
Таким образом, новые записи видимы, как только Вы используете связанный
табличный идентификатор, но изменения существующих записей требуют
перезапуска сервера прежде, чем они вступят в силу.innodb_only
,
вызовы add()
, set()
, incr()
и т.п.
может работать, но все еще вызвать сообщения отладки вроде
while expecting 'STORED', got unexpected response 'NOT_STORED
.
Сообщения отладки происходят, потому что новые и обновленные значения
посылаются непосредственно в таблицу InnoDB
, не будучи
сохраненными в кэш-памяти, из-за логики innodb_only
.
Поскольку использование InnoDB
в комбинации с
memcached вовлекает запись всех данных на диск
немедленно или когда-то позже, сырая работа, как ожидают, будет несколько
медленнее, чем использование memcached
отдельно. Используя InnoDB
плагин
memcached, надо максимально ускорить
операции memcached при достижении лучшей
работы, чем эквивалентные операции SQL.
Точки отсчета предполагают, что запросы и операции DML (вставки, обновления и удаления), которые используют интерфейс memcached, быстрее чем традиционный SQL. Операции DML, как правило, видят большие усовершенствования. Поэтому полагайте, что приспосабливание приложений с интенсивной записью, чтобы использовать интерфейс memcached, лучше.
Типы запросов, которые больше всего подходят для простых
GET
это запросы с единственным условием или
набором AND
в WHERE
:
SQL: SELECT col FROM tbl WHERE key = 'key_value'; memcached: GET key_value SQL: SELECT col FROM tbl WHERE col1 = val1 and col2 = val2 and col3 = val3; memcached: # Since you must always know these 3 values to look up the key, # combine them into a unique string and use that as the key # for all ADD, SET, and GET operations. key_value = val1 + ":" + val2 + ":" + val3 GET key_value SQL: SELECT 'key exists!' FROM tbl WHERE EXISTS (SELECT col1 FROM tbl WHERE KEY = 'key_value') LIMIT 1; memcached: # Test for existence of key by asking for its value and checking if the call succeeds, # ignoring the value itself. For existence checking, you typically only store a very # short value such as "1". GET key_value
Для лучшей работы разверните плагин daemon_memcached
на машинах, которые сконфигурированы как типичные серверы базы данных, где
большинство системной RAM передано
буферному пулу через опцию
innodb_buffer_pool_size
. Для систем с буферными пулами в
несколько гигабайт рассмотрите подъем значения
innodb_buffer_pool_instances
для максимальной пропускной
способности, когда большинство операций вовлекает данные, которые
уже кэшируются в памяти.
InnoDB
имеет много настроек, которые позволяют Вам выбирать
баланс между высокой надежностью, в случае катастрофического отказа и
количеством издержек ввода/вывода во время высоких рабочих нагрузок записи.
Например, рассмотрите установку
innodb_doublewrite
в 0
и
innodb_flush_log_at_trx_commit
в 2
.
Определите эксплуатационные качества с различными настройками
innodb_flush_method
.
Подробности в разделе 9.5.8.
Значение по умолчанию 1 для
daemon_memcached_r_batch_size
и
daemon_memcached_w_batch_size
предназначено для максимальной надежности результатов и безопасности
хранимых или обновленных данных.
В зависимости от типа приложения, Вы могли бы увеличить одну или обе из
этих настроек, чтобы уменьшить издержки частых операций
commit.
На занятой системе Вы могли бы увеличить
daemon_memcached_r_batch_size
зная, что
изменения данных, сделанные через SQL, возможно, не становится видимы
memcached немедленно (то есть, пока
обработано не больше N
запросов get
).
Обрабатывая данные, где каждая запись должна быть достоверно сохранена,
установите
daemon_memcached_w_batch_size
в 1
.
Увеличьте установку, обрабатывая большие количества обновлений,
предназначенных только для статистического анализа, где потеря последних
N
обновлений при катастрофическом отказе
является приемлемым риском.
Например, вообразите систему, которая контролирует трафик, пересекающий
оживленный мост, делая запись данных приблизительно для 100000 транспортных
средств каждый день. Если приложение считает различные типы транспортных
средств, чтобы проанализировать образцы трафика, измените
daemon_memcached_w_batch_size
на 100
, уменьшив
ввод/вывод на 99%. В случае отключения электричества потеряно максимум 100
отчетов, что может быть приемлемым пределом погрешности. Если бы вместо этого
приложение выполнило автоматизированный сбор данных для каждого автомобиля,
то Вы установили бы
daemon_memcached_w_batch_size
в 1
, чтобы
гарантировать, что каждый отчет был немедленно сохранен на диск.
Из-за пути, которым InnoDB
организует
значения ключа на диске, если у Вас есть большое количество ключей, которые
надо создать, может быть быстрее сортировать элементы данных значением ключа
в приложении и затем add
их в сортированном порядке, вместо
того, чтобы создать ключи в произвольном порядке.
Команда memslap, часть дистрибутива
memcached, не входит в плагин
daemon_memcached
, может быть полезна для сопоставительного
анализа различных конфигураций. Это может также использоваться, чтобы
произвести типовые пары ключа/значения, чтобы использовать в Ваших
собственных точках отсчета. См.
раздел
18.2.3.3.6.
В отличие от традиционного memcached,
daemon_memcached
позволяет Вам управлять длительностью значений
данных, произведенных посредством add
, set
,
incr
и т.п. По умолчанию, данные, написанные через интерфейс
memcached хранятся на диске, и get
возвратит новое значение с диска. Хотя поведение по умолчанию не предлагает
самую лучшую работу, это все еще быстро по сравнению с интерфейсом SQL для
таблиц InnoDB
.
Поскольку Вы приобретаете опыт, используя daemon_memcached
,
Вы можете рассмотреть настройки длительности для некритических классов
данных, рискуя тем, чтобы терять некоторые обновленные значения в случае
отключения электричества или возвратить данные, которые
являются немного устаревшими.
Важно понимать, как часто новые и измененные данные commit. Если данные важны, они должны быть немедленно переданы, чтобы это было безопасно в случае катастрофического отказа или отключения электричества. Если данные менее важные, такие как счетчики, которые сброшены после катастрофического отказа или данные о журналировании, которые Вы можете позволить себе потерять, Вы могли бы предпочесть более высокую пропускную способность, которая доступна с менее частыми сохранениями.
Когда memcached вставляет, обновляет
или удаляет данные в основной таблице InnoDB
, они меняются
немедленно (если
daemon_memcached_w_batch_size=1
) или некоторое время спустя
(если
daemon_memcached_w_batch_size
больше 1).
В любом случае изменение не может быть откачено. Если Вы увеличиваете
значение
daemon_memcached_w_batch_size
, чтобы избежать большого
ввода/вывода в течение напряженного времени, передача может стать редкой,
когда рабочая нагрузка уменьшается. Как мера по безопасности, фоновый поток
автоматически передает изменения, произведенные через
memcached API равномерно. Интервалом управляет
опция
innodb_api_bk_commit_interval
, у которой есть настройка
по умолчанию 5
секунд.
Когда memcached
вставляет или обновляет данные в основной таблице InnoDB
,
измененные данные немедленно видимы другим запросам
memcached, потому что новое значение остается в
кэш-памяти, даже если это еще не передано на сторону MySQL.
Когда memcached выполняет запрос
get
или incr
или DML на основной таблице
InnoDB
, Вы можете управлять, видит ли работа самые последние
данные, написанные в таблицу, только данные, которые были переданы, или
другие изменения операционного
уровня изоляции. Используйте
опцию
innodb_api_trx_level
, чтобы управлять этой особенностью. Числовые
значения, определенные для этой опции, соответствуют уровням изоляции,
например, REPEATABLE READ
.
Строгий уровень изоляции гарантирует, что данные, которые Вы получаете, не откачены или не изменились внезапно, чтобы заставлять последующие запросы возвратить различные значения. Однако, строгие уровни изоляции требуют больших издержек блокировки, что может вызвать ожидание. Для приложения NoSQL-стиля, которое не использует продолжительные транзакции, Вы можете, как правило, использовать уровень изоляции значения по умолчанию или переключаться на менее строгий уровень изоляции.
Опция
innodb_api_disable_rowlock
может использоваться, чтобы отключить блокировки строки, когда
memcached просит DML через
daemon_memcached
. По умолчанию
innodb_api_disable_rowlock
= OFF
,
что означает, что memcached
просит блокировки строки для get
и set
. Когда
innodb_api_disable_rowlock
= ON
,
memcached просит табличную блокировку
вместо блокировок строки.
Опция innodb_api_disable_rowlock
не является динамичной. Это
должно быть определено при запуске в командной строке
mysqld
или введено в конфигурационный файл MySQL.
По умолчанию Вы можете выполнить операции
DDL, например,
ALTER TABLE
на таблицах, используемых daemon_memcached
.
Чтобы избежать потенциального замедления, когда эти таблицы используются для
приложений высокой пропускной способности, отключите операции DDL на этих
таблицах, включая при запуске опцию
innodb_api_enable_mdl
. Эта опция является менее подходящей, если Вы получаете доступ к
тем же самым таблицам через memcached и SQL,
потому что это блокирует CREATE INDEX
на таблицах, которые могли быть важными для выполнения запросов.
Таблица innodb_memcache.cache_policies
определяет, хранить ли данные, написанные через интерфейс
memcached на диске
(innodb_only
, по умолчанию), только в памяти, как с традиционным
memcached
(cache-only
) или в обоих местах (caching
).
При значении caching
, если
memcached не может найти ключ в памяти, он ищет
значение в таблице InnoDB
. Значения из get
при caching
могут быть устаревшими, если значения были обновлены
на диске в таблице InnoDB
, но еще не выдохлись в кэш-памяти.
Кэширующая политика может быть установлена независимо для
get
, set
(включая incr
и
decr
), delete
и flush
.
Например, Вы могли бы позволить get
и set
, чтобы
запросить или обновить таблицу и кэш-память memcached
в то же самое время (используя caching
),
делая delete
, flush
или обе операции
только на копии в памяти (используя cache_only
).
Этот путь, удаляя или сбрасывая элемент только вычеркивает элемент от кэша, и
последнее значение возвращено из таблицы InnoDB
в следующий раз, когда элемент требуют.
mysql> SELECT * FROM innodb_memcache.cache_policies; +--------------+-------------+-------------+---------------+--------------+ | policy_name | get_policy | set_policy | delete_policy | flush_policy | +--------------+-------------+-------------+---------------+--------------+ | cache_policy | innodb_only | innodb_only | innodb_only | innodb_only | +--------------+-------------+-------------+---------------+--------------+ mysql> UPDATE innodb_memcache.cache_policies SET set_policy = 'caching' -> WHERE policy_name = 'cache_policy';
Значения innodb_memcache.cache_policies
считаны только при
запуске. После изменения значений в этой таблице, удалите и повторно
установите плагин daemon_memcached
, чтобы гарантировать, что
изменения вступают в силу.
mysql> UNINSTALL PLUGIN daemon_memcached; mysql> INSTALL PLUGIN daemon_memcached soname "libmemcached.so";
Точки отсчета предполагают, что daemon_memcached
ускоряет DML
(вставки, обновения и удаления) больше, чем он ускоряет запросы.
Единственная строка запроса DML является самыми легким типом запросов,
чтобы использовать операции memcached
.
INSERT
вместо add
,
UPDATE
вместо set
,
incr
или decr
,
DELETE
вместо delete
.
Эти операции, как гарантируют, затронут только одну строку, когда запущены
через интерфейс memcached, потому что
key
уникален в пределах таблицы.
В следующих примерах SQL t1
обращается к таблице,
используемой для операциях memcached,
основанных на конфигурации в innodb_memcache.containers
.
key
обращается к столбцу, перечисленному под
key_columns
, val
обращается к столбцу, перечисленному как value_columns
.
INSERT INTO t1 (key,val) VALUES (some_key
,some_value
); SELECT val FROM t1 WHERE key =some_key
; UPDATE t1 SET val =new_value
WHERE key =some_key
; UPDATE t1 SET val = val + x WHERE key =some_key
; DELETE FROM t1 WHERE key =some_key
;
Следующие TRUNCATE TABLE
и DELETE
, которые удаляют все
строки из таблицы, соответствуют flush_all
, где
t1
сконфигурирована как таблица для операций
memcached, как в предыдущем примере.
TRUNCATE TABLE t1; DELETE FROM t1;
Вы можете получить доступ к основной таблице InnoDB
(по умолчанию test.demo_test
)
через стандартные интерфейсы SQL. Однако, есть некоторые ограничения:
Запрашивая таблицу, к которой также получают доступ через
интерфейс memcached, помните, что
действия memcached могут быть сконфигурированы,
чтобы передаваться периодически, а не после каждой записи. Этим поведением
управляет опция
daemon_memcached_w_batch_size
. Если она установлена в
значение больше 1
, надо использовать
READ UNCOMMITTED
, чтобы найти строки, которые были только что вставлены.
mysql> SET SESSSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; mysql> SELECT * FROM demo_test; +------+------+------+------+-----------+------+------+------+------+------+------+ | cx | cy | c1 | cz | c2 | ca | CB | c3 | cu | c4 | C5 | +------+------+------+------+-----------+------+------+------+------+------+------+ | NULL | NULL | a11 | NULL | 123456789 | NULL | NULL | 10 | NULL | 3 | NULL | +------+------+------+------+-----------+------+------+------+------+------+------+
daemon_memcached_r_batch_size
. Если она
установлена в значение больше 1
, изменения, произведенные в
таблице, используя SQL, не видимы немедленно для memcached
.InnoDB
заблокирована как IS (intention shared) или
IX (intention exclusive) для всех операций в транзакции. Если Вы увеличиваете
daemon_memcached_r_batch_size
и
daemon_memcached_w_batch_size
существенно от их значения по умолчанию 1
,
таблица наиболее вероятно заблокирована, предотвращая запросы
DDL.Поскольку daemon_memcached
поддерживает
двоичный журнал MySQL,
обновления, сделанные на
главном сервере через интерфейс memcached
могут копироваться для резервного копирования, балансируя интенсивные рабочие
нагрузки чтения и высокую доступность. Все команды memcached
поддержаны с двоичным журналированием.
Вы не должны настроить daemon_memcached
на ведомых серверах.
Основное преимущество этой конфигурации это увеличение пропускной способности
на ведущем устройстве. Скорость механизма репликации не затронута.
Следующие разделы показывают, как использовать двоичный журнал, используя
daemon_memcached
с репликацией MySQL.
Предполагается, что Вы завершили установку, описанную в
разделе 16.19.3.
Чтобы использовать daemon_memcached
с
двоичным журналом, включите
опцию
innodb_api_enable_binlog
на
главном сервере.
Эта опция может быть установленатолько при запуске сервера. Вы должны также
включить двоичный журнал на главном сервере опцией
--log-bin
.
Вы можете добавить эти опции к конфигурационному файлу MySQL или в
командную строку mysqld
.
mysqld ... --log-bin -Б─⌠innodb_api_enable_binlog=1
master shell> mysqldump --all-databases --lock-all-tables > dbdump.db slave shell> mysql < dbdump.db
SHOW MASTER STATUS
, чтобы получить координаты
основного двоичного журнала.
mysql> SHOW MASTER STATUS;
CHANGE MASTER TO
, чтобы настроить ведомый сервер, используя
координаты из основного двоичного журнала.
mysql> CHANGE MASTER TO MASTER_HOST='localhost', MASTER_USER='root', MASTER_PASSWORD='', MASTER_PORT = 13000, MASTER_LOG_FILE='0.000001, MASTER_LOG_POS=114;
mysql> START SLAVE;
Если журнал ошибок выводит что-то, подобное следующему, ведомое устройство готово.
2013-09-24T13:04:38.639684Z 49 [Note] Slave I/O thread: connected to master 'root@localhost:13000', replication started in log '0.000001' at position 114
Этот пример демонстрирует, как проверить конфигурацию
InnoDB
memcached, используя
memcached и telnet, чтобы вставить, обновить и
удалить данные. Клиент MySQL используется, чтобы проверить результаты на
основном и ведомом серверах.
Пример использует таблицу demo_test
,
которая была составлена скриптом innodb_memcached_config.sql
во время начальной установки daemon_memcached
. Таблица
demo_test
содержит единственную запись в качестве примера.
Используйте команду set
, чтобы вставить
запись с ключом test1
, значение флага 10
,
значение истечения 0
, значение cas 1 и значение t1
.
telnet 127.0.0.1 11211 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. set test1 10 0 1 t1 STORED
demo_test
. Учитывая, что demo_test
не была ранее
изменена, должно быть две записи. Запись в качестве примера с ключом
AA
и запись, которую Вы только что вставили, с ключом
test1
. Столбец c1
отображается на ключ,
c2
значение, c3
флаг, c4
cas и
c5
ко времени истечения срока. Время истечения срока было
установлено в 0, так как это не использовано.
mysql> SELECT * FROM test.demo_test; +-------+--------------+----+----+----+ | c1 | c2 | c3 | c4 | c5 | +-------+--------------+----+----+----+ | AA | HELLO, HELLO | 8 | 0 | 0 | | test1 | t1 | 10 | 1 | 0 | +-------+--------------+----+----+----+
mysql> SELECT * FROM test.demo_test; +-------+--------------+----+----+----+ | c1 | c2 | c3 | c4 | c5 | +-------+--------------+----+----+----+ | AA | HELLO, HELLO | 8 | 0 | 0 | | test1 | t1 | 10 | 1 | 0 | +-------+--------------+----+----+----+
set
, чтобы обновить
ключ к значению new
.
telnet 127.0.0.1 11211 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. set test1 10 0 2 new STORED
Обновление копируется к ведомому серверу (заметьте, что
cas
также обновлено).
mysql> SELECT * FROM test.demo_test; +-------+--------------+----+----+----+ | c1 | c2 | c3 | c4 | c5 | +-------+--------------+----+----+----+ | AA | HELLO, HELLO | 8 | 0 | 0 | | test1 | new | 10 | 2 | 0 | +-------+--------------+----+----+----+
test1
командой delete
.
telnet 127.0.0.1 11211 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. delete test1 DELETED
Когда delete
копируется к ведомому устройству, запись
test1
на ведомом устройстве также удалена.
mysql> SELECT * FROM test.demo_test; +----+--------------+----+----+----+ | c1 | c2 | c3 | c4 | c5 | +----+--------------+----+----+----+ | AA | HELLO, HELLO | 8 | 0 | 0 | +----+--------------+----+----+----+
flush_all
.
telnet 127.0.0.1 11211 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. flush_all OK mysql> SELECT * FROM test.demo_test; Empty set (0.00 sec)
telnet 127.0.0.1 11211 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]' set test2 10 0 4 again STORED set test3 10 0 5 again1 STORED
mysql> SELECT * FROM test.demo_test; +-------+--------+----+----+----+ | c1 | c2 | c3 | c4 | c5 | +-------+--------+----+----+----+ | test2 | again | 10 | 4 | 0 | | test3 | again1 | 10 | 5 | 0 | +-------+--------+----+----+----+
flush_all
.
telnet 127.0.0.1 11211 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. flush_all OK
flush_all
скопировалась на ведомом сервере.
mysql> SELECT * FROM test.demo_test; Empty set (0.00 sec)
Формат двоичного журнала:
Большинство операций memcached
отображено на запросы DML
(аналоги вставки, удаления, обновления). С тех пор нет никакого фактического
запроса SQL, обрабатываемого сервером MySQL, все команды
memcached (кроме flush_all
)
используют журналирование Row-Based Replication (RBR), которое независимо от
любого значения
binlog_format
сервера.
flush_all
отображена на TRUNCATE TABLE
в MySQL 5.7 и ранее. Так как команды
DDL
могут использовать только основанное на запросе журналирование,
flush_all
копируется, посылая
TRUNCATE TABLE
. В
MySQL 8.0 и позже flush_all
отображена на DELETE
,
но все еще копируется, посылая
TRUNCATE TABLE
.Транзакции:
Понятие транзакций
не было частью memcached. Для исполнительных
соображений
daemon_memcached_r_batch_size
и
daemon_memcached_w_batch_size
используются, чтобы управлять пакетным размером для чтения и записи.
Эти настройки не затрагивают репликацию. Каждая работа SQL на основной
таблице InnoDB
копируется после успешного завершения.
daemon_memcached_w_batch_size
= 1
,
что означает, что каждая запись memcached
немедленно передана. Эта настройка по умолчанию подвергается определенному
количеству издержек, чтобы избежать несогласованностей в данных, которые
видимы на основных и ведомых серверах. Копируемые отчеты немедленно всегда
доступны на ведомом сервере. Если Вы устанавливаете
daemon_memcached_w_batch_size
к значению больше 1
,
записи, вставленные или обновленные через
memcached, не видимы немедленно на
главном сервере, чтобы смотреть на главном сервере записи прежде, чем они
будут переданы, используйте SET
TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
.
InnoDB
memcached
обращается к InnoDB
через InnoDB
API,
большинство которых непосредственно принято от встроенного
InnoDB
. Функции API передаются механизму
InnoDB
memcached как callback.
Функции InnoDB
API получают доступ к таблицам
InnoDB
непосредственно и являются главным образом операциями
DML, за исключением TRUNCATE TABLE
.
Команды memcached осуществлены через
InnoDB
memcached API.
Следующая таблица обрисовывает в общих чертах, как команды
memcached отображены на DML или операции DDL.
Таблица 16.13. Команды memcached и связанные операции DML или DDL
Команда memcached | DML или DDL |
---|---|
get | Команда чтения |
set | Поиск, сопровождаемый INSERT
или UPDATE (в зависимости от того, существует ли ключ) |
add | Поиск, сопровождаемый INSERT
или UPDATE |
replace | Поиск, сопровождаемый
UPDATE |
append | Поиск, сопровождаемый
UPDATE (добавляет данные к результату прежде
UPDATE ) |
prepend | Поиск, сопровождаемый
UPDATE (добавляет данные к результату прежде
UPDATE ) |
incr | Поиск, сопровождаемый
UPDATE |
decr | Поиск, сопровождаемый
UPDATE |
delete | Поиск, сопровождаемый
DELETE |
flush_all | TRUNCATE TABLE (DDL) |
Этот раздел описывает таблицы конфигурации, используемые
daemon_memcached
. Таблицы cache_policies
,
config_options
и containers
составлены
скриптом innodb_memcached_config.sql
в базе
данных innodb_memcache
.
mysql> USE innodb_memcache; Database changed mysql> SHOW TABLES; +---------------------------+ | Tables_in_innodb_memcache | +---------------------------+ | cache_policies | | config_options | | containers | +---------------------------+
Таблица cache_policies
определяет политику кэша для
InnoDB
memcached
. Вы можете определить отдельную
политику для get
, set
, delete
и
flush
в пределах единственной политики кэша. Настройка по
умолчанию для всех операций innodb_only
.
innodb_only
: Использовать InnoDB
как хранилище данных.
cache-only
: Использовать
memcached как хранилище данных.caching
: Использовать InnoDB
и
memcached как хранилище данных.
В этом случае, если memcached не
может найти ключ в памяти, он ищет значение в InnoDB
.disable
: Отключить кэширование.Таблица 16.14. Столбцы cache_policies
Столбец | Описание |
---|---|
policy_name |
Название политики кэша. Значение по умолчанию
cache_policy . |
get_policy | Политика кэша для операции
get. Допустимые значения innodb_only , cache-only ,
caching или disabled . Значение по умолчанию
innodb_only . |
set_policy |
Политика кэша для операции set. Допустимые значения
innodb_only , cache-only ,
caching или disabled . Значение по умолчанию
innodb_only . |
delete_policy |
Политика кэша для операции delete. Допустимые значения
innodb_only , cache-only ,
caching или disabled . Значение по умолчанию
innodb_only . |
flush_policy |
Политика кэша для операции flush. Допустимые значения
innodb_only , cache-only ,
caching или disabled . Значение по умолчанию
innodb_only . |
Таблица config_options
хранит настройки
memcached, которые могут быть изменены во
время выполнения, используя SQL. Поддержанные параметры конфигурации
separator
и table_map_delimiter
.
Таблица 16.15. Столбцы config_options
Столбец | Описание |
---|---|
Name |
Название опции memcached. Следующие параметры
конфигурации поддержаны в таблице config_options :
|
Value |
Значение опции memcached. |
Таблица containers
является самой важной из трех таблиц
конфигурации. Каждая таблица InnoDB
, которая используется, чтобы
сохранить значения memcached должна иметь
запись в таблице containers
. Запись обеспечивает отображение
между столбцом таблицы InnoDB
и столбцами таблицы container,
которые требуются для работы memcached
с InnoDB
.
Таблица containers
содержит запись по умолчанию для
test.demo_test
, которая составлена скриптом
innodb_memcached_config.sql
. Чтобы использовать плагин
daemon_memcached
с Вашей собственной таблицей
InnoDB
, Вы должны создать запись в containers
.
Таблица 16.16. Столбцы containers
Столбец | Описание |
---|---|
name |
Имя, данное контейнеру. Если таблица InnoDB
не требуется по имени, используя форму @@ , плагин
daemon_memcached применяет таблицу InnoDB с
containers.name = default .
Если нет такой записи, применяется первая запись в containers ,
упорядоченная в алфавитном порядке по name , определяющая
таблицу InnoDB по умолчанию. |
db_schema | Название базы данных, где находится
таблица InnoDB . Это необходимое значение. |
db_table | Название таблицы InnoDB ,
которая хранит значения memcached.
Это необходимое значение. |
key_columns | Столбец в таблице
InnoDB , которая содержит значения ключа поиска для
memcached. Это необходимое значение. |
value_columns | Столбцы (один или больше)
таблицы InnoDB для хранения данных memcached .
Много столбцов может быть определено, используя символ разделителя,
определенный в innodb_memcached.config_options .
По умолчанию разделитель это символ канала (|).
Чтобы определить много столбцов, отделите их определенным символом
разделителя. Например: col1|col2|col3 .
Это необходимое значение. |
flags | Столбцы таблицы InnoDB ,
которые используются в качестве флагов (определяемое пользователем числовое
значение, которое сохранено и получено наряду с основным значением) для
memcached. Значение флага может использоваться
в качестве спецификатора столбца для некоторых операций (таких, как
incr , prepend ), если значение
memcached отображено на много столбцов, чтобы
работа была выполнена на указанном столбце. Например, если Вы отобразили
value_columns на три столбца InnoDB ,
и надо увеличить только один столбце, используют flags , чтобы
определить столбец. Если Вы не используете flags , задайте
значение 0 , чтобы указать, что это не использовано. |
cas_column | Столбец таблицы, который хранит
значение compare-and-swap (cas). cas_column связано с путем,
которым memcached обращается
к различным серверам и данным о кэшах в памяти. Поскольку
memcached плотно объединен с единственным
сервером memcached,
механизм кэширования в памяти обработан MySQL и
буферным пулом,
этот столбец редко необходим. Если Вы не используете этот столбец, установите
значение 0 , чтобы указать, что это не использовано. |
expire_time_column | Столбец таблицы, который
хранит значение истечения. expire_time_column связано с путем,
которым memcached обращается
к различным серверам и данным о кэшах в памяти. Поскольку
memcached плотно объединен с единственным
сервером memcached,
механизм кэширования в памяти обработан MySQL и
буферным пулом, этот столбец
редко необходим. Если Вы не используете этот столбец, установите
значение 0 , чтобы указать, что это не использовано. Максимум
определен как INT_MAX32 или 2147483647 секунд. |
unique_idx_name_on_key |
Название индекса на ключевом столбце. Это должно быть уникальным индексом.
Это может быть primary key или
вторичным индексом.
Предпочтительно используйте первичный ключ таблицы InnoDB .
Использование первичного ключа избегает поиска, который выполнен, когда
используется вторичный индекс. Вы не можете создать
покрывающий индекс
для поисков в memcached: InnoDB
возвращает ошибку, если Вы пытаетесь определить композитный вторичный индекс
по ключам и по столбцам значений. |
Вы должны поставлять значение для db_schema
,
db_name
, key_columns
, value_columns
и
unique_idx_name_on_key
. Определите 0
для
flags
, cas_column
и expire_time_column
, если они не использованы.
key_columns
: Максимальный предел для ключа
memcached 250 символов, который проведен в
жизнь memcached. Отображенный ключ должен быть
не-Null CHAR
или
VARCHAR
.value_columns
: Должен быть отображен на
CHAR
,
VARCHAR
или
BLOB
.
Нет никакого ограничения длины, и значение может быть NULL.cas_column
: cas
это
целое число на 64 бита. Это должно быть отображено на
BIGINT
по крайней мере из 8 байтов. Если Вы не используете этот столбец, установите
значение 0
, чтобы указать, что это не использовано.expiration_time_column
: Должен быть отображен на
INTEGER
по крайней мере из 4 байтов. Время истечения срока определено как 32-битовое
целое число в течение времени Unix (число секунд с 1 января 1970 как
32-битовое значение), или число секунд с текущего времени. Для последнего
число секунд, возможно, не превышает 60*60*24*30 (число секунд через 30
дней). Если число, посланное клиентом, больше, сервер полагает, что это
реальное значение времени Unix, а не смещение с текущего времени. Если Вы не
используете этот столбец, установите значение 0
, чтобы указать,
что это не использовано.flags
: Должен быть отображен на
INTEGER
по крайней мере из 32 битов и может быть NULL.
Если Вы не используете этот столбец, установите значение 0
,
чтобы указать, что это не использовано.Предварительная проверка выполнена во время загрузки, чтобы провести в жизнь ограничения столбца. Если несоответствия будут найдены, то плагин не будет загружаться.
Во время инициализации, когда InnoDB
memcached
сконфигурирован с информацией, определенной в containers
,
каждый отображенный столбец, определенный в
containers.value_columns
, проверен для отображения в
InnoDB
. Если несколько столбцов InnoDB
отображены, есть проверка, чтобы гарантировать, что каждый столбец
существует с правильным типом.
memcached
, если есть больше
значений, чем число отображенных столбцов, только число отображенных значений
взято. Например, если есть шесть отображенных столбцов и семь разграниченных
значений обеспечены, только первые шесть разграниченных значений взяты.
Седьмое значение проигнорировано.Скрипт innodb_memcached_config.sql
создает таблицу
demo_test
в базе данных test
,
которая может использоваться, чтобы проверить
memcached немедленно после установки.
Скрипт innodb_memcached_config.sql
также создает запись для таблицы demo_test
в
innodb_memcache.containers
.
mysql> SELECT * FROM innodb_memcache.containers\G *************************** 1. row *************************** name: aaa db_schema: test db_table: demo_test key_columns: c1 value_columns: c2 flags: c3 cas_column: c4 expire_time_column: c5 unique_idx_name_on_key: PRIMARY mysql> SELECT * FROM test.demo_test; +----+--------------+----+----+----+ | c1 | c2 | c3 | c4 | c5 | +----+--------------+----+----+----+ | AA | HELLO, HELLO | 8 | 0 | 0 | +----+--------------+----+----+----+
Этот раздел описывает проблемы, с которыми Вы можете столкнуться,
используя InnoDB
memcached.
Если Вы сталкиваетесь со следующей ошибкой в журнале ошибок MySQL, сервер может быть не в состоянии запуститься:
failed to set rlimit for open files. Try running as root or requesting smaller maxconns value.
Сообщение об ошибке от memcached. Одно решение состоит в том, чтобы поднять предел OS для числа открытых файлов. Команды для проверки и увеличения предела файла зависят от ОС. Этот пример показывает команды для Linux и OS X:
# Linux shell> ulimit -n 1024 shell> ulimit -n 4096 shell> ulimit -n 4096 # OS X shell> ulimit -n 256 shell> ulimit -n 4096 shell> ulimit -n 4096
Другое решение состоит в том, чтобы сократить количество параллельных
соединений, разрешенных для memcached.
Чтобы сделать так, закодируйте опцию -c
memcached в параметре
daemon_memcached_option
в конфигурационном файле MySQL.
Значение по умолчанию 1024.
[mysqld] ... loose-daemon_memcached_option='-c 64'
InnoDB
удобно,
задав опцию -vvv
memcached в
параметре
daemon_memcached_option
в конфигурационном файле MySQL.
Исследуйте журнал ошибок MySQL на вывод отладки, связанный с
memcached.
[mysqld] ... loose-daemon_memcached_option='-vvv'
daemon_memcached
вызывает проблемы запуска сервера MySQL, Вы можете временно отключить
daemon_memcached
, добавляя эту строку в группу
[mysqld]
в конфигурационном файле MySQL:
daemon_memcached=OFF
Например, если Вы запускаете
INSTALL PLUGIN
прежде, чем вызвать скрипт
innodb_memcached_config.sql
, чтобы настроить необходимую базу
данных и таблицы, сервер мог быть не в состоянии запуститься.
Сервер мог также быть не в состоянии запуститься, если Вы неправильно
конфигурируете запись в innodb_memcache.containers
.
Чтобы удалить плагин memcached, сделайте следующее запрос:
mysql> UNINSTALL PLUGIN daemon_memcached;
daemon_memcached
в каждом случае, используйте
daemon_memcached_option
, чтобы определить уникальный порт
memcached для каждого
плагина daemon_memcached
.InnoDB
или не находит данных в таблице, но
memcached API
получает ожидаемые данные, врщможно, пропущена запись для таблицы в
innodb_memcache.containers
,
или Вы, возможно, не переключились на правильную таблицу при
get
или set
, используя формат
@@table_id
.
Эта проблема могла также произойти, если Вы изменяете существующую запись в
innodb_memcache.containers
, не перезапуская сервер MySQL позже.
Механизм хранения свободной формы достаточно гибок, чтобы сохранить или
получить значение из нескольких столбцов, такое как
col1|col2|col3
все еще работает, даже если демон использует
test.demo_test
, которая хранит значения в единственном столбце.
InnoDB
для использования с daemon_memcached
,
и столбцы в таблице определены как NOT NULL
,
гарантируйте, что значения поставляются для столбцов NOT NULL
,
вставляя запись для таблицы в innodb_memcache.containers
. Если
INSERT
для
innodb_memcache.containers
содержит меньше разграниченных значений, чем есть отображенных столбцов,
незаполненные столбцы установлены в NULL
.
Попытка вставить NULL
в столбец NOT NULL
вызывает сбой INSERT
,
что может только стать очевидным после того, как Вы повторно инициализируете
daemon_memcached
, чтобы применить изменения таблицы
innodb_memcache.containers
.cas_column
и
expire_time_column
в таблице
innodb_memcached.containers
установлены в NULL
,
следующая ошибка будет возвращена, пытаясь загрузить плагин
memcached:
InnoDB_Memcached: column 6 in the entry for config table 'containers' in database 'innodb_memcache' has an invalid NULL value.
memcached отклоняет использование
NULL
в cas_column
и
expire_time_column
. Установите значение этих столбцов к
0
, когда столбцы не использованы.
Когда ключ превышает 250 байтов, memcached возвращают ошибку. Это в настоящее время неподвижный предел в пределах memcached.
InnoDB
можно столкнуться, если значения превышают 768 байтов, 3072 байта в размере
или половину
innodb_page_size
. Эти пределы прежде всего применяются, если Вы
намереваетесь создать индекс на столбце значений, чтобы выполнить
производящие отчет запросы на том столбце, используя SQL. См.
раздел 16.8.7.Если Вы совместно используете конфигурационные файлы на серверах MySQL
различных версий, используя последние параметры конфигурации для
daemon_memcached
может вызвать ошибки запуска на более старых
версиях MySQL. Чтобы избежать проблем совместимости, используйте префикс
loose
с именами опции. Например, можно использовать
loose-daemon_memcached_option='-c 64'
вместо
daemon_memcached_option='-c 64'
.
Следующие общие руководящие принципы относятся к поиску
неисправностей InnoDB
:
Когда работа терпит неудачу, или Вы подозреваете ошибку, см. журнал ошибок сервера MySQL (см. раздел 6.4.2 ). Раздел B.3 предоставляет информацию о поиске неисправностей для некоторых из общих ошибок, с которыми Вы можете столкнуться.
innodb_print_all_deadlocks
, чтобы детали о каждом тупике
InnoDB
выводились в журнал ошибок сервера MySQL.
--console
, чтобы направить вывод к консоли.InnoDB
Monitors, чтобы получить информацию о
проблеме (см. раздел 16.16).
Если проблема с блокировками, включите Lock Monitor.
InnoDB
временно включает стандартный
InnoDB
Monitor при следующих условиях:
Ждет длинный семафор.
InnoDB
не может найти свободные блоки в буферном пуле.Если Вы подозреваете, что таблица повреждена, выполните
CHECK TABLE
.
Поиск неисправностей для InnoDB
I/O
зависят от того, когда проблема происходит: во время запуска сервера MySQL
или во время нормального функционирования, когда DML или запрос DDL терпят
неудачу из-за проблем на уровне файловой системы.
Если что-то идет не так, как надо, когда InnoDB
пытается инициализировать табличное пространство или файлы системного
журнала, удалите все файлы, создаваемые InnoDB
: все файлы
ibdata
и ib_logfile
.
Если Вы уже создали некоторые таблицы InnoDB
,
также удалите любые файлы .ibd
из каталогов базы данных MySQL.
Тогда попробуйте создание базы данных снова. Для самого легкого поиска
неисправностей, запустите сервер MySQL из командной строки так, чтобы Вы
видели то, что происходит.
Если InnoDB
печатает ошибку операционной системы во время
работы с файлом, обычно у проблемы есть одно из следующих решений:
Удостоверьтесь, что каталог файлов с данными и
каталог журналов InnoDB
существуют.
my.cnf
или my.ini
, чтобы это запустилось с опциями,
которые Вы определили.innodb_data_home_dir
и
innodb_data_file_path
. В частности любое значение MAX
в опции
innodb_data_file_path
это жесткий предел, превышение ограничения
вызывает фатальную ошибку.Чтобы исследовать повреждение страницы базы данных, Вы могли бы вывести
свои таблицы из базы данных с помощью
SELECT ... INTO OUTFILE
.
Обычно большинство данных, полученных таким образом, не повреждено. Серьезное
повреждение могло бы вызвать
SELECT * FROM
или фоновые
процессы. В таких случаях Вы можете использовать опцию
tbl_name
innodb_force_recovery
, чтобы запустить механизм хранения, препятствуя фоновым работам,
чтобы Вы могли вывести свои таблицы. Например, Вы можете добавить следующую
строку к разделу [mysqld]
Вашего файла опции прежде, чем перезапустить сервер:
[mysqld] innodb_force_recovery = 1
Установите
innodb_force_recovery
к значению больше 0 только в чрезвычайной
ситуации, чтобы Вы могли запустить InnoDB
и вывести свои таблицы. Прежде чем сделать так, гарантируйте, что у Вас есть
резервная копия Вашей базы данных в случае, если Вы должны обновить ее.
Значения 4 или больше могут надолго повредить файлы с данными. Используйте
innodb_force_recovery
4 или больше на производственном случае сервера только после
того, как Вы успешно проверили установку на отдельной физической копии Вашей
базы данных. Вызывая восстановление InnoDB
, Вы должны всегда
запускать с
innodb_force_recovery=1
и увеличьте значение только
по мере необходимости.
innodb_force_recovery
= 0 по умолчанию (нормальный запуск без
принудительного восстановления). Допустимые ненулевые значения для
innodb_force_recovery
от 1 до 6. Большее значение включает функциональность меньших
значений. Например, значение 3 включает всю функциональность значений 1 и 2.
Если Вы в состоянии вывести свои таблицы с
innodb_force_recovery
= 3 или меньше, тогда Вы относительно защищены от того, что
только некоторые данные на поврежденных отдельных страницах потеряны.
Значение 4 или больше считают опасным, потому что файлы с данными могут быть
надолго повреждены. Значение 6 считают решительным, потому что страницы базы
данных оставляют в устаревшем состоянии, которое в свою очередь может ввести
больше повреждений в B-trees
и другие структуры базы данных.
Как мера по безопасности, InnoDB
блокирует
INSERT
,
UPDATE
или
DELETE
, если
innodb_force_recovery
больше 0.
innodb_force_recovery
= 4 или выше запускает
InnoDB
в режиме только для чтения.
1
(SRV_FORCE_IGNORE_CORRUPT
)
Позволяет серверу работать, даже если он обнаруживает поврежденную
страницу. Попытки сделать
SELECT * FROM
перепрыгивают поврежденные записи индекса и страницы, что
помогает в дампе таблиц.tbl_name
2
(SRV_FORCE_NO_BACKGROUND
)
Предотвращает работу основного потока и любых потоки чистки . Если бы катастрофический отказ произошел во время работы чистки, это значение восстановления предотвращает такую ситуацию.
3
(SRV_FORCE_NO_TRX_UNDO
)
Не выполняет операционные отмены после восстановления катастрофического отказа.
4
(SRV_FORCE_NO_IBUF_MERGE
)
Не сливает буферы вставки.
Если они вызвали бы катастрофический отказ, не делает их. Не вычисляет
табличную статистику.
Это значение может надолго повредить файлы с данными. После использования
этого значения будьте готовы удалить и обновить все вторичные индексы.
Переключает InnoDB
в режим только для чтения.
5
(SRV_FORCE_NO_UNDO_LOG_SCAN
)
Не смотрит журналы отмены,
запуская базу данных: InnoDB
обработает даже неполные
транзакции как передано. Это значение может надолго повредить файлы с
данными. Переключает InnoDB
в режим только для чтения.
6
(SRV_FORCE_NO_LOG_REDO
)
Не делает накат журналов redo
в соединении с восстановлением. Это значение может надолго повредить файлы с
данными. Страницы базы данных листьев в устаревшем статусе, который в свою
очередь может ввести больше повреждения в B-деревья и другие структуры базы
данных. Переключает InnoDB
в режим только для чтения.
Вы можете SELECT
из таблиц, чтобы вывести их. С
innodb_force_recovery
= 3 или меньше Вы можете выполнить для таблиц DROP
или CREATE
. DROP TABLE
также поддержан с
innodb_force_recovery
больше 3.
Если Вы знаете, что данная таблица вызывает катастрофический отказ на
отмене, Вы можете удалить это. Если Вы сталкиваетесь с безудержной отменой,
вызванной отменом массового импорта или
ALTER TABLE
,
Вы можете уничтожить процесс
mysqld и установить
innodb_force_recovery
= 3
, поднять базу данных без отмены, а затем
DROP
таблицу, которая вызывает безудержную отмену.
Если повреждение в пределах табличных данных препятствует тому, чтобы Вы
вывели все табличное содержание, запрос c ORDER BY
может быть в состоянии вывести часть таблицы после поврежденной части.primary_key
DESC
Если верхний уровень
innodb_force_recovery
нужен для запуска
InnoDB
, могут быть поврежденные структуры данных, которые могли
вызвать сбои сложных запросов (запросы, содержащие WHERE
,
ORDER BY
или нечто подобное). В этом случае Вы можете быть в
состоянии использовать только обычные запросы SELECT * FROM t
.
Информация о табличных определениях хранится в словаре данных InnoDB. Если Вы перемещаете файлы с данными, или если катастрофический отказ сервера был в середине работы со словарем данных, данные словаря могут стать непоследовательными.
Если повреждение словаря данных или проблема последовательности
препятствуют тому, чтобы Вы запустили InnoDB
, см.
раздел 16.20.2.
При включении
innodb_file_per_table
(значение по умолчанию), следующие
сообщения могут появиться при запуске если файл табличного пространства
file-per-table
(файл .ibd
) отсутствует:
[ERROR] InnoDB: Operating system error number 2 in a file operation. [ERROR] InnoDB: The error means the system cannot find the path specified. [ERROR] InnoDB: Cannot open datafile for read-only: './test/t1.ibd' OS error: 71 [Warning] InnoDB: Ignoring tablespace `test/t1` because it could not be opened.
Используйте запрос DROP TABLE
, чтобы удалить данные о недостающей таблице из словаря данных.
Эта процедура описывает, как восстановить висячие строки
в файлах file-per-table
.ibd
к другому случаю MySQL. Вы могли бы использовать эту
процедуру, если системное табличное пространство потеряно или неисправимо, и
Вы хотите восстановить копию .idb
на новом сервере MySQL.
Процедура не поддержана для файлов .ibd
общего табличного пространства.
Процедура предполагает, что Вы имеете только резервные копии файла
.ibd
и восстанавливаете к той же самой версии MySQL, которая
первоначально создала файлы. См.
раздел 16.8.3
для информации о создании чистых резервных копий.
Ограничения копирования табличного пространства, обрисованные в общих чертах в разделе 16.7.6, применимы к этой процедуре.
На новом случае MySQL, создайте таблицу в базе данных с тем же самым именем.
mysql> CREATE DATABASE sakila; mysql> USE sakila; mysql> CREATE TABLE actor ( -> actor_id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, -> first_name VARCHAR(45) NOT NULL, -> last_name VARCHAR(45) NOT NULL, -> last_update TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP -> ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (actor_id), -> KEY idx_actor_last_name (last_name)) ENGINE=InnoDB -> DEFAULT CHARSET=utf8;
mysql> ALTER TABLE sakila.actor DISCARD TABLESPACE;
.idb
из
Вашего резервного каталога в новый каталог базы данных.
shell> cp /backup_directory
/actor.ibdpath/to/mysql-5.7/data
/sakila/
.ibd
есть необходимые разрешения..ibd
. Предупреждение выпущено, указывая,
что InnoDB
попытается импортировать файл без проверки схемы.
mysql> ALTER TABLE sakila.actor IMPORT TABLESPACE; SHOW WARNINGS; Query OK, 0 rows affected, 1 warning (0.15 sec) Warning | 1810 | InnoDB: IO Read error: (2, No such file or directory) Error opening './sakila/actor.cfg', will attempt to import without schema verification
.ibd
был успешно восстановлен.
mysql> SELECT COUNT(*) FROM sakila.actor; +----------+ | count(*) | +----------+ | 200 | +----------+
Следующие элементы описывают, как InnoDB
выполняет обработку ошибок. InnoDB
иногда откатывает
только запрос, который потерпел неудачу, в других ситуациях
откатывает всю транзакцию.
Если Вы исчерпываете пространство файла, происходит ошибка
Table is full
, InnoDB
откатывает запрос SQL.
Блокировка тайм-аута откатывает только единственный запрос,
который ждал блокировки и столкнулся с тайм-аутом. Чтобы откатить всю
транзакцию, запускают сервер с опцией
--innodb_rollback_on_timeout
.
Повторите запрос, используя текущее поведение, или всю транзакцию, если
используется
--innodb_rollback_on_timeout
.
Тупики и тайм-ауты нормальны на занятых серверах, и приложению необходимо знать, что они могут произойти и обработать их, повторяя. Вы можете сделать их менее вероятными, делая настолько маленькую работу, насколько возможно, между первым изменением данных во время транзакции и передачей, таким образом, блокировки проводятся в течение самого короткого времени и для самого маленького числа строк. Иногда разделение работы между различными транзакциями может быть практичным и полезным.
Когда операционная отмена происходит из-за тупика или тайм-аута
блокировки, это отменяет эффект запросов в пределах транзакции. Но если
запросом запуска транзакции был
START TRANSACTION
или
BEGIN
,
отмена не отменяет этот запрос. Далее запросы SQL становятся частью
транзакции до возникновения COMMIT
,
ROLLBACK
или некоторого запроса
SQL, который вызывает неявное закрытие транзакции.
IGNORE
.row too long error
откатывает запрос SQL.InnoDB
), они откатывают
соответствующий запрос SQL. Блокировки не выпущены при отмене
единственного запроса SQL.Во время неявных отмен, так же как во время выполнения явного
ROLLBACK
,
SHOW PROCESSLIST
показывает Rolling back
в столбце State
для соответствующего соединения.