2009-07-29 9 views
19

Sto usando MySQL 5.0 per un sito che è ospitato da GoDaddy (linux).Errore MySQL "Troppe connessioni"

Stavo facendo alcuni test sulla mia app web, e improvvisamente ho notato che le pagine si stavano rinfrescando molto lentamente. Alla fine, dopo una lunga attesa, sono arrivato a una pagina che diceva qualcosa sulla falsariga di "MySQL Error, Too many connections ...", e indicava il mio file config.php che si collega al database.

Mi sono appena collegato al database, nessun altro utente. In ciascuna delle mie pagine, includo il file config.php in alto e chiudo la connessione mysql alla fine della pagina. Ci possono essere diverse domande in mezzo. Temo di non chiudere abbastanza connessioni mysql (mysql_close()).

Tuttavia, quando provo a chiuderli dopo aver eseguito una query, ricevo errori di connessione sulla pagina. Le mie pagine sono PHP e HTML. Quando provo a chiudere una query, sembra che il prossimo non si connetterà. Dovrei includere nuovamente config.php dopo la chiusura per connettermi?

Questo errore mi ha spaventato perché in 2 settimane circa 84 persone hanno iniziato a utilizzare questa applicazione web.

Grazie.

EDIT:

Ecco alcuni pseudo-codice della mia pagina:

require_once('../scripts/config.php'); 

<?php 
    mysql_query.. 

    if(this button is pressed){ 
     mysql_query... 
    } 
    if(this button is pressed){ 
     mysql_query... 
    } 
    if(this button is pressed){ 
     mysql_query... 
    } 
?> 
some html.. 
.. 
.. 
.. 
.. 
<?php 
    another mysql_query... 
?> 
some more html.. 
.. 
.. 
<?php mysql_close(); ?> 

ho pensato che in questo modo, ogni volta che la pagina si apre, il collegamento si apre, e poi il collegamento si chiude quando la la pagina è stata caricata. Poi, il collegamento si apre di nuovo quando qualcuno fa clic su un pulsante sulla pagina, e così via ...

EDIT:

Okay, Ho appena parlato al telefono con GoDaddy. Apparentemente, con il mio pacchetto Economy, sono limitato a 50 connessioni alla volta. Mentre il mio problema si è verificato oggi solo con l'accesso al sito, mi hanno detto che stavano avendo alcuni problemi con il server in precedenza. Tuttavia, visto che avrò 84 utenti per la mia app Web, dovrei probabilmente passare a "Deluxe", che consente 100 connessioni alla volta. In un dato giorno, potrebbero esserci circa 30 utenti che accedono al mio sito alla volta, quindi penso che il 100 sarebbe una scommessa più sicura. Siete d'accordo?

+0

Incolla po 'di codice per favore. – Dirk

+4

Può sembrare strano, ma prova a mettere un qualche tipo di contatore sul tuo metodo di connessione per vedere se è DAVVERO chiamato solo una volta per pagina. Ho avuto un problema simile in cui stavo creando una nuova connessione per ogni query senza rendermene conto. Potrebbe valere la pena di un colpo. –

+0

@Mike B ottimo suggerimento, lo proverò sicuramente. – littleK

risposta

28

I provider di hosting condiviso generalmente consentono una quantità piuttosto piccola di connessioni simultanee per lo stesso utente.

Che il codice che fa è:

  • aprire una connessione al server MySQL
  • fare è roba (la generazione della pagina)
  • chiudere la connessione alla fine della pagina.

L'ultima fase, quando fatto al termine della pagina non è obbligatoria : (citando mysql_close s' manuale):

Uso mysql_close() non è solitamente necessario , come i collegamenti aperti non persistenti vengono automaticamente chiusi alla fine dell'esecuzione dello script .

ma nota che probabilmente non si dovrebbe usare connessioni persistenti in ogni caso ...

Due consigli:

  • uso mysql_connect INSEAD di mysql_pconnect(già OK per voi)
  • Set il quarto parametro di mysql_connect a false (già OK per te, poiché è il valore predefinito): (citando il manuale):

Se viene effettuata una seconda chiamata a mysql_connect() con le stesse argomenti, nessun nuovo collegamento sarà stabilito, ma, invece, verrà restituito l'identificatore di collegamento del collegamento già aperto .

Il parametro nuova_connessione modifica questo comportamento e rende mysql_connect() aprire sempre un nuovo link , anche se mysql_connect() è stato chiamato prima con gli stessi parametri .



Che cosa potrebbe causare il problema, allora?

Forse si sta cercando di accedere a diverse pagine in parallelo (utilizzando più schede nel browser, per esempio), che simulerà diversi utenti utilizzando il sito web, allo stesso tempo?

Se molti utenti utilizzano il sito contemporaneamente e il codice tra mysql_connect e la chiusura della connessione richiede molto tempo, significa che molte connessioni vengono aperte contemporaneamente ... E tu raggiungere il limite :-(

Tuttavia, poiché si è l'unico utente dell'applicazione, considerando che sono consentite fino a 200 connessioni simultanee, c'è qualcosa di strano in corso ...



Beh, pensando a "troppe connessioni" e "max_connections" ...

Se non ricordo male, max_connections non limita il numero di connessioni si può aprire il server MySQL, ma il numero totale di connessioni può essere aperto a quel server, da chiunque collegandosi ad esso.

Citando la documentazione di MySQL su Too many connections:

Se si ottiene un Troppe connessioni di errore quando si tenta di connettersi al server mysqld , ciò significa che tutti i connessioni disponibili sono in uso da altri clienti .

Il numero di connessioni consentite è controllato dalla variabile di sistema max_connections . Il valore predefinito è 100. Se è necessario supportare più connessioni, è necessario impostare un valore maggiore per questa variabile.

Quindi, in realtà, il problema potrebbe non viene da voi né il vostro codice di (che guarda bene, in realtà): potrebbe "solo" essere che non sei l'unico a cercare di connettersi al server MySQL (ricordate, "hosting condiviso"), e che ci sono troppe persone che lo utilizzano allo stesso tempo ...

... e se ho ragione ed è che, non c'è niente che si può fai per risolvere il problema: finché ci sono troppi database/utenti su quel server e che max_connection è impostato su 200, continuerai a soffrire ...


Come sidenote: prima di tornare a GoDaddy chiedendo loro su questo, sarebbe bello se qualcuno potesse convalidare ciò che ho appena detto ^^

+0

Grazie per la risposta molto approfondita! Avevo paura che potesse essere qualcosa fuori dal mio controllo ... Mi fa piacere sapere che il mio codice va bene, ma mi chiedevo se sarebbe stato di aiuto creare una classe wrapper mysql che si connettesse al db, eseguisse una query e poi chiudesse la connessione? Ho deciso che potrei provare ma, in base alla tua risposta, sembra che chiudere le connessioni mysql potrebbe non essere il problema ... – littleK

+0

Ho appena postato un EDIT che contiene la mia conversazione con GoDaddy. – littleK

+0

Upg questo modo per soli 84 utenti sembra/mi sembra un po 'eccessivo (84 utenti non è così tanto; un sacco di siti web hanno più utenti e non hanno questo tipo di problema ... Se avessero problemi con il loro server, dovresti aspettare un po 'per vedere come stanno le cose, ora –

2

Assicurarsi di non utilizzare connessioni persistenti. Questa è di solito una pessima idea ..

Se ce l'hai .. Al massimo dovrai supportare altrettante connessioni quante sono i processi di Apache. Sei in grado di modificare l'impostazione max_connections?

+0

Non sto usando connessioni persistenti. Non posso modificare l'impostazione max_connections ma, secondo GoDaddy: "Consentiamo fino a 200 connessioni simultanee per utente MySQL." – littleK

+0

Se non hai più di 200 processi Apache, verificherebbe (come altri posters menzionati) che non stai creando più di 1 connessione per richiesta. – Evert

2

Sei completamente sicuro che il server del database sia completamente dedicato a te?

Accedere alla base dati come root e utilizzare "MOSTRA ELENCO PROCESSI" per vedere chi è connesso. Idealmente collegalo al tuo sistema di monitoraggio per vedere quante connessioni ci sono nel tempo e avvisa se ce ne sono troppe.

Le connessioni di database massime possono essere configurate in my.cnf, ma attenzione per l'esaurimento della memoria o dello spazio indirizzo.

+0

@MarkR Sfortunatamente, non posso farlo. Sto usando GoDaddy Hosting Linux, quindi non ho un server dedicato o virtuale, quindi non posso accedere come root ... – littleK

2

Se si dispone di accesso alla shell, uso netstat per vedere quanti i socket sono aperti al tuo database e da dove provengono.

Su Linux, tipo:

netstat -n -a |grep 3306 

Su Windows, digitare:

netstat -n -a |findstr 3306 
+0

sono riuscito a farlo , tuttavia non ho idea di come interpretare i risultati (in modo da arrivare a conclusioni significative). Li ho postati al seguente link, ti ​​dispiacerebbe dare un'occhiata? Ho effettuato l'accesso al mio sito quando ho effettuato il netstat ... http://www.cs.scranton.edu/~behrk2/netstat_results.rtf Grazie! – littleK

3

ho avuto circa 18 mesi di trattare con questo (http://ianchanning.wordpress.com/2010/08/25/18-months-of-dealing-with-a-mysql-too-many-connections-error/)

Le soluzioni che ho avuto (che si applica a voi) alla fine erano:

  1. sintonizzare il database in base a MySQLTuner.
  2. deframmentare le tabelle settimanali sulla base di questo script bash post

deframmentazione da posta:

#!/bin/bash 

# Get a list of all fragmented tables 
FRAGMENTED_TABLES="$(mysql -e `use information_schema; SELECT TABLE_SCHEMA,TABLE_NAME 
FROM TABLES WHERE TABLE_SCHEMA NOT IN ('information_schema','mysql') AND 
Data_free > 0` | grep -v '^+' | sed 's,t,.,')" 

for fragment in $FRAGMENTED_TABLES; do 
    database="$(echo $fragment | cut -d. -f1)" 
    table="$(echo $fragment | cut -d. -f2)" 
    [ $fragment != "TABLE_SCHEMA.TABLE_NAME" ] && mysql -e "USE $database; 
    OPTIMIZE TABLE $table;" > /dev/null 2>&1 
done 
+0

il tuo collegamento nr1 è un 404. era questa la risorsa? https://raw.github.com/major/MySQLTuner-perl/master/mysqltuner.pl –

+0

@JPHellemons Grazie, ho risolto il collegamento - mysqltuner.com reindirizza a quello che hai menzionato. L'ho lasciato come mysqltuner.com nel caso in cui il reindirizzamento venga cambiato di nuovo – icc97

1

La soluzione potrebbe uno di questi, mi sono imbattuto in questo in un test MCQA, anche ho fatto non capito quale è giusto!

Impostare questo in my.cnf "= max_connections set-variable = 200"

Eseguire il comando "GLOBALmax_connections SET = 200"

Usa mysql_connect() la funzione sempre per connettersi al server MySQL

Usa sempre mysql_pconnect() in modo da connettersi al server MySQL

0

chi segue le possibili soluzioni:

1) Aumentare l'impostazione di connessione massima impostando la variabile globale in mysql.

set global max_connection=200; 

Nota: Esso aumenterà il carico del server.

2) piscina Svuotare il collegamento, come di seguito:

FLUSH HOSTS;

3) controllare il vostro processList e uccidere processlist specifico se non si vuole nessuno di loro.


È possibile fare riferimento a questo: -

article link

Problemi correlati