как определить, какой код PHP открывает соединения MySQL, которые не закрываются
У нас есть приложение, которое состоит из нескольких готовых PHP-приложений (ExpressionEngine и XCart), а также нашего собственного пользовательского кода.
Я не делал фактический анализ, поэтому я не знаю точно, как он был определен, но не удивлен, услышав, что слишком много соединений MySQL остаются незамкнутыми (я не удивлен, потому что я наблюдал значительную утечку памяти на нашем dev-сервере, где в течение дня или двух, начиная со 100 Мб на каждом сервере). начальная загрузка, весь гигабайт оперативной памяти потребляется, и очень мало из него кэшируется).
Итак, как мы можем точно определить, какой код PHP является виновником? У меня есть предыдущий опыт работы с XDebug, и я предложил, чтобы, когда мы получим нашу отдельную, промежуточную среду достаточно стабильной, мы модифицировали XDebug на dev и использовали ее для проведения некоторого анализа. Разумно ли это, и/или у кого-нибудь еще есть более конкретные и / или дополнительные предложения?
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:
В частности, поскольку я в настоящее время работаю над журналированием из некоторого пользовательского кода, я могу регистрировать использование памяти, пока я нахожусь в нем