6

We are getting both a PDOException and warnings. These warnings are driving us crazy.

Warning: PDOStatement::execute(): MySQL server has gone away in /home/Database.php on line 120

Warning: PDOStatement::execute(): Error reading result set's header in /home/Database.php on line 120

Here is the code that does this -- this is just to simulate a connection going away:

$db = new PDO('mysql:dbname=' . $name . ';host=' . $host, $user, $pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

$statement = $db->prepare('SET SESSION wait_timeout = 1');
$statement->execute();

sleep(3);

try {
    $statement = $db->prepare('SELECT 1');
    $statement->execute();
} catch (PDOException $e) {
    echo 'Exception! Err #:' . $e->errorInfo[1] . PHP_EOL;
}

EDIT: The question is why does this generate a warning and an exception. The code above just generates both even though we specifically tell PDO to throw exceptions.
The code above makes it happen faster than waiting for our servers default wait_timeout.

EDIT 2: I'm not sure why this was closed. The question is WHY is PHP spawning both a Warning, and an Exception regardless of the PDO Error Level?

Michael
  • 1,816
  • 7
  • 21
  • 35
  • So what is the question? – AVProgrammer Dec 04 '15 at 22:54
  • 1
    Why are you setting session timeout anyway? What problem are you trying to solve by doing that? You explain symptoms but not what you were actually doing to cause the issue. You also do not explain what you are trying to do. I need to know that. – Ryan Vincent Dec 04 '15 at 23:12
  • 2
    This is not a duplicate of that question. I'm asking why there are warnings AND exceptions regardless of ATTR_ERRMODE being set to ERRMODE_EXCEPTION. – Michael Dec 05 '15 at 00:44
  • 1
    This is not a duplicate. 5 people are wrong. – gaRex Feb 11 '16 at 08:07
  • 1
    Answered with details at http://stackoverflow.com/questions/35341276 – gaRex Feb 11 '16 at 14:46

2 Answers2

3

You set wait_timeout to 1 then you sleep 3, what will happen? MySql will close connection after one second and you will get error "Mysql Server has gone away" with next statement 'cause you sleep for 3.

http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_wait_timeout

edit

Question is duplicate of MySQL error 2006: mysql server has gone away

edit 2

Causes of this error:

  • low wait_timeout - solution: ping, reconnect or increase it too
  • large packets - solution: tune max_allowed_packet in my.cfg

PDO reconnect - simulate ping in PDO How do i ping the MySQL db and reconnect using PDO

edit 3 question updated

The only way (afaik) to get rid of these warnings is to set expected (eg. E_ERROR) error_reporting level. You could wrapped pdo calls up in for example to set E_ERROR before and reset to default after execution.

PDO logs warnings/errors for logs purposes (sic!) for further analytics. The attribute you set (by setAttribute or constructor) only changes error handling/behavior of pdo - throw or not:). These two things are separated.

Community
  • 1
  • 1
kwarunek
  • 12,141
  • 4
  • 43
  • 48
  • The question metioned as the duplicated question isn't explaining how to do this with PDO. But it explains the Mysql logic behind it. – jankal Dec 04 '15 at 23:04
  • 1
    I updated the question to add a little more detail behind the code snippet. Sorry for the confusion. – Michael Dec 05 '15 at 00:11
  • Thanks, that's a possibility I will look into. I'm hoping for something else though. – Michael Dec 05 '15 at 00:46
  • 1
    I'm still not sure why this was closed (and downvoted), since it was about why there are warnings when you set PDO to give exceptions. Regardless, since you gave an answer that answered the question I am marking it as the best. Thanks. – Michael Dec 18 '15 at 15:39
  • 1
    THIS is not a duplicate. The question clearly states: Why the f..k PDO gives us warnings when we tell to it to throw exceptions? – gaRex Feb 11 '16 at 08:09
  • Answered with details at http://stackoverflow.com/questions/35341276 – gaRex Feb 11 '16 at 14:47
-3

To prevent this error I'd just add

$db->setAttribute(PDO::ATTR_TIMEOUT,ini_get('max_execution_time'));

to your ->setAttribute calls after creating the PDO object.

I don't really know if this really works, but it should work.

(didn't test it)

jankal
  • 1,090
  • 1
  • 11
  • 28