Ошибка MySQL «Слишком много соединений»
-
05-07-2019 - |
Вопрос
Я использую MySQL 5.0 для сайта, размещенного на GoDaddy (Linux).
Я проводил тестирование своего веб-приложения и внезапно заметил, что страницы обновляются очень медленно.Наконец, после долгого ожидания, я добрался до страницы, на которой говорилось что-то вроде «Ошибка MySQL, слишком много подключений...», и она указывала на мой файл config.php, который подключается к базе данных.
К базе данных подключался только я, других пользователей нет.На каждой из моих страниц я включаю файл config.php вверху и закрываю соединение MySQL в конце страницы.Между ними может быть несколько запросов.Я боюсь, что недостаточно закрываю соединения MySQL (mysql_close()).
Однако когда я пытаюсь закрыть их после выполнения запроса, я получаю ошибки подключения на странице.Мои страницы PHP и HTML.Когда я пытаюсь закрыть запрос, кажется, что следующий не подключается.Придется ли мне снова включать config.php после закрытия, чтобы подключиться?
Эта ошибка меня напугала, потому что за 2 недели этим веб-приложением начали пользоваться около 84 человек.
Спасибо.
РЕДАКТИРОВАТЬ:
Вот псевдокод моей страницы:
require_once('../scripts/config.php');
<?php
mysql_query..
if(this button is pressed){
mysql_query...
}
if(this button is pressed){
mysql_query...
}
if(this button is pressed){
mysql_query...
}
?>
some html..
..
..
..
..
<?php
another mysql_query...
?>
some more html..
..
..
<?php mysql_close(); ?>
Я понял, что таким образом каждый раз, когда открывается страница, открывается соединение, а затем соединение закрывается, когда страница загружается.Затем соединение открывается снова, когда кто-то нажимает кнопку на странице, и так далее...
РЕДАКТИРОВАТЬ:
Хорошо, я только что разговаривал по телефону с GoDaddy.Судя по всему, с моим Эконом-пакетом я ограничен 50 подключениями одновременно.Хотя сегодняшняя проблема возникла, когда доступ к сайту получил только я, они сказали, что раньше у них были проблемы с сервером.Однако, учитывая, что у моего веб-приложения будет 84 пользователя, мне, вероятно, следует перейти на «Deluxe», который позволяет поддерживать 100 подключений одновременно.В определенный день к моему сайту может одновременно получить доступ около 30 пользователей, поэтому я думаю, что 100 будут более безопасным выбором.Ребята, вы согласны?
Решение
Поставщики виртуального хостинга обычно допускают довольно небольшое количество одновременных подключений для одного и того же пользователя.
Что делает ваш код:
- открыть соединение с сервером MySQL
- делай свое дело (генерируй страницу)
- закройте соединение в конце страницы.
Последний шаг, выполненный в конце страницы, не обязательный :(цитирую mysql_close
руководство):
Использование mysql_close() обычно не необходимо, так как непостоянное открытое ссылки автоматически закрываются на конец исполнения сценария.
Но учтите, что вам, вероятно, все равно не следует использовать постоянные соединения...
Два совета:
- использовать
mysql_connect
внутриmysql_pconnect
(уже ок для тебя) - Установите для четвертого параметра mysql_connect значение false (вас уже устраивает, так как это значение по умолчанию) :(цитата по мануалу):
Если второй звонок сделан на mysql_connect() с тем же аргументы, новая ссылка не будет установлено, но вместо этого, ссылка идентификатор уже открытой ссылки будет возвращен.
Новая_ссылка параметр изменяет это поведение и mysql_connect() всегда открывает новая ссылка, даже если mysql_connect() был вызванный раньше с тем же параметры.
Что же тогда может вызвать проблему?
Возможно, вы пытаетесь получить доступ к нескольким страницам одновременно. (например, используя несколько вкладок в браузере), который будет имитировать одновременное использование веб-сайта несколькими пользователями?
Если у вас много пользователей, использующих сайт одновременно, и код между mysql_connect
и закрытие соединения занимает много времени, это будет означать, что одновременно открывается множество соединений...И ты достигнешь предела :-(
Тем не менее, поскольку вы единственный пользователь приложения, учитывая, что у вас разрешено до 200 одновременных подключений, происходит что-то странное...
Ну, подумав о "Слишком много соединений" и "max_connections
"...
Если я правильно помню, max_connections
не ограничивает количество подключений ты может открыться на сервере MySQL, но общее количество подключений который можно открыть на этом сервере, кем-либо, подключающимся к нему.
Цитирование документации MySQL по Слишком много соединений :
Если вы получаете слишком много соединений ошибка при попытке подключиться к mysqld сервер, это означает, что все доступные соединения используются другие клиенты.
Количество разрешенных подключений: контролируется max_connections переменная системы.Значение по умолчанию: 100.Если вам нужно поддерживать больше соединений, вы должны установить больший значение для этой переменной.
Итак, на самом деле проблема может исходить не от вас и не от вашего кода. (что на самом деле выглядит нормально) :возможно, «просто» вы не единственный, кто пытается подключиться к этому серверу MySQL. (помните, «общий хостинг»), и что слишком много людей используют его одновременно...
...И если я прав, и это все, вы ничего не можете сделать, чтобы решить проблему:пока на этом сервере слишком много баз данных/пользователей и это max_connection
установлено на 200, вы продолжите страдать...
В качестве примечания:прежде чем вернуться к GoDaddy и спросить их об этом, было бы неплохо, если бы кто-нибудь мог подтвердить то, что я только что сказал ^^
Другие советы
У меня было около 18 месяцев борьбы с этим (http://ianchanning.wordpress.com/2010/08/25/18-months-of-dealing-with-a-mysql-too-many-connections-error/)
В конечном итоге у меня были следующие решения (которые применимы к вам):
- настроить базу данных в соответствии с MySQLTuner.
- дефрагментировать таблицы еженедельно на основе этого почта
Дефрагментация bash-скрипта из поста:
#!/bin/bash
# Get a list of all fragmented tables
FRAGMENTED_TABLES="$( mysql -e `use information_schema; SELECT TABLE_SCHEMA,TABLE_NAME
FROM TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','mysql') AND
Data_free > 0` | grep -v '^+' | sed 's,t,.,' )"
for fragment in $FRAGMENTED_TABLES; do
database="$( echo $fragment | cut -d. -f1 )"
table="$( echo $fragment | cut -d. -f2 )"
[ $fragment != "TABLE_SCHEMA.TABLE_NAME" ] && mysql -e "USE $database;
OPTIMIZE TABLE $table;" > /dev/null 2>&1
done
Убедитесь, что вы не используете постоянные соединения.Обычно это плохая идея..
Если у тебя это есть..В лучшем случае вам потребуется поддерживать столько соединений, сколько у вас есть процессов Apache.Можете ли вы изменить настройку max_connections?
Вы полностью уверены, что сервер базы данных полностью посвящен вам?
Войдите в базу данных как root и используйте «SHOW PROCESSLIST», чтобы увидеть, кто подключен.В идеале подключите это к своей системе мониторинга, чтобы с течением времени отслеживать количество подключений и предупреждать, если их слишком много.
Максимальное количество подключений к базе данных можно настроить в my.cnf, но следите за нехваткой памяти или адресного пространства.
Если у вас есть доступ к оболочке, используйте netstat, чтобы узнать, сколько сокетов открыто для вашей базы данных и откуда они берутся.
В Linux введите:
netstat -n -a |grep 3306
В Windows введите:
netstat -n -a |findstr 3306
Решение может быть одно из этих, я столкнулся с этим в тесте MCQA, даже не понял какой из них правильный!
Установите это в my.cnf "set-variable=max_connections=200"
Выполните команду «SET GLOBALmax_connections = 200»
Всегда используйте функцию mysql_connect() для подключения к серверу MySQL.
Всегда используйте функцию mysql_pconnect() для подключения к серверу MySQL.
Ниже приведены возможные решения:
1) Увеличьте настройку максимального соединения, установив глобальную переменную в MySQL.
set global max_connection=200;
Примечание: Это увеличит нагрузку на сервер.
2) Очистите пул соединений, как показано ниже:
FLUSH HOSTS;
3) проверьте свой список процессов и уничтожьте конкретный список процессов, если они вам не нужны.
Вы можете сослаться на это: -