Я написал код на PHP, который возвращает html-контент из доменов .edu. Здесь приводится краткое введение: Ошибки в отношении веб-искателя в PHP
Искатель отлично работает, когда количество ссылок на обход небольших (около 40 URL-адресов), но после этого числа я получаю сообщение «Ошибка сервера MySQL».
Я храню html-содержимое как longtext в таблицах MySQL, и я не понимаю, почему ошибка появляется после минимум 40-50 вставок.
Любая помощь в этом отношении высоко ценится.
Обратите внимание, что я уже изменил wait_timeout и max_allowed_packet для размещения моих запросов и php-кода, и теперь я не знаю, что делать. Пожалуйста, помогите мне в этом.
Возможно, вы склонны справляться с этой проблемой, «пинговая» сервер mysql перед запросом. Это плохая идея. Подробнее о том, почему, проверьте это сообщение SO: Должен ли я ping сервер mysql перед каждым запросом?
Лучший способ справиться с проблемой – обернуть запросы внутри блоков try/catch
и try/catch
любые исключения баз данных, чтобы вы могли обращаться с ними соответствующим образом. Это особенно важно в сценариях длинных и / или демонных типов. Итак, вот очень простой пример, использующий «диспетчер соединений» для управления доступом к соединениям с БД:
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 } } } } }
У меня есть другой ответ, который касается того, что, по моему мнению, является аналогичной проблемой, и для этого потребуется аналогичный ответ. В принципе, вы можете использовать mysql_ping()
для проверки соединения перед вашей вставкой. До MySQL 5.0.14 mysql_ping()
автоматически восстанавливал соединение с сервером, но теперь вам нужно построить свою собственную логику повторного подключения. Нечто похожее на это должно работать на вас:
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. }
Я столкнулся с ошибкой « Ошибка сервера Mysql» при использовании Mysql connector 5.X
, заменив dll на последнюю версию, решив проблему.
Вы открываете одно соединение с БД и повторно используете его? Возможно ли, что это простой тайм-аут? Вам может быть лучше, если открыть новое соединение с БД для каждой операции чтения / записи (IE contact .edu, получить текст, открыть БД, написать текст, закрыть db, повторить).
Также как вы используете ручку? Возможно ли, что он ошибся и «ушел» по этой причине?
Это то, что я делаю сейчас, основываясь на предложении rdlowrey, и я думаю, это тоже правильно.
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 "<br><br>Catched!!!<br><br>"; if(strstr($e->getMessage(), 'MySQL server has gone away')) { $this->connection = mysql_connect("localhost", "root", ""); mysql_select_db("crawler1", $this->connection); } } }
Поэтому, как только запрос не выполнен, скрипт пропустит его, но будет убедиться, что соединение восстановлено.
Тем не менее, мой веб-искатель сбой, когда встречаются файлы, такие как .jpg, .bmp, .pdf и т. Д. Есть ли способ пропустить эти URL-адреса, содержащие эти расширения. Я использую preg_match и дал pdf и doc для соответствия. Тем не менее, я хочу, чтобы функция пропускала все ссылки, содержащие расширения, такие как mp3, pdf и т. Д. Возможно ли это?