2009-07-29 3 views
19

Я использую MySQL 5.0 для сайта, размещенного GoDaddy (linux).Ошибка MySQL «Слишком много соединений»

Я делал некоторые тесты в своем веб-приложении, и вдруг я заметил, что страницы освежались очень медленно. Наконец, после долгого ожидания, я попал на страницу, в которой говорилось что-то вроде строк «Ошибка MySQL, слишком много соединений ...», и он указывал на мой файл config.php, который соединяется с базой данных.

Только что я подключился к базе данных, никаких других пользователей. На каждой из моих страниц я включаю файл config.php вверху и закрываю соединение mysql в конце страницы. Между ними может быть несколько запросов. Я боюсь, что я недостаточно закрываю связи mysql (mysql_close()).

Однако, когда я пытаюсь закрыть их после запуска запроса, на странице возникают ошибки подключения. Мои страницы - это PHP и HTML. Когда я пытаюсь закрыть запрос, кажется, что следующий не будет подключаться. Должен ли я включить config.php снова после закрытия, чтобы подключиться?

Эта ошибка напугала меня, потому что через 2 недели около 84 человек начинают использовать это веб-приложение.

Спасибо.

EDIT:

Вот некоторые псевдо-код моей страницы:

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(); ?> 

я понял, что этот путь, каждый раз, когда открывается страница, соединение открывается, а затем соединение закрывается, когда страница делается загрузка. Затем соединение снова открывается, когда пользователь нажимает кнопку на странице, и так далее ...

EDIT:

Хорошо, так что я только что получил по телефону с GoDaddy. По-видимому, с моим пакетом Economy я ограничился только 50 подключениями одновременно. Хотя моя проблема сегодня произошла, и только я обращался к сайту, они сказали, что раньше у них были проблемы с сервером. Однако, видя, что у меня будет 84 пользователя для моего веб-приложения, я, вероятно, должен перейти на «Делюкс», который позволяет одновременно устанавливать 100 подключений. В определенный день может быть около 30 пользователей, обращающихся к моему сайту за раз, поэтому я думаю, что 100 будет более безопасным. Вы, ребята, согласны?

+0

Вставить код пожалуйста. – Dirk

+4

Это может показаться сумасшедшим, но попробуйте поставить какой-то счетчик на свой метод подключения, чтобы увидеть, действительно ли он ДЕЙСТВИТЕЛЬНО только один раз на странице загружается. У меня была аналогичная проблема, когда я фактически создавал новое соединение для каждого запроса, не осознавая его. Возможно, стоит сделать снимок. –

+0

@ Mike B большое предложение, я обязательно попробую это. – littleK

ответ

28

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

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

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

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

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

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

Два советы:

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

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

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



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

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

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

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



Ну, думать о "слишком много соединений" и "max_connections" ...

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

Цитирование документации MySQL на Too many connections:

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

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

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

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


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

+0

Спасибо за очень тщательный ответ! Я боялся, что это может быть что-то из-под контроля ... Я рад слышать, что мой код в порядке, но мне было интересно, поможет ли ему создать класс оболочки mysql, который будет подключаться к db, запускать запрос и затем закрывать соединение? Я решил попробовать что, но, исходя из вашего ответа, похоже, что закрытие соединений mysql может не быть проблемой ... – littleK

+0

Я только что разместил EDIT, содержащий мой разговор с GoDaddy. – littleK

+0

Upg таким образом, только 84 пользователя кажутся/чувствуют себя немного излишними для меня (84 пользователей не так много; тонны веб-сайтов имеют больше пользователей, чем у них, и у них нет такой проблемы). Если у них были проблемы с их сервером, вы должны немного подождать, чтобы узнать, как это происходит, теперь –

2

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

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

+0

Я не использую постоянные соединения. Я не могу изменить настройку max_connections, но, согласно GoDaddy: «Мы разрешаем до 200 одновременных подключений для каждого пользователя MySQL.« – littleK

+0

Если у вас не более 200 процессов Apache, он будет проверять (как и другие плакаты), что вы не создаете более одного соединения для каждого запроса. – Evert

2

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

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

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

+0

@MarkR К сожалению, я не могу этого сделать. Я использую GoDaddy's Linux Hosting, поэтому у меня нет выделенного или виртуального сервера, поэтому я не могу войти в систему как root ... – littleK

2

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

В Linux введите:

netstat -n -a |grep 3306 

на окнах, типа:

netstat -n -a |findstr 3306 
+0

Я смог сделать это , однако я понятия не имею, как интерпретировать результаты (чтобы прийти к каким-либо значимым выводам). Я разместил их по следующей ссылке, не могли бы вы взглянуть? Я был зарегистрирован на моем сайте, когда я сделал netstat ... http://www.cs.scranton.edu/~behrk2/netstat_results.rtf Спасибо! – littleK

3

У меня было около 18 месяцев борьбы с этим (http://ianchanning.wordpress.com/2010/08/25/18-months-of-dealing-with-a-mysql-too-many-connections-error/)

Растворы, которые я имел (что будет применяться к вам), в конце концов:

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

Дефрагментация Баш скрипт с поста:

#!/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 
+0

Ваша ссылка nr1 - это 404. был ли этот ресурс? https://raw.github.com/major/MySQLTuner-perl/master/mysqltuner.pl –

+0

@JPHellemons Спасибо, я исправил ссылку - mysqltuner.com перенаправляет на тот, который вы упомянули. Я оставил его как mysqltuner.com, если перенаправление снова будет изменено – icc97

1

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

Установите в my.cnf "Set-переменная = max_connections = 200"

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

всегда использовать mysql_connect() функцию для того, чтобы соединиться с сервером MySQL

Используйте всегда mysql_pconnect() функция для того, чтобы соединиться с сервером MySQL

0

Подписок возможные решения:

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

set global max_connection=200; 

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

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

FLUSH HOSTS;

3) проверить PROCESSLIST и убить конкретные PROCESSLIST, если вы не хотите какой-либо из них.


Вы можете обратиться в этом: -

article link

Смежные вопросы