как определить, какой код PHP открывает соединения MySQL, которые не закрываются


У нас есть приложение, которое состоит из нескольких готовых PHP-приложений (ExpressionEngine и XCart), а также нашего собственного пользовательского кода.

Я не делал фактический анализ, поэтому я не знаю точно, как он был определен, но не удивлен, услышав, что слишком много соединений MySQL остаются незамкнутыми (я не удивлен, потому что я наблюдал значительную утечку памяти на нашем dev-сервере, где в течение дня или двух, начиная со 100 Мб на каждом сервере). начальная загрузка, весь гигабайт оперативной памяти потребляется, и очень мало из него кэшируется).

Итак, как мы можем точно определить, какой код PHP является виновником? У меня есть предыдущий опыт работы с XDebug, и я предложил, чтобы, когда мы получим нашу отдельную, промежуточную среду достаточно стабильной, мы модифицировали XDebug на dev и использовали ее для проведения некоторого анализа. Разумно ли это, и/или у кого-нибудь еще есть более конкретные и / или дополнительные предложения?

6 2

6 ответов:

Вы можете использовать

 SHOW PROCESSLIST  

Команда SQL для просмотра запущенных процессов. Это покажет вам имя пользователя, хост, базу данных и т. д., которые используются каждым процессом. Это должно дать вам некоторое представление о том, что происходит, особенно если у вас есть доступ к нескольким базам данных.

Подробнее здесь: http://codeinthehole.com/archives/2-Monitoring-MySQL-processes.html

Это не должно быть вызвано кодом php, потому что соединения mysql должны быть автоматически закрыты.

Cf: http://www.php.net/manual/function.mysql-connect.php :

Ссылка на сервер будет закрыта как только начнется выполнение сценария заканчивается, если только он не будет закрыт раньше. явный вызов mysql_close ().

Некоторые предложения:

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

PHP автоматически закрывает все соединения mysql, когда страница заканчивается. единственная причина, по которой веб-приложение PHP будет иметь слишком много незамкнутых соединений mysql-это либо 1) вы используете пул соединений, либо 2) есть ошибка в сервере mysql или соединителе.

Но если вы действительно хотите посмотреть на свой код, чтобы найти, где он соединяется, смотрите http://xdebug.org/docs/profiler

Как говорили другие, PHP завершает соединения MySQL, созданные через mysql_connect или эквиваленты msqli/PDO.

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

Можно уменьшить максимальное число подключений или уменьшить время ожидания для постоянных подключений. Смотрите комментарии в нижней части man-страницы для получения более подробной информации.

Я использовал для запуска сценария, который опрашивал SHOW STATUS for thread count, и я заметил, что использование mysql_connect всегда поощряло большое количество потоков. Меня это очень смущало, потому что тогда я не мог сказать, когда моя скорость соединения действительно падала. Поэтому я постарался централизовать все места, где вызывалась функция mysql_connect (), и исключить функцию mysql_connect ().

Следующее, что я сделал, это посмотрел на тайм-ауты соединения и настроил их на более чем 30 секунд, потому что. Так Что Я поправил мой мой.cnf с

Connect-timeout=30

Таким образом, я действительно мог видеть, что количество соединений падает. Чтобы определить количество соединений, которые вам нужно открыть, зависит от того, сколько работников apache вы запускаете раз количество соединений с базой данных, которые они будут открывать.

Другой вещью, которую я начал делать, было добавление примечания к моим запросам, чтобы определить их в SHOW PROCESSLIST или mytop, я бы добавил столбец примечания к моим результатам, таким как:

$q = "SELECT '".__FILE__.'.'.__LINE__."' as _info, * FROM table ...";

Это было бы покажите мне файл, выдающий запрос, когда я посмотрел на mytop, и он не сорвал кэш запросов MySQL, как при использовании

/* __FILE__.'.'.__LINE__ */ 

В начале моего запроса будет.

Я полагаю, что еще пара вещей, которые я могу сделать, в отношении общей Проблемы памяти, в отличие конкретно от MySQL, и особенно в контексте нашего собственного пользовательского кода, будет заключаться в том, чтобы обернуть наш код вызовами одной или другой из следующих встроенных функций PHP:

memory_get_usage

memory_get_peak_usage

В частности, поскольку я в настоящее время работаю над журналированием из некоторого пользовательского кода, я могу регистрировать использование памяти, пока я нахожусь в нем