2009-07-29 17 views
19

Estoy utilizando MySQL 5.0 para un sitio alojado por GoDaddy (Linux).Error de MySQL "Demasiadas conexiones"

Estaba haciendo algunas pruebas en mi aplicación web, y de repente noté que las páginas se actualizaban muy lentamente. Finalmente, después de una larga espera, llegué a una página que decía algo como "Error de MySQL, Demasiadas conexiones ...", y apuntaba a mi archivo config.php que se conecta a la base de datos.

Me acabo de conectar con la base de datos, no hay otros usuarios. En cada una de mis páginas, incluyo el archivo config.php en la parte superior y cierro la conexión de mysql al final de la página. Puede haber varias consultas en el medio. Me temo que no estoy cerrando las conexiones de mysql lo suficiente (mysql_close()).

Sin embargo, cuando intento cerrarlos después de ejecutar una consulta, recibo errores de conexión en la página. Mis páginas son PHP y HTML. Cuando intento cerrar una consulta, parece que la siguiente no se conectará. ¿Tendría que volver a incluir config.php después del cierre para poder conectarme?

Este error me asustó porque en 2 semanas, unas 84 personas comenzaron a usar esta aplicación web.

Gracias.

EDIT:

Aquí es un poco de pseudo-código de mi página:

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(); ?> 

que pensé que de esta manera, cada vez que se abra la página, la conexión se abre, y entonces la conexión se cierra cuando el la página está lista cargando A continuación, la conexión se abre de nuevo cuando alguien hace clic en un botón en la página, y así sucesivamente ...

EDIT:

bien, así que acabo de hablar por teléfono con GoDaddy. Aparentemente, con mi Paquete económico, estoy limitado a 50 conexiones a la vez. Mientras mi problema de hoy sucedía cuando solo yo accedía al sitio, me dijeron que estaban teniendo problemas con el servidor anteriormente. Sin embargo, viendo cómo voy a tener 84 usuarios para mi aplicación web, probablemente debería actualizar a "Deluxe", que permite 100 conexiones a la vez. En un día determinado, puede haber alrededor de 30 usuarios accediendo a mi sitio a la vez, por lo que creo que el 100 sería una apuesta más segura. ¿Están de acuerdo?

+0

pegar algo de código por favor. – Dirk

+4

Puede parecer una locura, pero intente poner algún tipo de contador en su método de conexión para ver si realmente solo se llama una vez por carga de página. Tuve un problema similar cuando en realidad estaba creando una nueva conexión para cada consulta sin darme cuenta. Puede valer la pena intentarlo. –

+0

@Mike B gran sugerencia, sin duda intentaré esto. – littleK

Respuesta

28

Los proveedores de hospedaje compartido generalmente permiten una cantidad bastante pequeña de conexiones simultáneas para el mismo usuario.

Lo que hace es su código:

  • abrir una conexión con el servidor MySQL
  • hacer son cosas (generación de la página)
  • cerrar la conexión al final de la página.

El último paso, cuando se hace al final de la página no es obligatoria : (citando mysql_close 's manual):

Usando mysql_close() no suele ser necesaria , como los enlaces abiertos no persistentes se cierran automáticamente al final de la secuencia de comandos .

pero tenga en cuenta que probablemente no debería utilizar conexiones persistentes de todos modos ...

Dos consejos:

  • uso mysql_connect insead de mysql_pconnect(ya bien para ti)
  • Set el cuarto parámetro de mysql_connect a falso (ya está bien para usted, ya que es el valor predeterminado): (citando el manual):

Si se realiza una segunda llamada a mysql_connect() con los mismos argumentos, se establecerá un nuevo enlace, pero en su lugar, se le devolverá el identificador de enlace de la conexión abierta .

El parámetro new_link modifica este comportamiento y hace mysql_connect() siempre abierto un nuevo enlace , incluso si mysql_connect() fue llamado antes con los mismos parámetros .



¿Qué puede causar el problema, entonces?

Quizás esté intentando acceder a varias páginas en paralelo (usando varias pestañas en su navegador, por ejemplo), que simularán varios usuarios que usan el sitio web al mismo tiempo?

Si tiene muchos usuarios que usan el sitio al mismo tiempo y el código entre mysql_connect y el cierre de la conexión lleva mucho tiempo, significará que se abrirán muchas conexiones al mismo tiempo ... Y lo hará alcance el límite :-(

Aún así, como usted es el único usuario de la aplicación, teniendo en cuenta que tiene habilitadas hasta 200 conexiones simultáneas, sucede algo extraño ...



Bueno, pensando en "demasiadas conexiones" y "max_connections" ...

Si no recuerdo mal, max_connections no limita el número de conexiones que puede abrirse en el servidor MySQL, pero el número total de conexiones que puede bo abierto en ese servidor, por cualquier persona conectando a él.

Citando la documentación de MySQL en Too many connections:

Si se obtiene un Demasiadas conexiones de error cuando intenta conectarse al servidor mysqld , esto significa que todos los conexiones disponibles están en uso por otros clientes .

El número de conexiones permitidas es controlado por la variable de sistema max_connections . Su valor predeterminado es 100. Si necesita admitir más conexiones, debe establecer un valor más grande para esta variable.

Así que, en realidad, el problema podría no viene de usted ni su código (que se ve bien, en realidad): podría "sólo" ser que usted no es el único que intenta conectarse a ese servidor MySQL (recuerda, "alojamiento compartido"), y que hay demasiadas personas que lo usan al mismo tiempo ...

... y si tengo razón y es que, no hay nada que puede para resolver el problema: siempre que haya demasiadas bases de datos/usuarios en ese servidor y que max_connection esté establecido en 200, continuará sufriendo ...


Como comentario: antes de volver a GoDaddy preguntándoles acerca de eso, sería bueno si alguien puede validar lo que acabo de decir ^^

+0

Gracias por la respuesta muy completa. Temía que fuera algo fuera de mi control ... Me alegra saber que mi código está bien, pero me preguntaba si sería útil crear una clase contenedora mysql que se conectara a la base de datos, ejecutar una consulta y luego cerrar la conexión. Decidí que podría intentarlo eso, pero, en función de su respuesta, parece que cerrar las conexiones de mysql puede no ser el problema ... – littleK

+0

Acabo de publicar un EDIT que contiene mi conversación con GoDaddy. – littleK

+0

Upg radiar de esta manera para solo 84 usuarios parece/se siente un poco exagerado para mí (84 usuarios no es mucho; toneladas de sitios web tienen más usuarios que eso, y no tienen ese tipo de problema) ... Si tuvieran problemas con su servidor, debería esperar un poco para ver cómo están las cosas, ahora –

2

Asegúrese de no estar utilizando conexiones persistentes. Esta suele ser una mala idea.

Si tiene eso .. A lo sumo, necesitará admitir tantas conexiones como procesos de Apache. ¿Puedes cambiar la configuración de max_connections?

+0

No estoy usando conexiones persistentes. No puedo modificar la configuración max_connections pero, de acuerdo con GoDaddy: "Permitimos hasta 200 conexiones simultáneas por usuario MySQL." – littleK

+0

Si no tiene más de 200 procesos Apache, verificará (como otros carteles mencionados) que no está creando más de 1 conexión por solicitud. – Evert

2

¿Está completamente seguro de que el servidor de la base de datos está completamente dedicado a usted?

Inicie sesión en la base de datos como raíz y use "MOSTRAR LISTA DE PROCESOS" para ver quién está conectado. Idealmente enganche esto en su sistema de monitoreo para ver cuántas conexiones hay en el tiempo y alerta si hay demasiadas.

Las conexiones de base de datos máximas se pueden configurar en my.cnf, pero tenga cuidado con la falta de memoria o espacio de direcciones.

+0

@MarkR Lamentablemente, no puedo hacer esto. Estoy usando GoDaddy's Hosting Linux, así que no tengo un servidor dedicado o virtual, así que no puedo iniciar sesión como root ... – littleK

2

Si usted tiene acceso a una consola, el uso netstat para ver cuántos Los sockets se abren en su base de datos y de dónde provienen.

En Linux, escriba:

netstat -n -a |grep 3306 

en Windows, escriba:

netstat -n -a |findstr 3306 
+0

Pude hacer eso Sin embargo, no tengo idea de cómo interpretar los resultados (para llegar a conclusiones significativas). Los publiqué en el siguiente enlace, ¿te importaría echar un vistazo? Me registraron en mi sitio cuando hice el netstat ... http://www.cs.scranton.edu/~behrk2/netstat_results.rtf ¡Gracias! – littleK

3

que tenían cerca de 18 meses de lidiar con este (http://ianchanning.wordpress.com/2010/08/25/18-months-of-dealing-with-a-mysql-too-many-connections-error/)

Las soluciones que tuve (que se aplicaría a usted) al final fueron:

  1. ajustar la base de datos de acuerdo con MySQLTuner.
  2. desfragmentar las tablas semanales basados ​​en esta escritura del golpe post

La desfragmentación del poste:

#!/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

su enlace nr1 es un 404. ¿era este el recurso? https://raw.github.com/major/MySQLTuner-perl/master/mysqltuner.pl –

+0

@JPHellemons Gracias, he arreglado el enlace - mysqltuner.com redirecciona al que usted ha mencionado. Lo dejé como mysqltuner.com en caso de que la redirección cambie nuevamente – icc97

1

La solución podría uno de ellos, me encontré con esto en una prueba MCQA, incluso lo hice ¡No se entiende cuál es el correcto!

Establecer esto en my.cnf "set-variable = max_connections = 200"

ejecute el comando "SET GLOBALmax_connections = 200"

Usar siempre mysql_connect() la función con el fin de conectar con el servidor MySQL

Usar siempre mysql_pconnect() la función con el fin de conectar con el servidor MySQL

0

las siguientes son soluciones posibles:

1) Aumente la configuración de conexión máxima estableciendo la variable global en mysql.

set global max_connection=200; 

Nota: Se aumentará la carga del servidor.

2) Piscina vacía la conexión de la siguiente manera:

FLUSH HOSTS;

3) comprobar su PROCESSLIST y matar processlist específico si no desea que ninguna de ellas.


Puede consultar la siguiente: -

article link

Cuestiones relacionadas