Solución de errores del “servidor MySQL ha desaparecido”

He escrito un código en PHP que devuelve el contenido html de los dominios .edu. Aquí se incluye una breve introducción: Errores relacionados con Web Crawler en PHP

El rastreador funciona bien cuando el número de enlaces para rastrear es pequeño (alrededor de 40 URL) pero obtengo el error “El servidor MySQL se ha ido” después de este número.

Estoy almacenando contenido html como texto largo en tablas MySQL y no entiendo por qué el error llega después de al menos 40-50 inserciones.

Se agradecerá enormemente cualquier ayuda en esta cuestión.

Tenga en cuenta que ya he modificado wait_timeout y max_allowed_packet para acomodar mis consultas y el código php, y ahora no sé qué hacer. Por favor, ayúdame en este sentido.

Puede inclinarse a manejar este problema “haciendo ping” al servidor mysql antes de una consulta. Esta es una mala idea. Para obtener más información sobre por qué, consulte esta publicación SO: ¿Debería hacer ping al servidor mysql antes de cada consulta?

La mejor forma de manejar el problema es envolviendo las consultas dentro de try/catch bloques try/catch y capturando las excepciones de la base de datos para que pueda manejarlas adecuadamente. Esto es especialmente importante en secuencias de comandos de tipo ejecución larga y / o tipo daemon. Entonces, aquí hay un ejemplo muy básico usando un “administrador de conexión” para controlar el acceso a las conexiones de DB:

 class DbPool { private $connections = array(); function addConnection($id, $dsn) { $this->connections[$id] = array( 'dsn' => $dsn, 'conn' => null ); } function getConnection($id) { if (!isset($this->connections[$id])) { throw new Exception('Invalid DB connection requested'); } elseif (isset($this->connections[$id]['conn'])) { return $this->connections[$id]['conn']; } else { try { // for mysql you need to supply user/pass as well $conn = new PDO($dsn); // Tell PDO to throw an exception on error // (like "MySQL server has gone away") $conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); $this->connections[$id]['conn'] = $conn; return $conn; } catch (PDOException $e) { return false; } } } function close($id) { if (!isset($this->connections[$id])) { throw new Exception('Invalid DB connection requested'); } $this->connections[$id]['conn'] = null; } } class Crawler { private $dbPool; function __construct(DbPool $dbPool) { $this->dbPool = $dbPool; } function crawl() { // craw and store data in $crawledData variable $this->save($crawledData); } function saveData($crawledData) { if (!$conn = $this->dbPool->getConnection('write_conn') { // doh! couldn't retrieve DB connection ... handle it } else { try { // perform query on the $conn database connection } catch (Exception $e) { $msg = $e->getMessage(); if (strstr($msg, 'MySQL server has gone away') { $this->dbPool->close('write_conn'); $this->saveData($val); } else { // some other error occurred } } } } } 

Tengo otra respuesta que trata de lo que creo que es un problema similar, y requeriría una respuesta similar. Básicamente, puede usar la función mysql_ping() para probar la conexión antes de su inserción. Antes de MySQL 5.0.14, mysql_ping() reconectaría automáticamente el servidor, pero ahora debe construir su propia lógica de reconexión. Algo similar a esto debería funcionar para usted:

 function check_dbconn($connection) { if (!mysql_ping($connection)) { mysql_close($connection); $connection = mysql_connect('server', 'username', 'password'); mysql_select_db('db',$connection); } return $connection; } foreach($array as $value) { $dbconn = check_dbconn($dbconn); $sql="insert into collected values('".$value."')"; $res=mysql_query($sql, $dbconn); //then some extra code. } 

Estaba enfrentando el error “El servidor Mysql se ha ido” al usar Mysql connector 5.X , reemplazando dll a la última versión resolvió el problema.

¿Estás abriendo una única conexión de BD y reutilizándola? ¿Es posible que sea un tiempo de espera simple? Puede que le sea más útil abriendo una nueva conexión de base de datos para cada una de sus operaciones de lectura / escritura (contacto IE .edu, obtener texto, abrir base de datos, escribir texto, cerrar db, repetir).

Además, ¿cómo estás usando el mango? ¿Es posible que haya dado un error y se haya “ido” por esa razón?

Bueno, esto es lo que estoy haciendo ahora en base a la sugerencia de rdlowrey y supongo que esto también es correcto.

 public function url_db_html($sourceLink = NULL, $source) { $source = mysql_real_escape_string($source); $query = "INSERT INTO html (id, sourceLink, sourceCode) VALUES (NULL,('$sourceLink') , ('$source'))"; try { if(mysql_query($query, $this->connection)==FALSE) { $msg = mysql_errno($this->connection) . ": " . mysql_error($this->connection); throw new DbException($msg); } } catch (DbException $e) { echo "

Catched!!!

"; if(strstr($e->getMessage(), 'MySQL server has gone away')) { $this->connection = mysql_connect("localhost", "root", ""); mysql_select_db("crawler1", $this->connection); } } }

Entonces, una vez que la consulta no se ha podido ejecutar, el script se saltará pero se asegurará de que la conexión se restablezca.

Sin embargo, mi rastreador web se cuelga cuando se encuentran archivos como .jpg, .bmp, .pdf, etc. ¿Hay alguna manera de omitir esas URL que contienen estas extensiones? Estoy usando preg_match y he dado pdf y doc para que coincida. Sin embargo, quiero que la función omita todos los enlaces que contengan extensiones como mp3, pdf, etc. ¿Es esto posible?