Foros del Web » Programando para Internet » PHP »

Server dice "MySQL server has gone away"

Estas en el tema de Server dice "MySQL server has gone away" en el foro de PHP en Foros del Web. Hola, tengo un código que combina el simplepie ( www.simplepie.org ), es decir un lector de rss, con programación php que hace cosas con la ...
  #1 (permalink)  
Antiguo 03/04/2012, 09:11
Avatar de humanista  
Fecha de Ingreso: abril-2005
Mensajes: 878
Antigüedad: 19 años
Puntos: 15
Server dice "MySQL server has gone away"

Hola, tengo un código que combina el simplepie (www.simplepie.org), es decir un lector de rss, con programación php que hace cosas con la base de datos.

Me explico, hago un WHILE en el que el simplepie lee cada web (mediante rss) y lo que me traigo de cada una lo almaceno en la base de datos (INSERT). Al final, saco con SELECT todo lo almacenado.

El tema es que todo este proceso se hace con unas 20 webs (20 ciclos del WHILE) o incluso más y a veces me sale el error MySQL server has gone away.

He hablado con los del hosting y me contestan esto, entiendo que con toda la razón del mundo:

No podemos ampliar el timeout porque perjudicaria seriamente al servidor. Tenga
en cuenta que si se acumulan sentencias de la base de datos abierta, por
retrasos, se acabara saturando el servidor y se caera. Por lo tanto tenemos que
dejar las configuraciones de esa manera para mantener una cierta estabilidad.
Si ve que el simplepie le falla, intente hacer uso de otro sistema que recoja
primero los datos sin mantener las conexiones de la base de datos abierta y una
vez recogidos los datos los introduzca, sería lo mas logico.


El caso es que el tiempo antes de que se caiga el servidor es de 30 segundos.

Qué puedo hacer? Vale, la solución fácil es consultar menos webs pero necesito que sean bastantes.

He pensado que en lugar de insertar en la base de datos, que lo acumule en una array y así me evito el INSERT y el SELECT. Pero me temo que eso sólo me ahorrará unos pocos segundos, no más de 5 o así.

No sé si a alguien se le ocurre cómo hacerlo. Lo que dice de "recoger los datos sin mantener las conexiones de la base de datos abierta" no lo entiendo.

Gracias.
  #2 (permalink)  
Antiguo 03/04/2012, 09:19
Avatar de SirDuque  
Fecha de Ingreso: febrero-2009
Ubicación: Paso del Rey, Buenos Aires, Argentina
Mensajes: 975
Antigüedad: 15 años, 2 meses
Puntos: 89
Respuesta: Server dice "MySQL server has gone away"

humanista, ¿te molestaria mostrarme la cadena SQL de un INSERT?.
IMPORTANTE: ¿cuantos registros trae cada pagina?.
OTRA: estas haciendo multiple INSERT,( INSERT INTO tabla () VALUES (),(),(),(),(),() ) o simple ( INSERT INTO tabla () VALUES () ).
__________________
Mono programando!
twitter.com/eguimariano
  #3 (permalink)  
Antiguo 03/04/2012, 09:20
Avatar de truman_truman  
Fecha de Ingreso: febrero-2010
Ubicación: /home/user
Mensajes: 1.341
Antigüedad: 14 años, 2 meses
Puntos: 177
Respuesta: Server dice "MySQL server has gone away"

Pregunta, es necesario guardar todo en la base de datos? no podes mostrar los datos en ese mismo momento?
Todo esto que decís que hace tu script, los hace el usuario o solo vos como administrador?
digo porque si lo haces solo vos, lo podrías hacer mas lento, osea ir guardando de a una , así no recargar el servidor
__________________
la la la
  #4 (permalink)  
Antiguo 03/04/2012, 09:29
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Server dice "MySQL server has gone away"

Si estas usando la extensión MySQL, tiene una función mysql_ping que te puede ayudar en procesos como este.

Saludos.
  #5 (permalink)  
Antiguo 03/04/2012, 13:10
Avatar de humanista  
Fecha de Ingreso: abril-2005
Mensajes: 878
Antigüedad: 19 años
Puntos: 15
Respuesta: Server dice "MySQL server has gone away"

Hola, por partes:

- SQL del INSERT:
Código MySQL:
Ver original
  1. $sq="INSERT into tabla (campo1, campo2, campo3, campo4, campo5, campo6, campo7, campo8, campo9) values ('$campo1', '$campo2', '$campo3', '$campo4', '$campo5', '$campo6', '$campo7', '$campo8', '$campo9')";

son numéricos los campos 1, 2 y 4, el resto alfanuméricos.

- Busco en cada página 5 registros (no sé si son muchos...)

- Lo de múltiples INSERTs no lo entiendo. Hago un INSERT por cada uno de los 5 registros de cada página, es decir números de páginas (pongamos 25) por 5 = 125 INSERTs.

- Respecto a guardar todo en la base de datos, es imprescindible ya que luego ordeno los registros insertados por fecha descendente.

- Todo esto lo hace por cada usuario, no tiene nada que ver con el administrador.

- Cómo sé si estoy usando la extensión MySQL?

Gracias
  #6 (permalink)  
Antiguo 03/04/2012, 14:46
Avatar de SirDuque  
Fecha de Ingreso: febrero-2009
Ubicación: Paso del Rey, Buenos Aires, Argentina
Mensajes: 975
Antigüedad: 15 años, 2 meses
Puntos: 89
Respuesta: Server dice "MySQL server has gone away"

El multiple INSERT funciona de la siguiente manera:

Código PHP:
// 7 INSERT en una sola query.
$sql="INSERT INTO tabla (campo1, campo2, campo3)
 VALUES 
('$campo1', '$campo2', '$campo3'), ('$campo1', '$campo2', '$campo3'), ('$campo1', '$campo2', '$campo3'), ('$campo1', '$campo2', '$campo3'), ('$campo1', '$campo2', '$campo3'), ('$campo1', '$campo2', '$campo3'), ('$campo1', '$campo2', '$campo3')"
;
mysql_query($sql);

// Este insert suplanta:
//INSERT 1
$sql="INSERT INTO tabla (campo1, campo2, campo3)
 VALUES 
('$campo1', '$campo2', '$campo3')"
;
mysql_query($sql);
//INSERT 2
$sql="INSERT INTO tabla (campo1, campo2, campo3)
 VALUES 
('$campo1', '$campo2', '$campo3')"
;
mysql_query($sql);
//INSERT 3
$sql="INSERT INTO tabla (campo1, campo2, campo3)
 VALUES 
('$campo1', '$campo2', '$campo3')"
;
mysql_query($sql);
//INSERT 4
$sql="INSERT INTO tabla (campo1, campo2, campo3)
 VALUES 
('$campo1', '$campo2', '$campo3')"
;
mysql_query($sql);
//INSERT 5
$sql="INSERT INTO tabla (campo1, campo2, campo3)
 VALUES 
('$campo1', '$campo2', '$campo3')"
;
mysql_query($sql);
//INSERT 6
$sql="INSERT INTO tabla (campo1, campo2, campo3)
 VALUES  ('$campo1', '$campo2', '$campo3')"
;
mysql_query($sql);
//INSERT 7
$sql="INSERT INTO tabla (campo1, campo2, campo3)
 VALUES 
('$campo1', '$campo2', '$campo3')"
;
mysql_query($sql); 
PASO 1:
Como implementarlo en tu codigo:

Código PHP:

$SQL 
"INSERT INTO tabla (campo1, campo2, campo3)
 VALUES "
;
$INSERTS = array();

//Bucle
while (){

$INSERTS []= "('$campo1', '$campo2', '$campo3')";

}
//Fin bucle.

$SQL .= implode', ',$INSERTS);
mysql_query($SQL)or die( mysql_error() ); 
Con esto va a ser mas rapido el proceso.

PASO 2:

En la tabla segun los datos que nos interecen declaralos como llaves INDEX

Despues ANALYZE TABLE tabla; OPTIMIZE TABLE tabla;

PASO 3:

Las condiciones del SELECT deben apuntar a los INDEX del paso 2.

Comentanos los resultados.
El select
__________________
Mono programando!
twitter.com/eguimariano
  #7 (permalink)  
Antiguo 03/04/2012, 16:20
Avatar de humanista  
Fecha de Ingreso: abril-2005
Mensajes: 878
Antigüedad: 19 años
Puntos: 15
Respuesta: Server dice "MySQL server has gone away"

Gracias, dame un poco de tiempo para probarlo pero creo que incluso me podría ahorrar los INSERTS si lo meto todo en un array y la ordeno y la saco, sin INSERTS ni SELECTS.

Lo pruebo y lo comento aquí pero gracias porque he aprendido a hacer múltiples INSERTS.

De todas formas me temo que el problema no es del número de INSERTS ni SELECTS, es decir que creo que me voy a ahorrar no más de 5 segundos (aunque algo es algo).

El tema es que el simplepie (o cualquier otro lector rss) se tiene que traer todo el rss y analizarlo (en mi caso 5 registros). Todo eso lo hace por cada 1 de las... pongamos 25 webs que proceso cada vez que se hace click, incluso podría ser alguna más.

Lo digo porque en otro proceso he probado de rebajar de leer 25 webs a leer 10 (con el simplepie) y noto bastante bastante diferencia.
  #8 (permalink)  
Antiguo 03/04/2012, 16:35
Avatar de SirDuque  
Fecha de Ingreso: febrero-2009
Ubicación: Paso del Rey, Buenos Aires, Argentina
Mensajes: 975
Antigüedad: 15 años, 2 meses
Puntos: 89
Respuesta: Server dice "MySQL server has gone away"

Con multiple insert realizo 100MIL en menos de 30 seg.
Un simple query es esto:

mysql_query () ->
<- resultado
mysql_query () ->
<- resultado
mysql_query () ->
<- resultado
mysql_query () ->
<- resultado

En cambio un multiple query equivale a esto:

mysql_query () ->
<- resultado

Es evidente que lo diseñaron para que la transacciones con mysql sea mas rapida y no carge la base de datos.

-------------------------------------------------------

Con respecto de ingresar todo en un array, es una mejor idea, si nos facilitas el codigo podriamos ayudarte.
__________________
Mono programando!
twitter.com/eguimariano
  #9 (permalink)  
Antiguo 03/04/2012, 19:58
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Server dice "MySQL server has gone away"

Con la función que te pase deberías de poder resolver el problema ya que esta hecha para eso para que antes de enviar el query verifiques sí esta conectado y así evitar el MySQL Server Has Gone Away
  #10 (permalink)  
Antiguo 04/04/2012, 01:25
Avatar de humanista  
Fecha de Ingreso: abril-2005
Mensajes: 878
Antigüedad: 19 años
Puntos: 15
Respuesta: Server dice "MySQL server has gone away"

Vale, probaré todo lo que me decís y reporto aquí.

De todas formas una pregunta. El hecho de que el server se me caiga, se debe a los procesos en la base de datos INSERTs y SELECTs o a que el simplepie está trabajando durante mucho tiempo? O si es debido a ambos, cuál tiene más importancia?

Entiendo que el simplepie hace usa la función file_get_contents (o algo parecido) para "traerse" el contenido de otras webs.

Esto puede hacer caer el servidor si se trae 25 webs (RSS) y 5 registros por web? Es que me da que ese puede ser el problema.

Ahora lo tengo tal que así:

Código PHP:
Ver original
  1. while (25 webs)
  2. {
  3.     instancio el objeto del simplepie
  4.     for (5 registros por web)
  5.     {
  6.        INSERT del registro
  7.      }
  8. }
  9.  
  10. SELECT de los registros ordenados por fecha desc


Si lanzar el simplepie no hace tumbar al servidor, bastaría con quitar el INSERT (de todas formas lo tengo q hacer ya q consume recursos, aunque sean pocos) y meter todo en una array y luego sacarla ordenada.

La
  #11 (permalink)  
Antiguo 04/04/2012, 01:34
Avatar de humanista  
Fecha de Ingreso: abril-2005
Mensajes: 878
Antigüedad: 19 años
Puntos: 15
Respuesta: Server dice "MySQL server has gone away"

GatorV donde podría poner la función mysql_ping?
  #12 (permalink)  
Antiguo 04/04/2012, 04:48
Avatar de truman_truman  
Fecha de Ingreso: febrero-2010
Ubicación: /home/user
Mensajes: 1.341
Antigüedad: 14 años, 2 meses
Puntos: 177
Respuesta: Server dice "MySQL server has gone away"

yo creo que deberías obtener primero todas las webs y luego recien guardarlas, porque el tiempo que se tarda en consultar las webs lo estás desaprobechando en dejar abierta la coneccion a la base de datos. Primero guarda las webs en un array (todas) y luego El insert
__________________
la la la
  #13 (permalink)  
Antiguo 04/04/2012, 07:21
Avatar de humanista  
Fecha de Ingreso: abril-2005
Mensajes: 878
Antigüedad: 19 años
Puntos: 15
Respuesta: Server dice "MySQL server has gone away"

Sí, pero es que incluso el INSERT me lo puedo ahorrar. Realmente sólo lo necesito para tener metidas en algún sitio todas las webs (y sus 5 registros por cada una) y luego sacarlas ordenadas por fecha.

Es decir el hecho de que estén en la base de datos es como "puente" para luego sacarlos ordenados. De hecho cuando los saco, borro la base de datos (la tabla en cuestión).

Por esto es por lo que digo que puedo hacer lo mismo pero con un array. Y así lo haré porque va a ir mejor.

El tema sigue siendo que acceder a todas esas webs con el simplepie creo que va a ser muy pesado.
  #14 (permalink)  
Antiguo 04/04/2012, 07:31
Avatar de SirDuque  
Fecha de Ingreso: febrero-2009
Ubicación: Paso del Rey, Buenos Aires, Argentina
Mensajes: 975
Antigüedad: 15 años, 2 meses
Puntos: 89
Respuesta: Server dice "MySQL server has gone away"

Almacenando en tu DB es hacer un cacheo, MUY UTIL, ya que va a ser mas rapido que peticion file_get_contents.
Claro solo tienes que poner una condicion, para saber cuanto tiempo almacenar.

Por ejemplo:

1º Busqueda inicial, guardo todo en DB con un campo mas de DATETIME
2º Cuando las requirea, comparo las fechas DATETIME y si paso X tiempo ( minutos, dias, semas ).
2.1º Si no paso el tiempo, las muestro.
2.2º Si ya paso el tiempo, las borro y vuelvo a cargarlas.

IMAGINATE si tenes 10 o 100 usuarios ONLINE haciendo 125 peticiones file_get_contents simultaneos. Peor que taringa xD!
__________________
Mono programando!
twitter.com/eguimariano
  #15 (permalink)  
Antiguo 04/04/2012, 07:59
Avatar de humanista  
Fecha de Ingreso: abril-2005
Mensajes: 878
Antigüedad: 19 años
Puntos: 15
Respuesta: Server dice "MySQL server has gone away"

Lo siento SirDuque no te entiendo
  #16 (permalink)  
Antiguo 04/04/2012, 09:20
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Server dice "MySQL server has gone away"

Sí nada más estas usando la BDD para ordenar creo que estas haciendo un mal uso de ella, es mucho mejor en el caso que ordenes en el lado de PHP usando los parámetros que quieras.
  #17 (permalink)  
Antiguo 04/04/2012, 09:36
Avatar de humanista  
Fecha de Ingreso: abril-2005
Mensajes: 878
Antigüedad: 19 años
Puntos: 15
Respuesta: Server dice "MySQL server has gone away"

Si te refieres al uso de arrays, sí, voy a hacerlo así y a prescindir de la base de datos para ello pero el problema sigue siendo (creo yo) que el simplepie satura el servidor, no?
  #18 (permalink)  
Antiguo 05/04/2012, 05:07
Avatar de humanista  
Fecha de Ingreso: abril-2005
Mensajes: 878
Antigüedad: 19 años
Puntos: 15
Respuesta: Server dice "MySQL server has gone away"

Estoy montando el array:

Código PHP:
Ver original
  1. $arrayrss = array("titulo" => $titulo, "descripcion" => $descripcion, "seconds" => $seconds);

El campo clave es $seconds, es por el que quiero ordenar el array (simula a fecha, es decir el número de segundos que han pasado desde que se escribió el artículo, item, del rss) y puede haber duplicados.

Varias dudas:

1º No sé si hago bien es meterlo ahí o debería crear la array tal que así $arrayrss[$seconds]=array("titulo" => $titulo, "descripcion" => $descripcion)

2º Cómo recorro la array? Entiendo que tal y como la tengo definida no puede ser con foreach sino simplemente podría mostrar un registro con echo $arrayrss[0] por ejemplo, pero no va.

3º Quiero ordenar la array por $seconds ascendente y luego por cada registro sacar sus campos, por ejemplo

$seconds ------- $titulo------ $descripcion
1200 ---------- valor1------ valor2
2500 ---------- valor1------ valor2
2720 --------- valor1------ valor2
4870 ---------- valor1------ valor2
11300 ---------- valor1------ valor2

Se me escapa cómo hacerlo...

Última edición por humanista; 05/04/2012 a las 08:28
  #19 (permalink)  
Antiguo 05/04/2012, 08:57
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Server dice "MySQL server has gone away"

Para eso tienes la función array_multisort, para poder ordenar todo por el campo que quieres.

Para mostrarlo efectivamente haces un foreach() y solo es cuestión que lo indiques:
Código PHP:
Ver original
  1. foreach ($arrayrss as $field => $entry) {
  2.         echo "$field => $entry";
  3. }

Saludos.
  #20 (permalink)  
Antiguo 05/04/2012, 09:02
Avatar de truman_truman  
Fecha de Ingreso: febrero-2010
Ubicación: /home/user
Mensajes: 1.341
Antigüedad: 14 años, 2 meses
Puntos: 177
Respuesta: Server dice "MySQL server has gone away"

Se trata de un array multidimensional o array de arrays, osea un array general en donde sus elementos o indices también son array.

Yo me imagino que podrías hacer algo asi:


Código PHP:
<?php

$arrayrss 
= array(
            
1002 => array("titulo" => 'titulo1'"descripcion1" => 'descripcion2'),
            
1001 => array("titulo" => 'titulo2'"descripcion2" => 'descripcion1'),
            
1004 => array("titulo" => 'titulo3'"descripcion3" => 'descripcion4'),
            
1003 => array("titulo" => 'titulo4'"descripcion4" => 'descripcion3')
            );
ksort($arrayrss);

echo 
'<pre>';
print_r($arrayrss);

usar el indice del array principal con la fecha en segundos, para poder ordenarlo por ese campo con la funcion ksort()
__________________
la la la
  #21 (permalink)  
Antiguo 05/04/2012, 12:33
Avatar de humanista  
Fecha de Ingreso: abril-2005
Mensajes: 878
Antigüedad: 19 años
Puntos: 15
Respuesta: Server dice "MySQL server has gone away"

GatorV he seguido tu consejo del multisort en este link

http://php.net/manual/es/function.array-multisort.php (ejemplo #3)

pero me da este error

Warning: Cannot use a scalar value as an array in /home/virtual/

Código PHP:
foreach ($arrayrss as $key => $row)
{
$titulo[$key]              = $row["titulo"];
$descripcion[$key]           = $row["descripcion"];
$seconds[$key]      = $row["seconds"];

y también otro error

Warning: array_multisort() [function.array-multisort]: Argument #1 is an unknown sort flag in /home/virtual

cuando hago

Código PHP:
array_multisort($secondsSORT_ASC$arrayrss); 
  #22 (permalink)  
Antiguo 05/04/2012, 13:48
Avatar de truman_truman  
Fecha de Ingreso: febrero-2010
Ubicación: /home/user
Mensajes: 1.341
Antigüedad: 14 años, 2 meses
Puntos: 177
Respuesta: Server dice "MySQL server has gone away"

El problema es que tu array no es multidimensional , fijate en el ejemplo que te puse mas arriba, ese si es multi
__________________
la la la
  #23 (permalink)  
Antiguo 05/04/2012, 14:36
Avatar de humanista  
Fecha de Ingreso: abril-2005
Mensajes: 878
Antigüedad: 19 años
Puntos: 15
Respuesta: Server dice "MySQL server has gone away"

Creo que ese no es el problema ya que si me invento una variable $difseconds con valores "normales" va bien.

El tema es que hago operaciones con esta variable, y son de tipo fecha como mktime y divisiones y así.

No sé si se podrá transformar escalar en "normal"...
  #24 (permalink)  
Antiguo 05/04/2012, 16:24
Avatar de humanista  
Fecha de Ingreso: abril-2005
Mensajes: 878
Antigüedad: 19 años
Puntos: 15
Respuesta: Server dice "MySQL server has gone away"

ok, el problema era usar un nombre de variable que ya existía y daba error.

Ahora sólo me falta recorrer la array y sacar los datos y no sé cómo ya q el array es así:

seconds ---------100 ----200 ----300
titulo -----------tit2 -----tit3 -----tit1
descripcion ------desc2 --desc3----desc1

Última edición por humanista; 05/04/2012 a las 16:29
  #25 (permalink)  
Antiguo 05/04/2012, 17:27
Avatar de humanista  
Fecha de Ingreso: abril-2005
Mensajes: 878
Antigüedad: 19 años
Puntos: 15
Respuesta: Server dice "MySQL server has gone away"

Tras miles de pruebas he conseguido más o menos hacerlo pero me gustaría depurarlo. Con esto lo saco:

Código PHP:
Ver original
  1. echo $arrayrss[0][titulo];

Tengo un contador manual del número de registros y podría hacer un bucle normal y corriente del tipo:

Código PHP:
for ($i 0$i <= $contador$i++) 
pero... ya puestos a dejarlo de 10, se podría hacer con un foreach?
  #26 (permalink)  
Antiguo 05/04/2012, 17:55
Avatar de truman_truman  
Fecha de Ingreso: febrero-2010
Ubicación: /home/user
Mensajes: 1.341
Antigüedad: 14 años, 2 meses
Puntos: 177
Respuesta: Server dice "MySQL server has gone away"

pero entoces tenés 3 array? o entendí mal? en ese caso podrás ordenar el seconds, pero no los otros, o me equivoco?
__________________
la la la

Última edición por truman_truman; 05/04/2012 a las 18:04
  #27 (permalink)  
Antiguo 05/04/2012, 18:20
Avatar de humanista  
Fecha de Ingreso: abril-2005
Mensajes: 878
Antigüedad: 19 años
Puntos: 15
Respuesta: Server dice "MySQL server has gone away"

sí, sólo ordené por el seconds.

es una array (no tres) con 3 campos, 1 de ellos el seconds.

lógicamente al ser una array tiene varios registros (muchos), y cada 1 con su título, descripción y seconds.

creo la array, ordeno con multisort y saco el array, ya ordenada, con for.
  #28 (permalink)  
Antiguo 06/04/2012, 09:12
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Server dice "MySQL server has gone away"

Claro que se puede hacer con foreach:
Código PHP:
Ver original
  1. foreach ($array as $counter => $rss) {
  2.       echo $rss['titulo'];
  3. }

Etiquetas: mysql, server
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 00:04.