Это сообщение написано Дэвидом Басби из блога MySQL Performance.
У одного из наших клиентов службы удаленных администраторов баз данных недавно возникла проблема с размером на диске для конкретной таблицы; короче говоря, в этой таблице было около 25 миллионов строк данных аудита приложений с размером диска 345 ГБ, записанных исключительно для целей отладки, которая может происходить или не происходить.
Столкнувшись с задачей уменьшения размера диска и обеспечения постоянной доступности данных (строго исключая архив устройства), мы начали изучать доступные варианты для клиента.
Мы остановились на следующих вариантах дальнейшего тестирования.
- Встроенное сжатие строк InnoDB
- Встроенная в MySQL функция compress (), использующая zlib для сжатия данных.
- Механизм хранения архива 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.