MySQL: ошибка Too many connections — причины и решение
Сайт внезапно перестаёт открываться, в логах приложения — MySQL ошибка Too many connections. Это значит, что база исчерпала лимит одновременных подключений и отказывает новым. Проблема почти всегда не в том, что лимит мал, а в том, что соединения не освобождаются или их плодит приложение. Разберём, как быстро вернуть сайт к жизни и убрать причину, а не только симптом.
Содержание
- Первое действие: верните работоспособность и оцените масштаб
- Причина 1: приложение не закрывает соединения
- Причина 2: слишком низкий max_connections
- Причина 3: слишком долго живут соединения
- Причина 4: всплеск нагрузки или атака
- Как проверить, что проблема ушла
- Профилактика: чтобы подключения не кончались
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Первое действие: верните работоспособность и оцените масштаб
Сначала верните базу к работе, затем разбирайтесь. Зайдите в MySQL (у пользователя root обычно есть резервное подключение сверх лимита) и посмотрите, сколько соединений открыто и какой лимит:
SHOW STATUS LIKE 'Threads_connected';
SHOW VARIABLES LIKE 'max_connections';
SHOW PROCESSLIST;
Threads_connected покажет текущее число подключений, max_connections — лимит, а SHOW PROCESSLIST — кто эти соединения держит и в каком они состоянии. Это сразу даёт картину: если сотни соединений висят в состоянии Sleep, значит приложение открывает их и не закрывает — это утечка. Если все заняты тяжёлыми запросами — база перегружена медленными запросами. Диагноз определяет лечение: не спешите просто поднимать лимит, сначала поймите, почему соединения кончились.
Причина 1: приложение не закрывает соединения
Самый частый корень проблемы — приложение открывает подключения к базе и не закрывает их, оставляя висеть в состоянии Sleep. Со временем они накапливаются и упираются в лимит. В SHOW PROCESSLIST вы увидите множество строк со Sleep и большим значением Time. Это признак утечки соединений в коде или неверной работы с пулом. Быстро оценить долю спящих можно так:
SELECT COMMAND, COUNT(*) FROM information_schema.processlist GROUP BY COMMAND;
Если Sleep — большинство, лечите приложение: закрывайте соединения после использования, применяйте пул подключений с ограниченным размером и корректным возвратом соединений, проверяйте, что фреймворк не открывает новое подключение на каждый запрос без переиспользования. Поднятие max_connections тут лишь оттянет проблему: утечка снова заполнит и увеличенный лимит. Чинить нужно источник — работу приложения с соединениями.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать VPS под базуПричина 2: слишком низкий max_connections
Иногда лимит действительно мал для реальной нагрузки. Дефолтные 151 подключение могут не покрывать пик посещаемости легитимного, хорошо написанного приложения. Если соединения заняты делом, а не висят впустую, и вы упираетесь в лимит на пике — поднимите его с учётом памяти:
SET GLOBAL max_connections = 300;
Это применит новое значение немедленно (до перезапуска). Чтобы закрепить, пропишите max_connections в конфиге под [mysqld] и перезапустите MySQL. Важно: каждое соединение потребляет память, поэтому нельзя выставлять лимит в тысячи бездумно — иначе на пике база запросит больше RAM, чем есть, и сервер уйдёт в своп или упадёт. Поднимайте лимит соразмерно доступной памяти и размеру буферов на соединение. Это решение подходит, только когда соединения реально нужны, а не утекают.
Причина 3: слишком долго живут соединения
Соединения могут накапливаться не из-за явной утечки, а потому что висят слишком долго. Параметр wait_timeout определяет, через сколько секунд бездействия MySQL сам закроет спящее соединение. Если он огромен, спящие подключения от приложения долго занимают слоты. Проверьте и при необходимости уменьшите:
SHOW VARIABLES LIKE 'wait_timeout';
Слишком большое значение (например, 28800 секунд — 8 часов по умолчанию) означает, что забытые соединения будут висеть часами. Разумное уменьшение wait_timeout заставит базу освобождать брошенные подключения быстрее. Но это компромисс, а не панацея: если приложение активно переиспользует соединения из пула, слишком агрессивный таймаут начнёт рвать живые подключения. Настраивайте его в связке с поведением пула приложения, а не в отрыве от него.
Причина 4: всплеск нагрузки или атака
Резкий рост числа подключений бывает вызван всплеском реального трафика, запуском тяжёлого фонового процесса, который наплодил соединений, или даже атакой. Посмотрите в SHOW PROCESSLIST, откуда идут подключения и что они делают: если это лавина запросов с одного адреса или явно аномальный процесс — причина внешняя. Быстро снять давление можно, аккуратно завершив зависшие или явно лишние соединения по их id:
KILL 12345;
Завершайте только то, в чём уверены. Если это всплеск легитимного трафика — вопрос в мощности и лимитах; если аномалия — разберитесь с источником на уровне приложения или файрвола. Долгие фоновые задачи, открывающие много соединений, стоит переписать так, чтобы они работали через ограниченный пул, а не плодили подключения без счёта.
Как проверить, что проблема ушла
После правок убедитесь, что соединения перестали накапливаться. Понаблюдайте за динамикой числа подключений под нагрузкой:
SHOW STATUS LIKE 'Max_used_connections';
Max_used_connections показывает пиковое число использованных соединений с момента запуска — сравнивайте его с лимитом. Если пик держится заметно ниже max_connections и спящих соединений больше не накапливается, проблема решена по существу. Если же значение снова подбирается к лимиту — утечка или нагрузка никуда не делись, копайте дальше в приложении. Хороший признак здоровья — стабильное число активных соединений без растущего хвоста Sleep в PROCESSLIST.
Профилактика: чтобы подключения не кончались
Главная профилактика — правильная работа приложения с соединениями. Используйте пул подключений с разумным ограничением размера, всегда закрывайте или возвращайте соединения в пул после использования, не открывайте новое подключение на каждый запрос. Тогда база работает со стабильным, предсказуемым числом соединений, и лимит перестаёт быть проблемой. Настройте wait_timeout в согласии с поведением пула, чтобы брошенные соединения не висели часами.
Держите max_connections соразмерным памяти сервера и мониторьте Threads_connected и Max_used_connections — это заранее показывает приближение к лимиту. Если приложение здоровое, а нагрузка честно выросла, увеличение памяти сервера позволит поднять лимит без риска свопа. Но начинать всегда стоит с вопроса «не утекают ли соединения»: в большинстве случаев Too many connections — это симптом кода, а не слабого сервера.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать VPS под базуОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Почему возникает ошибка Too many connections?
База исчерпала лимит одновременных подключений. Чаще всего причина — приложение не закрывает соединения, и они копятся в состоянии Sleep, реже — реально высокий трафик при низком лимите.
Стоит ли просто поднять max_connections?
Только если соединения реально заняты делом, а не утекают, и есть запас памяти. При утечке увеличение лимита лишь оттянет проблему — сначала почините работу приложения с соединениями.
Как быстро вернуть сайт, если база отказывает?
Зайдите под root (у него есть резервное подключение), посмотрите SHOW PROCESSLIST, при необходимости завершите зависшие соединения через KILL id, затем разберитесь с причиной накопления.
Как оплатить более мощный сервер из России?
В MAATRIX — картой российского банка, через СБП, криптовалютой или токеном MAAT. Иностранная карта не нужна.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.