Интенсивная дисковая активность MySQL даже без выполнения запросов

Попытка устранить проблему с таинственным узким местом дискового ввода-вывода, вызванным MySQL.

Я использую следующие команды для проверки скорости чтения/записи диска:

#write
dd if=/dev/zero of=/tmp/writetest bs=1M count=1024 conv=fdatasync,notrunc

#read
echo 3 > /proc/sys/vm/drop_caches; dd if=/tmp/writetest of=/dev/null bs=1M count=1024

Я перезагрузил машину, отключил cron, чтобы ни один из моих обычных процессов не выполнял запросы, убил веб-сервер, который обычно работает, и убил mysqld.

Когда я запускаю тест чтения без запуска mysqld, я получаю 1073741824 bytes (1.1 GB) copied, 2.19439 s, 489 MB/s. Стабильно около 450-500 МБ/с.

Когда я запускаю резервное копирование службы mysql, а затем снова запускаю тест чтения, я получаю 1073741824 bytes (1.1 GB) copied, 135.657 s, 7.9 MB/s. Стабильно около 5 МБ/с.

Запуск show full processlist в mysql не показывает никаких запросов (и я все равно отключил все, что будет запускать запросы). На вкладке «Состояние сервера» MySQLWorkbench я вижу, что чтение InnoDB колеблется между 30–200 операциями чтения в секунду и 3–15 операциями записи в секунду, даже если запросы не выполняются.

Если я запущу iotop -oPa, я увижу, что mysqld работает со скоростью чтения диска 1 МБ в секунду, когда запросы не выполняются. Это кажется большим, учитывая, что запросы не выполняются, но в то же время этого недостаточно, чтобы моя команда dd выполнялась так долго... Единственная другая вещь, выполняющая disk io, это jbd2/sda3-8.

Не уверен, что это связано, но если я пытаюсь убить сервер mysql с помощью service mysql stop, он говорит: «Попытка остановить MySQL истекла», и процесс mysqld продолжает работать, но я больше не могу подключиться к БД. Я должен использовать kill -9, чтобы убить процесс mysqld и перезапустить сервер.

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

Как я могу узнать, почему MySQL так много читает с диска, когда он по существу простаивает?


person user1538516    schedule 28.05.2020    source источник


Ответы (2)


Вы обновляли/удаляли/вставляли большое количество строк? Если это так, рассмотрите эти задержки при записи на диск:

  • Блок, содержащий данные, не сразу записывается обратно на диск.
  • То же самое для клавиш UNIQUE.
  • Обновления вторичных индексов попадают в буфер изменений. Они складываются в блоки индексов, часто даже позже.
  • Обновления/удаления оставляют после себя список истории, который необходимо очистить после завершения транзакции.

Эти вещи обрабатываются фоновыми задачами, которые не отображаются в PROCESSLIST. Они могут быть видны в процессах mysqld, в основном как ввод-вывод. (ЦП, вероятно, минимальный.)

Был ли ROLLBACK? Сделки оптимистичны. Таким образом, ROLLBACK должен проделать большую работу, чтобы отменить то, что было оптимистично уже совершено.

Если резко убить mysqld (или отключить питание), то после перезапуска возникает ROLLBACK.

У SSD нет времени поиска. Жесткие диски должны перемещать головки чтения/записи на переменную величину; это требует времени. Если ваш dd работает на одном конце диска, а mysqld работает на другом конце, поиск увеличивает кажущееся время ввода-вывода.

person Rick James    schedule 30.05.2020

Как и многие другие проблемы с производительностью, это оказалось многогранной проблемой.

По сути, проблема заключалась в том, что ночные резервные копии системы и базы данных записывались на отдельный массив рейдов жестких дисков на следующий день, а затем мастер отправлял FLUSH TABLES и заставлял задания mysql и работу репликации ждать этого. Кроме того, ненужный побочный процесс копирует много гигабайт текстовых файлов по системе несколько раз в день. Тонны переключений контекста, поскольку система пыталась копировать данные для резервного копирования, одновременно выполняя работу mysql (репликация и другие задания).

В итоге я уменьшил количество таблиц, которые мы реплицировали (некоторые из них были ненужными), уменьшил количество копий текстовых файлов в системе, когда они не нужны, увеличил память и ввод-вывод, выделенные серверу mysql, оптимизировал резервные копии mysql и системные резервные копии и ограничил задания cron, запускающие процессы mysql, чтобы дать резервным копиям mysql больше времени для завершения. При всем этом резервное копирование едва завершалось к 7 утра каждое утро, поэтому я решил, что нам нужно запускать резервное копирование mysql только по выходным, а не по ночам, что нормально, поскольку все это довольно статические данные.

person user1538516    schedule 10.06.2020
comment
Рассмотрите возможность резервного копирования с ведомого устройства вместо ведущего. - person Rick James; 11.06.2020