Domanda

Abbiamo un'applicazione che comprende un paio di applicazioni PHP standardizzate (ExpressionEngine e XCart) oltre al nostro codice personalizzato.

Non ho eseguito l'analisi effettiva, quindi non so esattamente come sia stato determinato, ma non sono sorpreso di sapere che troppe connessioni MySQL non vengono chiuse (non sono sorpreso perché ho riscontrato perdite significative di memoria sul nostro server di sviluppo, in cui nel corso di uno o due giorni, a partire da 100 MB all'avvio iniziale, viene consumato l'intero gig di ram e ne viene memorizzato molto poco nella cache).

Quindi, come possiamo determinare con precisione quale codice PHP è il colpevole? Ho avuto precedenti esperienze con XDebug e ho suggerito che, quando abbiamo ottenuto il nostro ambiente di gestione temporanea separato ragionevolmente stabile, abbiamo adattato XDebug su dev e lo abbiamo usato per fare qualche analisi. È ragionevole e / o qualcun altro ha suggerimenti più specifici e / o aggiuntivi?

È stato utile?

Soluzione

Puoi usare

 SHOW PROCESSLIST  

Comando SQL per vedere quali processi sono in esecuzione. Questo ti dirà il nome utente, host, database, ecc che sono in uso da ogni processo. Questo dovrebbe darti un'idea di cosa sta succedendo, specialmente se hai accesso a un numero di database.

Altro qui: http://codeinthehole.com/archives/2- Monitoraggio-MySQL-processes.html

Altri suggerimenti

Questo non dovrebbe essere causato da un codice php perché le connessioni mysql dovrebbero essere chiuse automaticamente.

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

  

Il collegamento al server verrà chiuso   non appena l'esecuzione della sceneggiatura   termina, a meno che non sia stato chiuso prima da   chiamando esplicitamente mysql_close ().

Alcuni suggerimenti:

  • il tuo sviluppatore ha tecnicamente un accesso diretto al tuo server mysql di produzione? se sì, probabilmente lasciano aperto il loro Mysql Manager :)
  • hai qualche processo batch giornaliero? se sì, forse ci sono alcuni processi zombi in memoria

PHP chiude automaticamente tutte le connessioni mysql al termine della pagina. l'unica ragione per cui un'applicazione web PHP avrebbe troppe connessioni mysql non chiuse è 1) stai usando il pool di connessioni, oppure 2) c'è un bug nel server mysql o nel connettore.

ma se vuoi davvero guardare il tuo codice per scoprire dove si sta connettendo, vedi http: // xdebug. org / docs / profiler

Come altri hanno detto, PHP termina le connessioni MySQL create tramite mysql_connect o gli equivalenti msqli / PDO.

Tuttavia, puoi creare connessioni permanenti con mysql_pconnect . Cercherà connessioni esistenti aperte e userà quelle; se non riesce a trovarne uno, ne aprirà uno nuovo. Se hai ricevuto molte richieste contemporaneamente, potrebbe aver causato l'apertura e il mantenimento di un sacco di connessioni.

È possibile ridurre il numero massimo di connessioni o ridurre il timeout per le connessioni permanenti. Vedi i commenti in fondo alla man page per ulteriori informazioni i dettagli.

Ero solito eseguire uno script che eseguiva il polling di SHOW STATUS per il conteggio dei thread e ho notato che l'uso di mysql_pconnect ha sempre incoraggiato un numero elevato di thread. L'ho trovato molto sconcertante perché in quel momento non sono riuscito a capire quando la mia velocità di connessione stava scendendo. Quindi mi sono assicurato di centralizzare tutti i luoghi in cui veniva chiamato mysql_connect () ed eliminare mysql_pconnect ().

La prossima cosa che ho fatto è stato guardare i timeout della connessione e regolarli su più come 30 secondi perché. Quindi ho modificato my.cnf con

connect-timeout = 30

così ho potuto effettivamente vedere il numero di connessioni cadere. Per determinare il numero di connessioni che devi aprire dipende da quanti apache worker stai eseguendo volte il numero di connessioni al database che apriranno ognuna.

L'altra cosa che ho iniziato a fare è stata aggiungere una nota alle mie query per individuarle in SHOW PROCESSLIST o mytop, aggiungerei una colonna di nota ai miei risultati come:

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

Questo mi mostrerebbe il file che emetteva la query quando guardavo mytop, e non sventava la cache delle query MySQL come usando

/* __FILE__.'.'.__LINE__ */ 

all'inizio della mia query sarebbe.

Suppongo che un altro paio di cose che posso fare, per quanto riguarda il problema di memoria generale, al contrario di MySQL, e in particolare nel contesto del nostro codice personalizzato, sarebbe avvolgere il nostro codice con chiamate a uno o al altre delle seguenti funzioni integrate di PHP:

memory_get_usage

memory_get_peak_usage

In particolare dato che attualmente sto lavorando alla registrazione da un codice personalizzato, posso registrare l'utilizzo della memoria mentre ci sono

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top