🚦
Хостинг

Ошибка «Too many connections» в MySQL: причины и решение

10.11.2026
← Все статьи

Обычно сайт работает быстро, но в моменты наплыва посетителей вместо страниц начинает появляться ошибка базы данных, а в логе — запись Too many connections. Это значит, что сервер MySQL не может принять новое подключение: все «места» заняты, и следующий запрос отклоняется прямо на входе. Разберём, откуда берётся эта ошибка, как её диагностировать и что сделать, чтобы сайт оставался стабильным под нагрузкой.

Как устроена ошибка 1040

Параметр max_connections на сервере MySQL задаёт общее число подключений, которые могут быть открыты одновременно. Каждый PHP-процесс подключается к базе, чтобы сформировать страницу, и удерживает соединение до конца работы. Если число одновременно открытых подключений достигает лимита, новая попытка завершается ошибкой:

ERROR 1040 (HY000): Too many connections

Важно помнить, что эта ошибка относится ко всему серверу, а не к одному пользователю. При превышении лимита на уровне пользователя появляется другая ошибка — 1203 max_user_connections, а при исчерпании почасовой квоты — 1226. Поэтому точный код в логе — основа правильной диагностики.

Почему подключения заканчиваются

Многие понимают эту ошибку как «слишком много посетителей», но на практике причина чаще в том, что подключения подолгу остаются занятыми. Если страница формируется за 50 миллисекунд, сотня подключений способна обслужить тысячи запросов в секунду. Но если один медленный запрос блокирует таблицу, зависящие от неё запросы ждут в очереди, и каждый занимает своё подключение. В результате за несколько секунд заполняются все соединения.

Среди других частых причин — боты, без остановки запрашивающие одни и те же страницы, тяжёлые страницы категорий и фильтров без кеша, долгие скрипты экспорта или отчётов. Кроме того, если число PHP-воркеров больше лимита подключений базы, при росте нагрузки веб-сервер «заваливает» базу параллельными запросами, которые она не в состоянии обработать.

Команды для диагностики

Если у вас собственный VPS или административный доступ к базе, сначала посмотрите лимит и текущее состояние. Threads_connected показывает число открытых сейчас подключений, а Max_used_connections — максимум с момента запуска сервера. Если второе значение равно лимиту, сервер действительно упирался в потолок:

SHOW VARIABLES LIKE 'max_connections';
SHOW GLOBAL STATUS LIKE 'Threads_connected';
SHOW GLOBAL STATUS LIKE 'Max_used_connections';

Следующий шаг — понять, чем заняты подключения. SHOW FULL PROCESSLIST выводит для каждого соединения пользователя, время выполнения и текущий запрос. Если много запросов с большим значением Time или строк в состоянии Waiting for table metadata lock, проблема не в нагрузке, а в конкретном запросе:

SHOW FULL PROCESSLIST;
-- остановить безнадёжно зависший запрос:
KILL 48213;

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

Увеличение лимита и очистка простаивающих подключений

Лимит можно временно поднять на работающем сервере, но после перезапуска значение сбросится. Для постоянного изменения его прописывают в конфигурационном файле MySQL. Полезно также уменьшить wait_timeout: по умолчанию простаивающее соединение может оставаться открытым часами и впустую занимать место:

# временно, до перезапуска
SET GLOBAL max_connections = 300;

# постоянно: /etc/mysql/my.cnf или /etc/my.cnf, секция [mysqld]
[mysqld]
max_connections = 300
wait_timeout    = 120

# затем перезапуск (имя службы зависит от системы)
sudo systemctl restart mysql

Бездумно увеличивать лимит тоже опасно. Каждое подключение занимает память под свои буферы, поэтому на сервере с небольшим объёмом памяти и разрешённой тысячей подключений при пике нагрузки MySQL может упасть из-за нехватки памяти. Лимит нужно оценивать вместе с объёмом оперативной памяти и innodb_buffer_pool_size. На виртуальном хостинге эти настройки пользователь не меняет — ими управляет провайдер.

Что можно сделать на стороне приложения

Самое эффективное решение часто состоит в том, чтобы сократить сами обращения к базе. Следующие меры дают заметный результат даже без изменения настроек сервера:

Пример: день объявления результатов экзаменов

Сайт частной школы в Ташкенте misol.uz весь год работал без проблем. Но в день объявления результатов вступительных экзаменов тысячи родителей одновременно открыли страницу результатов, и через несколько минут сайт начал выдавать Too many connections. Проверка показала, что при каждом открытии страница перебирала всю таблицу по столбцу без индекса, и каждый запрос длился несколько секунд.

После добавления индекса время запроса упало до миллисекунд, а страницу результатов поставили в короткий кеш. Лимит подключений не меняли, но ошибка больше не возвращалась: каждое соединение теперь освобождалось мгновенно. Этот пример хорошо показывает, почему прежде чем повышать лимит, нужно выяснить, чем заняты подключения. Если сайт размещён на хостинге sayt.uz и ошибка повторяется, откройте тикет в техподдержку, указав время и адрес страницы.

Подготовка заранее

Подключения чаще всего заканчиваются во время заранее известных событий: акций, объявления результатов, рекламных кампаний. Перед такими днями стоит прогнать самые посещаемые страницы простым нагрузочным тестом, проверить работу кеша и исправить медленные запросы — тогда сайт не откажет именно в тот момент, когда он нужнее всего.

Похожие статьи

📁 Подключение к хостингу по SFTP через FileZilla и WinSCP 🗄️ Как создать базу данных и пользователя в ISPmanager 🔤 utf8mb4: как сохранить эмодзи и узбекские буквы в MySQL без искажений 📦 Next.js standalone build: меньше ресурсов и деплой на маленький сервер
🌐 Язык
🇺🇿 O'zbek 🇺🇿 Ўзбек 🇷🇺 Русский ✓ 🇬🇧 English