Тестирование дисков для MySQL с помощью fio

fio - это утилита для нагрузочного тестирования дисковой подсистемы.

Установить утилиту в операционной системе Debian и производных от неё можно из официальных репозиториев следующей командой:

# apt-get install fio

Для тестирования дисков понадобится шаблон, в котором будут описаны все особенности производимых тестов. Для подготовки шаблона, хотя бы в общих чертах соответствующего реальной нагрузке, стоит воспользоваться статистикой нагрузки на диски от сервера MySQL, дисковую подсистему для которого мы будем тестировать. Получить эту информацию можно, например, с помощью Zabbix. Шаблон контроля нагрузки на диски можно взять из статьи Статистика ввода-вывода diskstats в Linux через Zabbix. Нам понадобится информация:

  • о соотношении операций чтения и записи,
  • о соотношении объединённых и не объединённых операций чтения и записи.

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

Также нам понадобится информация о размере блока на диске. Сделать это можно с помощью утилиты hdparm, которую можно установить из одноимённого пакета:

# hdparm -I /dev/sda | grep Physical
    Physical Sector size:                  4096 bytes

Кроме этого нам понадобится информация о следующих настройках и свойствах MySQL:

  • Используется ли при работе с дисками кэш операционной системы. Если innodb_flush_method = O_DIRECT и tokudb_directio = ON, то кэш не используется и MySQL работает с дисками без кэша операционной системы,
  • Объём файлов баз данных,
  • Объём буферных кэшей MySQL - сумма key_buffer_size, innodb_buffer_pool_size и tokudb_cache_size, я испльзую их как объём тестовых операций,
  • Количество потоков, работающих с дисками - сумма innodb_read_io_threads, innodb_write_io_threads и innodb_purge_threads,
  • Количество одновременно открытых файлов - я использовал наименьшее из innodb_open_files и open_files_limit.

Шаблон тестирования с именем db.fio:

[db]
direct=1                 # Прямой ввод-вывод без использования кэша операционной системы - как в MySQL
readwrite=randrw         # Случайные чтения и записи - в действительности чтения случайные, а записи в основном последовательные
rwmixread=1              # Операции чтения составляют 1% от общего количества - в действительности чтений около 0,1%
percentage_random=35     # Случайных операций 35% от общего количества, остальные - последовательные - посчитано по соотношению объединәнных и не объединённых операций чтения/записи
blocksize=4k             # Размер блока файловой системы (MySQL использует 16-килобайтные блоки) - как на дисках
size=2T                  # Размер файла, внутри которого происходит тестирование - примерно как объём всей БД
io_size=128G             # Объём операций чтения/записи внутри файла - как объём буфера InnoDB
ioengine=libaio          # Асинхронные операции чтения/записи
iodepth=62               # 62 параллельно работающих потока - как количество потоков чтения, записи и очистки
directory=/srv/fio/      # Создавать файлы для теста в указанном каталоге
openfiles=8192           # Держать открытыми одновременно не более 8192 файлов
nrfiles=8192             # Объём size будет поделён на 8192 файла - как количество таблиц
filename_format=$filenum # В качестве имени файал используется его порядковый номер - так все файлы будут использоваться разными потоками
file_service_type=pareto # Распределение операций по файлам - чаще всего используется только небольшое количество таблиц, подавляющее большинство практически не используется
allow_file_create=1      # Разрешить создание файлов для проведения тестов
thread                   # Создавать параллельные потоки, а не процессы

Для запуска тестирования вызываем fio с указанием созданного шаблона:

# fio db.fio