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

StackOverflow https://stackoverflow.com/questions/1643652

Вопрос

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

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

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

Это было полезно?

Решение

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

 SHOW PROCESSLIST  

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

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

Другие советы

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

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

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

Несколько предложений :

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

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

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

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

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

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

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

Следующее, что я сделал, это посмотрел на тайм-ауты подключения и настроил их примерно на 30 секунд, потому что.Поэтому я скорректировал свой файл my.cnf с помощью

время ожидания подключения=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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top