Spec-Zone.ru › MySQL 5.7

14.11 Форматы строк InnoDB

Формат строки таблицы определяет, как её строки хранятся физически, что, в свою очередь, может влиять на производительность запросов и операций DML. Чем больше строк помещается на одной странице диска, тем быстрее работают запросы и поиск по индексам, меньше требуется оперативной памяти в пуле буферов и меньше операций ввода-вывода для записи обновлённых значений.

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

Столбцы переменной длины являются исключением из правила, что значения столбцов хранятся в узлах индекса B-дерева. Столбцы переменной длины, которые слишком длинные, чтобы поместиться на странице B-дерева, хранятся на отдельных страницах диска, называемых страницами переполнения. Такие столбцы называются столбцами вне страницы. Значения столбцов вне страницы хранятся в односвязных списках страниц переполнения, причём у каждого такого столбца есть свой список из одной или нескольких страниц переполнения. В зависимости от длины столбца, все или префикс значений столбца переменной длины хранятся в B-дереве, чтобы избежать потерь места и необходимости чтения отдельной страницы.

Движок хранения InnoDB поддерживает четыре формата строк: REDUNDANT, COMPACT, DYNAMIC и COMPRESSED.

Таблица 14.9 Обзор форматов строк InnoDB

Таблица 14.9 Обзор форматов строк InnoDB
Формат строки Характеристики компактного хранения Улучшенное хранение столбцов переменной длины Поддержка длинного префикса индексного ключа Поддержка сжатия Поддерживаемые типы табличных пространств Требуемый формат файла
REDUNDANT Нет Нет Нет Нет system, file-per-table, general Antelope или Barracuda
COMPACT Да Нет Нет Нет system, file-per-table, general Antelope или Barracuda
DYNAMIC Да Да Да Нет system, file-per-table, general Barracuda
COMPRESSED Да Да Да Да file-per-table, general Barracuda

Следующие разделы описывают характеристики хранения форматов строк и как определить и узнать формат строки таблицы.

  • Формат строки REDUNDANT

  • Формат строки COMPACT

  • Формат строки DYNAMIC

  • Формат строки COMPRESSED

  • Определение формата строки таблицы

  • Определение формата строки таблицы

Формат строки REDUNDANT

Формат REDUNDANT обеспечивает совместимость со старыми версиями MySQL.

Формат строки REDUNDANT поддерживается обоими форматами файлов InnoDB (Antelope и Barracuda). Более подробная информация в разделе 14.10, «Управление форматом файлов InnoDB».

Таблицы, использующие формат строки REDUNDANT, хранят первые 768 байтов значений столбцов переменной длины (VARCHAR, VARBINARY и BLOB и TEXT типы) в записи индекса в узле B-дерева, а остальную часть — на страницах переполнения. Столбцы фиксированной длины, превышающие или равные 768 байтам, кодируются как столбцы переменной длины, которые могут храниться вне страницы. Например, столбец CHAR(255) может превышать 768 байт, если максимальная длина байта набора символов больше 3, как это происходит с utf8mb4.

Если значение столбца составляет 768 байт или меньше, страница переполнения не используется, что может привести к некоторой экономии операций ввода-вывода, так как значение полностью хранится в узле B-дерева. Это хорошо работает для относительно коротких значений столбца BLOB, но может привести к заполнению узлов B-дерева данными вместо ключей, снижая их эффективность. Таблицы со многими столбцами BLOB могут привести к тому, что узлы B-дерева станут слишком полными и будут содержать слишком мало строк, что сделает весь индекс менее эффективным, чем если бы строки были короче или значения столбцов хранились вне страницы.

Характеристики хранения формата строки REDUNDANT

Формат строки REDUNDANT имеет следующие характеристики хранения:

  • Каждая запись индекса содержит заголовок длиной 6 байт. Заголовок используется для связывания последовательных записей и для блокировки на уровне строк.

  • Записи в кластеризованном индексе содержат поля для всех пользовательских столбцов. Кроме того, есть поле идентификатора транзакции длиной 6 байт и поле указателя журнала длиной 7 байт.

  • Если для таблицы не определён первичный ключ, каждая запись кластеризованного индекса также содержит поле идентификатора строки длиной 6 байт.

  • Каждая запись вторичного индекса содержит все столбцы первичного ключа, определённые для ключа кластеризованного индекса, которые не находятся во вторичном индексе.

  • Запись содержит указатель на каждое поле записи. Если общая длина полей в записи меньше 128 байт, указатель занимает один байт; в противном случае — два байта. Массив указателей называется каталогом записи. Область, на которую указывают указатели, является частью данных записи.

  • Внутренне столбцы символов фиксированной длины, такие как CHAR(10), хранятся в формате фиксированной длины. При этом завершающие пробелы не усекаются из столбцов VARCHAR.

  • Столбцы фиксированной длины, превышающие или равные 768 байтам, кодируются как столбцы переменной длины, которые могут храниться вне страницы. Например, столбец CHAR(255) может превышать 768 байт, если максимальная длина байта набора символов больше 3, как это происходит с utf8mb4.

  • Значение SQL NULL зарезервирует один или два байта в каталоге записи. Значение SQL NULL зарезервирует ноль байт в данных записи, если хранится в столбце переменной длины. Для столбца фиксированной длины фиксированная длина столбца резервируется в данных записи. Резервирование фиксированного места для значений NULL позволяет обновлять столбцы на месте от значений NULL до значений, не являющихся NULL, без фрагментации страницы индекса.

Формат строк COMPACT

Формат строк COMPACT уменьшает занимаемое место примерно на 20% по сравнению с форматом строк REDUNDANT, но при этом увеличивает использование ЦП для некоторых операций. Если ваша рабочая нагрузка — типичная, ограниченная скоростью кэширования и скоростью диска, то формат COMPACT, вероятно, будет быстрее. Если рабочая нагрузка ограничена скоростью ЦП, формат COMPACT может быть медленнее.

Формат строк COMPACT поддерживается в обоих форматах файлов InnoDB (Antelope и Barracuda). Более подробную информацию см. в разделе 14.10, «Управление форматом файлов InnoDB».

Таблицы, использующие формат строк COMPACT, хранят первые 768 байт значений столбцов переменной длины (VARCHAR, VARBINARY, и BLOB и TEXT типов) в записи индекса внутри узла, а остальную часть — на страницах переполнения. Столбцы фиксированной длины, большие или равные 768 байтам, кодируются как столбцы переменной длины, которые могут храниться вне страницы. Например, столбец CHAR(255) может превышать 768 байт, если максимальная длина байта набора символов больше 3, как в случае с utf8mb4.

Если значение столбца составляет 768 байт или меньше, страница переполнения не используется, и это может привести к некоторым экономиям при ввода-выводе, поскольку значение полностью хранится в узле дерева B. Это хорошо работает для значений столбцов BLOB сравнительно небольшой длины, но может привести к заполнению узлов дерева B данными вместо значений ключей, уменьшая их эффективность. Таблицы со многими столбцами BLOB могут привести к тому, что узлы дерева B станут слишком полными и будут содержать слишком мало строк, что сделает весь индекс менее эффективным, чем если бы строки были короче или значения столбцов хранились вне страницы.

Характеристики хранения формата строк COMPACT

Формат строк COMPACT имеет следующие характеристики хранения:

  • Каждая запись индекса содержит 5-байтовый заголовок, перед которым может быть переменный заголовок. Заголовок используется для объединения последовательных записей и для блокировки на уровне строк.

  • Переменная часть заголовка записи содержит битовую вектор для указания столбцов NULL. Если количество столбцов в индексе, которые могут быть NULL, составляет N, битовая вектор занимает CEILING(N/8) байт. (Например, если в индексе от 9 до 16 столбцов, которые могут быть NULL, битовая вектор использует два байта.) Столбцы, которые NULL, не занимают места, кроме бита в этом векторе. Переменная часть заголовка также содержит длины столбцов переменной длины. Длина каждого столбца занимает один или два байта, в зависимости от максимальной длины столбца. Если все столбцы в индексе — NOT NULL и имеют фиксированную длину, у записи нет переменной части заголовка.

  • Для каждого не-NULL столбца переменной длины в заголовке записи содержится длина столбца в одном или двух байтах. Два байта необходимы только в том случае, если часть столбца хранится во внешних страницах переполнения или максимальная длина превышает 255 байт, а фактическая длина превышает 127 байт. Для внешнего столбца 2-байтовая длина указывает длину внутренней части плюс 20-байтовый указатель на внешнюю часть. Внутренняя часть — 768 байт, поэтому длина составляет 768+20. 20-байтовый указатель хранит истинную длину столбца.

  • За заголовком записи следуют данные содержимого столбцов, не являющихся NULL.

  • Записи в кластеризованном индексе содержат поля для всех определённых пользователем столбцов. Кроме того, есть 6-байтовое поле идентификатора транзакции и 7-байтовое поле указателя отката.

  • Если для таблицы не определён первичный ключ, каждая запись кластеризованного индекса также содержит 6-байтовое поле идентификатора строки.

  • Каждая запись вторичного индекса содержит все столбцы первичного ключа, определённые для ключа кластеризованного индекса, которые не находятся во вторичном индексе. Если какие-либо столбцы первичного ключа имеют переменную длину, у заголовка записи каждого вторичного индекса есть переменная часть для записи их длин, даже если вторичный индекс определён на столбцах фиксированной длины.

  • Внутренне, для наборов символов фиксированной длины, столбцы символов фиксированной длины, такие как CHAR(10), хранятся в формате фиксированной длины.

    Конечные пробелы не усекаются из столбцов VARCHAR.

  • Внутренне, для наборов символов переменной длины, таких как utf8mb3 и utf8mb4, InnoDB пытается сохранить CHAR(N) в N байтах, обрезая конечные пробелы. Если длина в байтах значения столбца CHAR(N) превышает N байт, конечные пробелы обрезаются до минимума длины в байтах значения столбца. Максимальная длина столбца CHAR(N) равна максимальной длине в байтах символа × N.

    Минимально N байт зарезервировано для CHAR(N). Зарезервирование минимального пространства N во многих случаях позволяет выполнять обновления столбцов на месте без фрагментации страниц индекса. В сравнении, столбцы CHAR(N) занимают максимальную длину в байтах символа × N при использовании формата строк REDUNDANT.

    Столбцы фиксированной длины, большие или равные 768 байтам, кодируются как поля переменной длины, которые могут храниться вне страницы. Например, столбец CHAR(255) может превышать 768 байт, если максимальная длина байта набора символов больше 3, как в случае с utf8mb4.

Формат строк DYNAMIC

Формат строки DYNAMIC предлагает те же характеристики хранения, что и формат строки COMPACT, но добавляет расширенные возможности хранения для длинных столбцов переменной длины и поддерживает большие префиксы ключей индексов.

Формат файла Barracuda поддерживает формат строки DYNAMIC. Смотрите Раздел 14.10, «Управление форматом файлов InnoDB».

При создании таблицы с ROW_FORMAT=DYNAMIC, InnoDB могут хранить значения длинных столбцов переменной длины (для типов VARCHAR, VARBINARY и BLOB и TEXT) полностью вне страницы, при этом запись индекса кластеризации содержит только 20-байтовый указатель на страницу переполнения. Поля фиксированной длины, большие или равные 768 байтам, кодируются как поля переменной длины. Например, столбец CHAR(255) может превышать 768 байтов, если максимальная длина байта набора символов больше 3, как это происходит с utf8mb4.

Хранение столбцов вне страницы зависит от размера страницы и общего размера строки. Когда строка слишком длинная, для хранения вне страницы выбираются самые длинные столбцы, пока запись индекса кластеризации не поместится на страницу. Столбцы TEXT и BLOB, которые не превышают 40 байтов, хранятся в строке.

Формат строки DYNAMIC сохраняет эффективность хранения всей строки в узле индекса, если она помещается (как и форматы COMPACT и REDUNDANT), но формат строки DYNAMIC избегает проблемы заполнения узлов B-дерева большим количеством байтов данных длинных столбцов. Формат строки DYNAMIC основан на идее о том, что если часть длинного значения данных хранится вне страницы, то, как правило, эффективнее хранить все значение вне страницы. С форматом DYNAMIC более короткие столбцы, скорее всего, останутся в узле B-дерева, сводя к минимуму количество страниц переполнения, необходимых для данной строки.

Формат строки DYNAMIC поддерживает префиксы ключей индексов до 3072 байтов. Эта функция контролируется переменной innodb_large_prefix, которая включена по умолчанию. Подробнее см. описание переменной innodb_large_prefix.

Таблицы, использующие формат строки DYNAMIC, могут храниться в системном табличном пространстве, табличных пространствах на основе файлов на таблицу и общих табличных пространствах. Для хранения таблиц DYNAMIC в системном табличном пространстве либо отключите innodb_file_per_table и используйте обычное CREATE TABLE или ALTER TABLE заявление, либо используйте параметр таблицы TABLESPACE [=] innodb_system с CREATE TABLE или ALTER TABLE. Переменные innodb_file_per_table и innodb_file_format не применимы к общим табличным пространствам, а также не применимы при использовании параметра таблицы TABLESPACE [=] innodb_system для хранения таблиц DYNAMIC в системном табличном пространстве.

Характеристики хранения формата строк DYNAMIC

Формат строки DYNAMIC является вариантом формата строки COMPACT. Характеристики хранения см. в Характеристики хранения формата строки COMPACT.

Формат строк COMPRESSED

Формат строки COMPRESSED предлагает те же характеристики и возможности хранения, что и формат строки DYNAMIC, но добавляет поддержку сжатия данных таблицы и индекса.

Формат файла Barracuda поддерживает формат строки COMPRESSED. Смотрите Раздел 14.10, «Управление форматом файлов InnoDB».

Формат строки COMPRESSED использует аналогичные внутренние данные для хранения вне страницы, как формат строки DYNAMIC, с дополнительными соображениями по хранению и производительности, связанными со сжатием данных таблицы и индекса и использованием меньших размеров страниц. С форматом строки COMPRESSED параметр KEY_BLOCK_SIZE контролирует, сколько данных столбцов хранится в индексе кластеризации и сколько размещается на страницах переполнения. Дополнительную информацию о формате строки COMPRESSED см. в Разделе 14.9, «Сжатие таблиц и страниц InnoDB».

Формат строки COMPRESSED поддерживает префиксы ключей индексов до 3072 байтов. Эта функция контролируется переменной innodb_large_prefix, которая включена по умолчанию. Подробнее см. описание переменной innodb_large_prefix.

Таблицы, использующие формат строки COMPRESSED, могут быть созданы в табличных пространствах на основе файлов на таблицу или общих табличных пространствах. Системное табличное пространство не поддерживает формат строки COMPRESSED. Чтобы сохранить таблицу COMPRESSED в табличном пространстве на основе файлов на таблицу, переменная innodb_file_per_table должна быть включена, а innodb_file_format должна быть установлена на Barracuda. Переменные innodb_file_per_table и innodb_file_format не применимы к общим табличным пространствам. Общие табличные пространства поддерживают все форматы строк с оговоркой, что сжатые и несжатые таблицы не могут сосуществовать в одном общем табличном пространстве из-за разного размера физических страниц. Дополнительную информацию см. в Разделе 14.6.3.3, «Общие табличные пространства».

Характеристики хранения формата строк COMPRESSED

Формат строки COMPRESSED является вариантом формата строки COMPACT. Характеристики хранения см. в Характеристики хранения формата строки COMPACT.

END_OF_DOCUMENT_MARKER

Определение формата строк таблицы

По умолчанию формат строк для InnoDB таблиц определяется переменной 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 или ALGORITHM=INPLACE, где требуется ребилдинг таблицы. Подробнее см. Раздел 14.13.1, «Online DDL Operations». 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
  FILE_FORMAT: Barracuda
   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
  FILE_FORMAT: Antelope
   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)));
    

    Для дополнительной информации см. Раздел 14.23, «InnoDB Limits».

  • Импорт таблицы, которая не определяет явно формат строк, приводит к ошибке несоответствия схемы, если значение innodb_default_row_format на сервере-источнике отличается от значения на сервере назначения. Для получения дополнительной информации см. Раздел 14.6.1.3, «Импорт InnoDB таблиц».

Определение формата строк таблицы

Для определения формата строк таблицы используйте 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:

В качестве альтернативы можно запросить таблицу INNODB_SYS_TABLES схемы Information Schema:

mysql> SELECT NAME, ROW_FORMAT FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME='test1/t1';
+----------+------------+
| NAME     | ROW_FORMAT |
+----------+------------+
| test1/t1 | Dynamic    |
+----------+------------+

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/innodb-row-format.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API