Таблицы MyISAM


Тип таблиц MyISAM принят по умолчанию в MySQL версии 3.23. Он основывается на коде ISAM и обладает в сравнении с ним большим количеством полезных дополнений.

Индекс хранится в файле с расширением .MYI (MYIndex), а данные - в файле с расширением .MYD (MYData). Таблицы MyISAM можно проверять/восстанавливать при помощи утилиты myisamchk. Использование myisamchk для послеаварийного восстановления. Таблицы MyISAM можно сжимать при помощи команды myisampack, после чего они будут занимать намного меньше места. myisampack, MySQL-генератор сжатых таблиц (только для чтения).

Новшества, которыми обладает тип MyISAM:

  • Флаг в файле MyISAM, указывающий, правильно была закрыта таблица или нет. В случае запуска mysqld с параметром --myisam-recover таблицы MyISAM будут автоматически проверяться и/или восстанавливаться при открытии, если таблица была закрыта неправильно.

  • При помощи команды INSERT можно вставлять новые строки в таблицу, в середине файла данных которой нет свободных блоков, в то время как другие потоки считывают из таблицы информацию (совмещенная вставка). Свободный блок может быть получен при обновлении строки с динамической длиной, когда большее количество данных заменяется меньшим количеством или при удалении строк. Когда свободных блоков не остается, все последующие блоки снова будут вставляться как совмещенные.

  • Поддержка больших файлов (63 бита) в файловых/операционных системах, которые поддерживают большие файлы.

  • Хранение всех данных осуществляется с первым младшим байтом. Это делает данные независимыми от операционной системы. Единственное требование - в компьютере должны применяться дополненные до двух байтов целые числа со знаком (как и во всех компьютерах в последние 20 лет) и формат с плавающей единичной запятой IEEE (также использующийся в подавляющем большинстве серийных компьютеров). Единственными компьютерами, которые могут не поддерживать бинарную совместимость, являются встроенные системы (поскольку в них иногда применяются специальные процессоры). При хранении данных с первым младшим байтом не происходит снижения скорости. Обычно байты в строке таблицы не выровнены и нет большой разницы в том, как прочитать невыровненный байт - в прямой последовательности или в обратной. Фактическое время извлечения значения столбца также не критично по сравнению со временем выполнения остального кода.

  • Все ключи номеров хранятся с первым старшим байтом, чтобы сжатие индексов было более эффективным.

  • Внутренняя обработка столбца AUTO_INCREMENT. MyISAM автоматически обновляет его при выполнении команд INSERT/UPDATE. Значение AUTO_INCREMENT может быть обнулено оператором myisamchk. После этого столбец AUTO_INCREMENT будет быстрее (по крайней мере на 10%) и старые номера не будут повторно использоваться, как со старым ISAM. Обратите внимание: когда AUTO_INCREMENT задан в конце составного ключа, старое поведение все еще сохраняется.

  • При вставке в отсортированном порядке (как при использовании столбца AUTO_INCREMENT) дерево ключей будет разделено таким образом, чтобы верхний узел содержал только один ключ. При этом сокращается расход пространства памяти в дереве ключей.

  • Столбцы BLOB и TEXT могут быть проиндексированы.

  • В индексных столбцах разрешены значения NULL. Они занимают 0-1 байта на ключ.

  • По умолчанию максимальная длина ключа составляет 500 байтов (это значение может быть изменено при повторной компиляции). В случаях, когда ключи больше 250 байтов, для них используются большие размеры блока ключа, чем предусмотренные по умолчанию 1024 байта.

  • По умолчанию в таблице может быть не более 32 ключей. Это значение можно увеличить до 64 без повторной компиляции myisamchk.

  • myisamchk будет отмечать таблицы как проверенные, если они запускаются с параметром --update-state. myisamchk --fast будет проверять только те таблицы, в которых отсутствует данная пометка.

  • myisamchk -a сохраняет статистические данные по частям ключа (не только для ключей целиком, как в ISAM).

  • Строки с динамическим размером будут менее фрагментированными, чем при смешивании удалений с обновлениями и вставками. Это осуществляется путем автоматического сочетания удаленных смежных блоков и расширением блоков, если следующий блок удален.

  • myisampack может упаковывать столбцы BLOB и VARCHAR.

  • Можно поместить файл данных и файл индексов в разные каталоги, чтобы увеличить скорость (с параметром DATA/INDEX DIRECTORY="path" для CREATE TABLE). Синтаксис оператора CREATE TABLE.

MyISAM также поддерживает следующие функции, которые можно будет использовать в MySQL в ближайшем будущем:

  • Поддержка типа VARCHAR; столбец VARCHAR начинается с длины, которая хранится в 2 байтах.

  • Таблицы с VARCHAR могут иметь фиксированную или динамическую длину записей.

  • VARCHAR и CHAR могут быть до 64 Кб длиной. У всех ключевых сегментов есть свои собственные определения языка. Это позволяет задавать в MySQL различные определения языка для каждого столбца.

  • Для UNIQUE может использоваться вычисленный хэш-индекс. Это позволяет использовать UNIQUE с любым сочетанием столбцов в таблице (тем не менее, нельзя производить поиск по вычисленному UNIQUE индексу).

Обратите внимание, что индексные файлы при использовании MyISAM обычно намного меньше в сравнении с ISAM. Это означает, что для MyISAM обычно задействуется меньше системных ресурсов, чем для ISAM, но больше загружается процессор при вставке данных в сжатый индекс.

Приведенные ниже параметры mysqld могут использоваться для изменения поведения таблиц MyISAM. SHOW VARIABLES.

Параметр Описание
--myisam-recover=# Автоматическое восстановление таблиц после сбоя.
-O myisam_sort_buffer_size=# При восстановлении таблиц используется буфер.
--delay-key-write=ALL Не сбрасывать на диск ключевые буферы между записями для любых таблиц MyISAM
-O myisam_max_extra_sort_file_size=# Используется, чтобы помочь MySQL выбрать, когда использовать медленный, но надежный метод создания индекса кэша ключей. Обратите внимание на то, что этот параметр задается в мегабайтах!
-O myisam_max_sort_file_size=# Не использовать метод быстрой сортировки индекса для созданных индексов, если временный файл превысит этот размер. Обратите внимание на то, что этот параметр задается в мегабайтах!
-O bulk_insert_buffer_size=# Размер кэша дерева, используемого при оптимизации групповых вставок. Обратите внимание: это ограничение на поток!

Автоматическое восстановление активизируется при запуске mysqld с параметром --myisam-recover=# (Параметры командной строки mysqld). Когда таблица открывается, производится проверка, не помечена ли она как сбойная, не равна ли переменная счетчика открытий таблицы нулю (0) и не производится ли запуск с параметром --skip-external-locking. Если хотя бы одно из этих условий выполняется, произойдет следующее:

  • Будет произведена проверка таблицы на наличие ошибок;

  • Если обнаружится ошибка, будет произведена попытка быстрого восстановления (с сортировкой и без повторного создания файла данных) таблицы;

  • Если восстановление не удалось из-за ошибки в файле данных (например, ошибка дублирующегося ключа), будет произведена вторая попытка, но на этот раз с повторным созданием файла данных.

  • Если восстановление не удастся, будет произведена еще одна попытка с применением старого метода восстановления (запись по строкам без сортировки), который обеспечивает устранение ошибок любого типа с использованием незначительных ресурсов диска.

Если не удается восстановить все строки из предыдущего выполненного оператора, и не был указан параметр FORCE для myisam-recover, автоматическое восстановление будет отменено со следующей ошибкой в файле ошибок:

Error: Couldn't repair table: test.g00pages

Если в этом случае был указан параметр FORCE, вместо вышеуказанного сообщения в файле ошибок будет присутствовать следующее предупреждение:

Warning: Found 344 of 354 rows when repairing ./test/g00pages

Обратите внимание: если запустить автоматическое восстановление с параметром BACKUP, необходимо установить скрипт cron, который автоматически перемещает файлы с именами tablename-datetime.BAK из каталогов базы данных на носитель резервного копирования.

Параметры командной строки mysqld.