Spec-Zone .ru
спецификации, руководства, описания, API

5.4.6.5. Как Работы Сжатия для Таблиц InnoDB

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

Алгоритмы сжатия

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

MySQL реализует сжатие со справкой известной zlib библиотеки, которая реализует алгоритм сжатия LZ77. Этот алгоритм сжатия зрел, устойчив, и эффективен и в использовании ЦП и в сокращении размера данных. Алгоритм "без потерь", так, чтобы исходные несжатые данные могли всегда быть восстановлены от сжатой формы. Сжатие LZ77 работает, находя последовательности данных, которые повторяются в пределах данных, которые будут сжаты. Образцы значений в Ваших данных определяют, как хорошо они сжимаются, но типичные пользовательские данные часто сжимаются на 50 % или больше.

В отличие от сжатия, выполняемого приложением, или функциями сжатия некоторых других систем управления базами данных, сжатие InnoDB применяется и к пользовательским данным и к, индексирует. Во многих случаях, индексирует, может составить 40-50 % или больше полного размера базы данных, таким образом, это различие является существенным. Когда сжатие работает хорошо на набор данных, размер файлов данных InnoDB ( .idb файлы), 25 % к 50 % несжатого размера или возможно меньший. В зависимости от рабочей нагрузки эта меньшая база данных может поочередно привести к сокращению ввода-вывода, и увеличению пропускной способности, по скромной стоимости с точки зрения увеличенного использования ЦП. Можно скорректировать баланс между уровнем сжатия и издержками ЦП, изменяя innodb_compression_level параметр конфигурации.

Хранение данных InnoDB и Сжатие

Все пользовательские данные в таблицах InnoDB хранятся в страницах, включающих B-дерево, индексируют (кластерный индекс). В некоторых других системах баз данных этот тип индексирует, вызывается, "индексируют - организованная таблица". Каждая строка в индексировать узле содержит значения (определенный пользователем или сгенерированный системой) первичный ключ и все другие столбцы таблицы.

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

Сжатие узлов B-дерева (и кластеризируемого и вторичного индексирует) обрабатывается по-другому от сжатия страниц переполнения, используемых, чтобы хранить долго VARCHAR, BLOB, или TEXT столбцы, как объяснено в следующих разделах.

Сжатие Страниц B-дерева

Поскольку они часто обновляются, страницы 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 ВЫКЛЮЧЕНО, и последующее INSERT или UPDATE оператор пытается создать элемент индекса, который не помещается в размер сжатой страницы, сбоев работы с ERROR 42000: Row size too large. (Это сообщение об ошибке не называет индексирование, для которого запись является слишком большой, или упомяните длину индексировать записи или максимального размера записи на той определенной индексной странице.), Чтобы решить эту проблему, восстановите таблицу с ALTER TABLE и выберите больший сжатый размер страницы (KEY_BLOCK_SIZE), сократитесь, любой префикс столбца индексирует, или отключите сжатие полностью с ROW_FORMAT=DYNAMIC или ROW_FORMAT=COMPACT.

Сжимая BLOB, VARCHAR, и ТЕКСТОВЫЕ Столбцы

В таблице InnoDB, BLOB, VARCHAR, и TEXT столбцы, которые не являются частью первичного ключа, могут быть сохранены на отдельно выделенных страницах переполнения. Мы именуем эти столбцы как столбцы вне страницы. Их значения сохранены в отдельно-связанных-списках страниц переполнения.

Для таблиц, составленных в ROW_FORMAT=DYNAMIC или ROW_FORMAT=COMPRESSED, значения BLOB, TEXT, или VARCHAR столбцы могут быть сохранены полностью вне страницы, в зависимости от их длины и длины всей строки. Для столбцов, которые сохранены вне страницы, запись кластерного индекса только содержит 20-байтовые указатели на страницы переполнения, одно для каждого столбца. Сохранены ли какие-либо столбцы вне страницы, зависит от размера страницы и полного размера строки. Когда строка является слишком длинной, чтобы соответствовать полностью в пределах страницы кластерного индекса, MySQL выбирает самые длинные столбцы для хранения вне страницы до судорог строки на странице кластерного индекса. Как отмечено выше, если строка не соответствует отдельно на сжатой странице, ошибка происходит.

Таблицы, составленные в более старых версиях MySQL, используют формат файла Антилопы, который поддерживает только ROW_FORMAT=REDUNDANT и ROW_FORMAT=COMPACT. В этих форматах MySQL хранит первые 768 байтов BLOB, VARCHAR, и TEXT столбцы в кластерном индексе записывают наряду с первичным ключом. 768-байтовый префикс сопровождается 20-байтовым указателем на страницы переполнения, которые содержат остальную часть значения столбца.

Когда таблица находится в COMPRESSED формат, все данные, записанные, чтобы переполнить страниц, сжимается, "как"; то есть, MySQL применяет zlib алгоритм сжатия ко всему элементу данных. Кроме данных, сжатые страницы переполнения содержат несжатый заголовок и метку конца, включающую контрольную сумму страницы и ссылку к следующей странице переполнения, между прочим. Поэтому, очень существенные сбережения хранения могут быть получены для дольше BLOB, TEXT, или VARCHAR столбцы, если данные очень сжимаемы, как это часто бывает с текстовыми данными. Данные изображения, такой как JPEG, обычно уже сжимается и так не извлекает выгоду очень из того, чтобы быть сохраненным в сжатой таблице; двойное сжатие может потратить впустую циклы ЦП для небольших или никаких сбережений пространства.

Страницы переполнения имеют тот же самый размер как другие страницы. Строка, содержащая десять столбцов, сохраненные вне страницы, занимает десять страниц переполнения, даже если полная длина столбцов составляет только 8 k байтов. В несжатой таблице десять несжатых страниц переполнения занимают 160 K байтов. В сжатой таблице с 8 K размера страницы они занимают только 80 k байтов. Таким образом часто более эффективно использовать сжатый формат таблицы для таблиц с длинными значениями столбцов.

Используя 16 K сжатого размера страницы может уменьшить хранение и затраты ввода-вывода для BLOB, VARCHAR, или TEXT столбцы, потому что такие данные часто сжимаются хорошо, и могли бы поэтому потребовать меньшего количества страниц переполнения, даже при том, что узлы самого B-дерева берут так много страниц в качестве в несжатой форме.

Сжатие и Пул буферов InnoDB

В сжатой таблице InnoDB каждая сжатая страница (ли 1 K, 2 K, 4 K или 8 K) соответствует несжатой странице 16 K байтов (или меньший размер, если innodb_page_size устанавливается). Чтобы получить доступ к данным в странице, MySQL читает сжатую страницу из диска, если это уже не находится в пуле буферов, затем распаковывает страницу к своей исходной форме. Этот раздел описывает, как InnoDB управляет пулом буферов относительно страниц сжатых таблиц.

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

MySQL отслеживает, из которых страницы, чтобы сохранить в памяти, и чтобы можно выселить использование последнего использованного (LRU) список, так, чтобы горячий (часто получал доступ) данные имели тенденцию оставаться в памяти. Когда к сжатым таблицам получают доступ, MySQL использует адаптивный алгоритм LRU, чтобы достигнуть соответствующего баланса сжатых и несжатых страниц в памяти. Этот адаптивный алгоритм чувствителен к тому, работает ли система в I/O-bound или ограниченном ЦП способе. Цель состоит в том, чтобы избежать тратить слишком много страниц распаковки времени обработки, когда ЦП занят, и избегать делать избыточный ввод-вывод, когда у ЦП есть свободные циклы, которые могут использоваться для того, чтобы распаковать сжатые страницы (который может уже быть в памяти). Когда система является I/O-bound, алгоритм предпочитает выселять несжатую копию страницы, а не обе копии, делать больше комнаты для других дисковых страниц, чтобы стать резидентным. Когда система ограничена ЦП, MySQL предпочитает выселять обоих сжатая и несжатая страница, так, чтобы больше памяти могло использоваться для "горячих" страниц и сокращения потребности распаковать данные в памяти только в сжатой форме.

Сжатие и Файлы Журнала отката InnoDB

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

Отметьте, что сжатые таблицы используют различный формат файла для журнала отката и табличных областей на таблицу чем в MySQL 5.1 и ранее. Резервный продукт MySQL Enterprise поддерживает этот последний формат файла Барракуды для сжатых таблиц InnoDB. Более старый InnoDB Горячий Резервный продукт может только поддержать таблицы, используя Антилопу формата файла, и таким образом не поддерживает, сжимал таблицы InnoDB.