У меня есть серверная система, работающая на Mac OS X 10.4 (Darwin Kernel Version 8.10.1). Этот сервер используется в основном как сервер Bugzilla, но есть и другие запущенные веб-службы (Testlink, TikiWiki).
В базе данных Bugzilla около 60000 ошибок, а в системе около 300 активных пользователей.
Bugzilla находится в версии 3.0, работает на Perl 5.8.6, Apache 1.3.33 с mySQL 5.0.38
Время от времени у нас возникают серьезные проблемы из-за того, что Bugzilla выдает ошибку базы данных:
Software error:
Can't connect to the database.
Error: Too many connections
У меня уже есть несколько выводов о возможных решениях этой проблемы, но я хотел поднять более общий вопрос, как вы будете отлаживать эти типы проблем?
Прямо сейчас мы настроили следующее для мониторинга базы данных mySQL:
Мы только начали собирать эти данные, чтобы увидеть, сможем ли мы найти причину проблемы «Слишком много соединений».
Можно ли еще что-нибудь придумать для мониторинга базы данных mySQL и для диагностики основной причины проблемы?
Есть два различных плана атаки, которые необходимо выполнить при диагностике этих типов ошибок:
во-первыхсуществует вероятность того, что это проблема, связанная с фактическим используемым программным обеспечением: что-то, по сути, поглощает соединения и не освобождает их обратно (либо вообще с точки зрения зависания потока, либо в течение разумного периода времени с точки зрения медленный запрос).
Журнал медленных запросов очень полезен при диагностике проблем, но ваше значение 15 секунд почти бесполезно: если запрос занимает 15 секунд, то вы довольно сильно облажались. Как правило, я ищу запросы, выполнение которых занимает более одной или двух секунд. Проработайте все, что отображается в этом журнале, используя ключевое слово EXPLAIN, и посмотрите, что вызывает замедление (плохие соединения, сортировка, требующая временной таблицы и т. Д.) - некоторая умная магия с кешированием запросов и индексами часто может помочь, если это невозможно пойдите глубже и возитесь с дизайном кода / базы данных.
Также не упускайте из виду общий журнал запросов в mysql. Хотя вы не захотите оставлять его включенным (надолго) на производственном сервере, он может быстро сказать вам, если вместо одного запроса, принимающего возраст, конкретная функция в программном обеспечении забивает базу данных сотнями небольших запросы. Очевидно, что единственный способ решить подобные проблемы - это рефакторинг кода.
Во-вторых, вам необходимо выяснить, виновата ли конфигурация программного обеспечения. Сколько одновременных подключений вы используете? Каково фактическое количество максимальных подключений, установленных в mysql. Это может быть что-то столь же простое, как apache обслуживает, скажем, 100 одновременных запросов, в то время как mysql настроен только на прием 20 соединений - очевидно, что что-то даст. Если вы можете оценить, какой объем трафика вы ожидаете обработать, то для балансировки всех компонентов достаточно здравого смысла (а иногда и рывка Google, чтобы найти правильную настройку).
Сколько у вас рабочих apache? Какое максимальное количество подключений mysql вы разрешили? Поскольку apache порождает процесс cgi для каждого работника httpd при обработке запроса, тогда, если первый больше, чем второй, apache может открыть больше соединений, чем позволяет mysql.
Я бы предложил следующие настройки ведения журнала
log_slow_queries
log-queries-not-using-indexes
set-variable = long_query_time=1
Работа cron для сброса очень полезна, но на тот случай, если у вас нет ничего готового для построения графика, я могу порекомендовать Мунин который имеет плагины MySQL для мониторинга
что может быть весьма полезно для определения шипов. По умолчанию я бегаю с интервалом в пять минут.
Пользуясь им за последний год, я обнаружил довольно интересную ситуацию с ним раньше, которая иначе осталась бы совершенно незамеченной.