Как определить, какой код PHP открывает MySQL-соединения, которые не закрываются - PullRequest
2 голосов
/ 29 октября 2009

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

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

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

Ответы [ 6 ]

3 голосов
/ 29 октября 2009

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

 SHOW PROCESSLIST  

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

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

2 голосов
/ 29 октября 2009

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

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

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

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

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

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

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

подключения таймаут = 30

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

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

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

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

/* __FILE__.'.'.__LINE__ */ 

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

1 голос
/ 29 октября 2009

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

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

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

1 голос
/ 29 октября 2009

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

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

0 голосов
/ 29 октября 2009

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

memory_get_usage

memory_get_peak_usage

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

...