Статьи

Приключения в Архивации

Это сообщение написано Дэвидом Басби из блога MySQL Performance.

У одного из наших клиентов службы удаленных администраторов баз данных недавно возникла проблема с размером на диске для конкретной таблицы; короче говоря, в этой таблице было около 25 миллионов строк данных аудита приложений с размером диска 345 ГБ, записанных исключительно для целей отладки, которая может происходить или не происходить.

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

Мы остановились на следующих вариантах дальнейшего тестирования.

  1. Встроенное сжатие строк InnoDB
  2. Встроенная в MySQL  функция compress (), использующая zlib для сжатия данных.
  3. Механизм хранения архива MySQL.

механическая обработка

Фаза инструментария состояла из создания сценариев для генерации репрезентативных полезных нагрузок для сравнения, в этом случае это были бы некоторые данные IMDB XML, разрезанные так, чтобы они помещались в поля VARCHAR (1000) для требований клиента.

Сначала с таблиц схемы.

CREATE TABLE `archive_table` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `dat` varchar(1000) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=ARCHIVE DEFAULT CHARSET=latin1;
CREATE TABLE `compressed_data` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `dat` blob,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `compressed_row` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `dat` varchar(1000) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4;
CREATE TABLE `non_compressed_data` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `dat` varchar(1000) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Как видно, у нас есть следующее:

  • archive_table (единственное изменение здесь — Двигатель)
  • сжатые_данные (здесь изменение VARCHAR (1000) -> BLOB для целей использования  compress ()  )
  • compress_row (Формат строки, установленный на сжатый, убедитесь, что у вас есть innodb_file_format Barracuda, так как Антилопа не поддерживает сжатие)
  • non_compressed_data (наш тестовый элемент управления)

Теперь нам нужно было сгенерировать данные «полезной нагрузки» для этого. Я быстро создал сценарий bash для задачи, чтобы обеспечить приблизительно 1 млн строк на таблицу.

Скрипты доступны на GitHub

Сценарий adventures_in_archiving_load_schema.sh сначала удалится и создаст схему adventures_in_archiving.

Затем он попытается восстановить файл полезных данных adventures_in_archiving_data.sql (4 ГБ), если он не существует в текущей папке.

Последующая загрузка полезной нагрузки в схему adventures_in_archiving , однако, это не быстрый процесс, требующий около 4 минут для генерации данных и последующих 63 минут для импорта.

Полученные результаты

Размер на диске двигатель Коэффициент сжатия
7,1 Архив 173,07: 1
304M InnoDB row_format = сжатый ключ_блок_размер = 4 4,04: 1
648M компресс() 1,897: 1
1.2G InnoDB 1: 1

Сразу же архив показался очевидным выбором, однако есть ошибки, которые следует принять во внимание.

Юридическая экспертиза

Ниже приведен список, который наиболее вероятно повлияет на производственные развертывания.

  • Использование автоинкремента не рекомендуется. # 37182   # 37871  # 40216
  • Если уровень диска уже критичен, а исходной таблицей является MyISAM, может быть потеря данных, если недостаточно места для завершения операции.  # 37648
  • Использование INSERT DELAYED не рекомендуется. # 48339
  • Использование репликации на основе операторов не рекомендуется. # 48343
  • Очистите буферы перед попыткой проверки контрольной суммы таблицы. # 57188
  • Инструменты восстановления не будут работать с архивными таблицами. # 62054

Резюме

Архивирование в этом случае является решением проблемы дискового хранилища, однако вы всегда должны учитывать недостатки и ошибки, связанные с механизмом хранения, прежде чем приступить к его использованию. Также вы должны знать, что архив не имеет хорошей производительности.

например

mysql> select id from archive_table order by id desc limit 1;
+---------+
| id      |
+---------+
| 1143883 |
+---------+
1 row in set (2.04 sec)
mysql> select id from compressed_row order by id desc limit 1;
+---------+
| id      |
+---------+
| 1143883 |
+---------+
1 row in set (0.00 sec)

Также вы должны очистить буфер, например, запустив команду select в таблице, прежде чем вставки будут записаны на диск.

Следовать за

Было сделано несколько альтернативных предложений, поэтому в скором времени будет опубликована статья, в которой мы кратко рассмотрим размер диска для TokuDB и Infobright.