Ошибка MySQL Слишком много подключений

Я использую 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 будет более безопасным вариантом. Вы, ребята, согласны?


person littleK    schedule 29.07.2009    source источник
comment
Это может показаться безумием, но попробуйте поставить какой-нибудь счетчик на свой метод подключения, чтобы увидеть, ДЕЙСТВИТЕЛЬНО ли он вызывается только один раз при загрузке страницы. У меня была аналогичная проблема, когда я фактически создавал новое соединение для каждого запроса, не осознавая этого. Может, стоит попробовать.   -  person Mike B    schedule 29.07.2009
comment
@Mike B отличное предложение, я обязательно попробую.   -  person littleK    schedule 29.07.2009
comment
@Michael Пожалуйста, посмотрите мою правку ..   -  person littleK    schedule 29.07.2009
comment
@Mike B Хорошо, я добавил код в свой файл config.php для записи INITIATED в файл. Затем я щелкнул по 12 ссылкам на сайте и получил 12 ИНИЦИАТИВНЫХ в файле ... Таким образом, кажется, что соединение инициируется при каждой загрузке страницы, как я и ожидал. НО, я заметил в моем config.php, что у меня было: $ connect = mysql_connect ($ dbhost, $ dbuser, $ dbpass); $ connect_sting = mysql_select_db ($ dbname); mysql_connect ($ dbhost, $ dbuser, $ dbpass) или умереть (Не удалось подключиться: .mysql_error ()); mysql_select_db ($ dbname) или умереть (mysql_error ()); Которая каждый раз открывала бы две связи ...   -  person littleK    schedule 30.07.2009


Ответы (7)


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

Что делает ваш код:

  • открыть соединение с сервером MySQL
  • делать это (создание страницы)
  • закрыть соединение в конце страницы.

Последний шаг, сделанный в конце страницы, не является обязательным: (цитируя _1 _ руководство):

Использование mysql_close () обычно не требуется, поскольку непостоянные открытые ссылки автоматически закрываются в конце выполнения скрипта.

Но учтите, что вам, вероятно, в любом случае не следует использовать постоянные соединения ...

Два совета:

  • используйте mysql_connect вместо mysql_pconnect (уже подходит для вас)
  • Установите для четвертого параметра mysql_connect значение false (для вас это уже нормально, так как это значение по умолчанию): (цитируя руководство):

Если второй вызов mysql_connect () сделан с теми же аргументами, новая ссылка не будет установлена, но вместо этого будет возвращен идентификатор ссылки уже открытой ссылки.

Параметр new_link изменяет это поведение и заставляет mysql_connect () всегда открывать новую ссылку, даже если mysql_connect () был вызван ранее с теми же параметрами.



Что же тогда могло вызвать проблему?

Может быть, вы пытаетесь получить доступ к нескольким страницам параллельно (например, используя несколько вкладок в браузере), что имитирует одновременное использование веб-сайта несколькими пользователями?

Если у вас много пользователей, использующих сайт одновременно, и код между mysql_connect и закрытием соединения занимает много времени, это будет означать, что одновременно будет открыто много соединений ... И вы достигнете предела < сильный> :-(

Тем не менее, поскольку вы единственный пользователь приложения, учитывая, что у вас разрешено до 200 одновременных подключений, происходит что-то странное ...



Ну, если подумать о "слишком много подключений" и "_5 _" ...

Если я правильно помню, max_connections не ограничивает количество подключений, которые вы можете открыть с сервером MySQL, но общее количество подключений, которые могут быть открыты для этого сервера, < strong> любым, кто к нему подключается.

Цитата из документации MySQL по Слишком много соединений:

Если при попытке подключиться к серверу mysqld вы получаете сообщение об ошибке «Слишком много подключений», это означает, что все доступные подключения используются другими клиентами.

Количество разрешенных подключений контролируется системной переменной max_connections. Его значение по умолчанию - 100. Если вам нужно поддерживать больше подключений, вы должны установить для этой переменной большее значение.

Так что на самом деле проблема может исходить не от вас, ни от вашего кода (который на самом деле выглядит нормально): возможно, «просто», что вы не единственный, кто пытается подключиться к этому серверу MySQL < em> (помните, «общий хостинг»), и что слишком много людей используют его одновременно ...

... И если я прав, и это так, вы ничего не можете сделать, чтобы решить проблему: пока на этом сервере слишком много баз данных / пользователей и для max_connection установлено значение 200 , ты и дальше будешь страдать ...


В качестве примечания: прежде чем вернуться в GoDaddy и спросить их об этом, было бы неплохо, если бы кто-нибудь мог подтвердить то, что я только что сказал ^^

person Pascal MARTIN    schedule 29.07.2009
comment
Спасибо за очень обстоятельный ответ! Я боялся, что это может быть что-то вне моего контроля ... Я рад слышать, что мой код в порядке, но мне было интересно, поможет ли это кому-нибудь создать класс-оболочку mysql, который будет подключаться к базе данных, запустить запрос, а затем закрыть соединение? Я решил, что могу попробовать это, но, судя по вашему ответу, похоже, что закрытие соединений mysql не может быть проблемой ... - person littleK; 30.07.2009
comment
Я только что опубликовал РЕДАКТИРОВАНИЕ, содержащее мой разговор с GoDaddy. - person littleK; 30.07.2009
comment
Обновление таким способом только для 84 пользователей кажется мне немного излишним (84 пользователя - это не так уж много; на тоннах веб-сайтов пользователей больше, и у них нет таких проблем) ... Если бы у них были проблемы с их сервером, вам стоит немного подождать, чтобы увидеть, как обстоят дела сейчас - person Pascal MARTIN; 30.07.2009

Я имел дело с этим около 18 месяцев ( http://ianchanning.wordpress.com/2010/08/25/18-months-of-dealing-with-a-mysql-too-many-connections-error/ < / а>)

В итоге у меня были следующие решения (которые применимы к вам):

  1. настройте базу данных в соответствии с MySQLTuner.
  2. еженедельно дефрагментируйте таблицы на основе этого сообщения

Скрипт дефрагментации 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
person icc97    schedule 26.08.2010
comment
ваша ссылка nr1 - это 404. Это был ресурс? raw.github.com/major/MySQLTuner-perl/master/mysqltuner. pl - person JP Hellemons; 23.08.2013
comment
@JPHellemons Спасибо, я исправил ссылку - mysqltuner.com перенаправляет на тот, который вы упомянули. Я оставил его как mysqltuner.com на случай, если перенаправление снова изменится - person icc97; 26.08.2013

Убедитесь, что вы не используете постоянные соединения. Обычно это плохая идея ..

Если у вас это есть ... В лучшем случае вам нужно будет поддерживать столько же соединений, сколько у вас есть процессов apache. Можете ли вы изменить настройку max_connections?

person Evert    schedule 29.07.2009
comment
Я не использую постоянные соединения. Я не могу изменить настройку max_connections, но, согласно GoDaddy: мы разрешаем до 200 одновременных подключений на одного пользователя MySQL. - person littleK; 29.07.2009
comment
Если у вас не более 200 процессов Apache, он подтвердит (как и другие упомянутые плакаты), что вы не создаете более одного соединения на запрос. - person Evert; 30.07.2009

Вы полностью уверены, что сервер базы данных полностью посвящен вам?

Войдите в базу данных как root и используйте «SHOW PROCESSLIST», чтобы увидеть, кто подключен. В идеале подключите это к своей системе мониторинга, чтобы увидеть, сколько соединений будет с течением времени, и предупредить, если их слишком много.

Максимальное количество подключений к базе данных можно настроить в my.cnf, но следите за нехваткой памяти или адресного пространства.

person MarkR    schedule 29.07.2009
comment
@MarkR К сожалению, я не могу этого сделать. Я использую Linux-хостинг GoDaddy, поэтому у меня нет выделенного или виртуального сервера, поэтому я не могу войти в систему как root ... - person littleK; 30.07.2009

Если у вас есть доступ к оболочке, используйте netstat, чтобы узнать, сколько сокетов открыто для вашей базы данных и откуда они берутся.

В Linux введите:

netstat -n -a |grep 3306

В окнах введите:

netstat -n -a |findstr 3306
person Wouter van Nifterick    schedule 30.07.2009
comment
Мне это удалось, однако я понятия не имею, как интерпретировать результаты (чтобы прийти к каким-либо значимым выводам). Я разместил их по следующей ссылке, не могли бы вы взглянуть? Я вошел на свой сайт, когда сделал netstat ... cs.scranton.edu /~behrk2/netstat_results.rtf Спасибо! - person littleK; 30.07.2009

Решение может быть одним из них, я столкнулся с этим в тесте MCQA, даже не понял, какой из них правильный!

Установите это в my.cnf "set-variable = max_connections = 200"

Выполните команду «SET GLOBALmax_connections = 200»

Всегда используйте функцию mysql_connect () для подключения к серверу mysql

Всегда используйте функцию mysql_pconnect () для подключения к серверу mysql

person Nitesh    schedule 27.02.2011

Возможны следующие решения:

1) Увеличьте максимальное количество подключений, установив глобальную переменную в mysql.

set global max_connection=200;

Примечание. Это увеличит нагрузку на сервер.

2) Очистите пул подключений, как показано ниже:

FLUSH HOSTS;

3) проверьте свой список процессов и уничтожьте определенный список процессов, если они вам не нужны.


Вы можете сослаться на это: -

ссылка на статью

person dilraj singh    schedule 19.09.2017