Симптомы приходят вместе: сайт еле ворочается, в top во главе списка стоит mysqld или mariadbd, а иногда приложение сообщает «Too many connections». Идёт ли речь о высокой загрузке CPU в MySQL или о высокой загрузке CPU в MariaDB, причина редко в слишком слабом сервере. Гораздо чаще несколько запросов выполняют гораздо больше работы, чем должны, а всё остальное стоит за ними в очереди. В этом руководстве разбирается диагностика на актуальных релизах, таких как MySQL 8.4 и MariaDB 11: от первого взгляда в реальном времени до прочного решения.
Шаг 1: посмотрите, что сейчас вызывает высокую загрузку CPU в MySQL
Подключитесь консольным клиентом (в MariaDB он называется mariadb) и выполните SHOW FULL PROCESSLIST. Каждая строка — это соединение: сколько времени выполняется его текущий оператор, его состояние и полный текст запроса. Закономерности быстро бросаются в глаза:
- Десятки копий одного и того же запроса, каждая выполняется секундами: один дорогой запрос, на который попадает обычный трафик.
- Много соединений в состоянии Sleep: приложение открывает соединения и не закрывает их, либо его пул слишком велик.
- Состояния вроде "Waiting for table metadata lock": изменение схемы или долгая транзакция блокирует всех остальных.
- Состояния сортировки и временных таблиц на множестве строк: группировка или сортировка без подходящего индекса.
Картину дополняют два счётчика состояния. Threads_running показывает, сколько запросов выполняется в данный момент, а Max_used_connections — пик с последнего перезапуска. Сервер с несколькими ядрами CPU и десятками работающих потоков перегружен запросами, а не посетителями.
Шаг 2: включите журнал медленных запросов MySQL
Моментальный снимок показывает кризис; журнал медленных запросов MySQL показывает закономерность. Включите его, задав slow_query_log в ON и long_query_time около одной секунды для начала, а затем снижайте порог, когда будут устранены худшие нарушители. Обе настройки можно менять во время работы и закрепить в конфигурационном файле сервера. MariaDB использует те же имена переменных и объясняет параметры в своём обзоре журнала медленных запросов.
Оставьте журнал включённым на несколько репрезентативных напряжённых дней, а затем сведите его. mysqldumpslow (в MariaDB — mariadb-dumpslow) группирует похожие операторы, а pt-query-digest из Percona Toolkit даёт более подробный рейтинг. Сортируйте по суммарному времени, а не по самому медленному одиночному запросу: оператор, который занимает 0.2 секунды, но выполняется при каждом просмотре страницы, обходится намного дороже ночного отчёта.
Шаг 3: исправьте запросы, которые имеют значение
Для каждого запроса из верха списка выполните EXPLAIN и прочтите, что планирует сделать оптимизатор. Обычное исправление медленных запросов — одно из следующих:
- Отсутствующий или неподходящий индекс. Полное сканирование таблицы, обозначаемое type ALL, по большой таблице, где составной индекс по фильтруемым и сортируемым столбцам нашёл бы строки напрямую.
- Функция над индексированным столбцом, например столбец с временной меткой, обёрнутый в функцию даты внутри условия WHERE, из-за чего индекс не используется. Исправляет переписывание условия в виде диапазона.
- Ведущие подстановочные знаки в поиске LIKE, с которыми не поможет ни один обычный индекс. Настоящее решение — полнотекстовый индекс или поисковый сервис.
- Один и тот же небольшой запрос, повторённый сотни раз на страницу, типичный для плагинов и циклов приложения, лучше решается кешированием в самом приложении.
Сначала проверяйте изменения индексов на копии базы данных. Каждый индекс ускоряет одни чтения, но добавляет работу при каждой вставке и обновлении, а построение индекса на очень большой таблице может замедлять её, пока идёт построение.
Почему «Too many connections» — обычно симптом
Эта ошибка означает, что использованы все разрешённые соединения. Значение max_connections по умолчанию и в MySQL, и в MariaDB — 151, и увеличить его очень заманчиво. Но каждое соединение требует памяти, а большее число одновременных запросов на тех же ядрах CPU лишь замедляет каждый из них. Лучше ищите причину слишком большого числа соединений:
- Медленные запросы, удерживающие соединения открытыми, что возвращает нас к шагу 3.
- Больше воркеров PHP-FPM или потоков приложения, чем база данных может обслужить одновременно. Веб-уровень нужно рассчитывать так, чтобы его пик укладывался в max_connections, оставляя запас для администрирования.
- Простаивающие соединения, которые часами держатся открытыми из-за постоянных соединений или слишком большого пула; управляются они wait_timeout и настройками пула в приложении.
Проверка конфигурации и настройка производительности MariaDB
Когда запросы под контролем, проверьте настройки, определяющие, насколько тяжело приходится работать серверу баз данных. Буферный пул InnoDB должен вмещать регулярно используемые данные, чтобы чтение шло из памяти, а не с диска. Временные таблицы, сбрасываемые на диск, видны по счётчику Created_tmp_disk_tables. Эти проверки составляют ядро анализа производительности MySQL и MariaDB. Кеш запросов — не решение: в MySQL 8 его удалили, а MariaDB поставляется с отключённым кешем, потому что на нагруженных серверах он становится точкой конкуренции. Для настройки производительности MariaDB на серверах с множеством коротких соединений стоит присмотреться к пулу потоков. И если вы всё ещё используете MySQL 8.0, учтите, что Oracle прекратила его поддержку в апреле 2026 года; 8.4 — релиз с долгосрочной поддержкой, на который переходит большинство серверов с 8.0, а обновление — хороший повод перепроверить планы запросов.
Часто задаваемые вопросы: высокая загрузка CPU в MySQL
Всегда ли высокая загрузка CPU — проблема базы данных?
Нет. Если mysqld или mariadbd не находится в верхней части списка процессов, смотрите в сторону PHP, веб-сервера или задания резервного копирования. База данных — вероятный виновник, когда её процесс доминирует, а в списке процессов видно, как копятся запросы.
Нужно ли перезапускать MySQL, когда CPU загружен на максимум?
Перезапуск ненадолго очищает очередь, но те же запросы возвращаются вместе с трафиком, а перезапуск ещё и опустошает буферный пул, поэтому сервер работает медленнее, пока не прогреется снова. Сначала сохраните вывод SHOW FULL PROCESSLIST, чтобы не потерять улики.
Можно ли безопасно прервать долго выполняющийся запрос?
KILL QUERY с ID соединения из списка процессов останавливает оператор и оставляет соединение открытым, а KILL завершает соединение. Остановка крупной записи может занять время, потому что её изменения откатываются, и она не устраняет причину, поэтому запишите запрос, прежде чем прерывать его.
Если база данных в Лос-Анджелесе или где-либо ещё постоянно перегревается, наша услуга оптимизации баз данных MySQL и MariaDB включает анализ журнала медленных запросов, индексов и конфигурации, причём большая часть времени уходит на сбор журнала за несколько напряжённых дней, а не на сами изменения. Когда вторая половина проблемы — веб-сервер, посмотрите нашу услугу оптимизации веб-сервера Apache. Свяжитесь с нами, указав версию вашей базы данных и описав, когда происходят замедления.




