weedo tech blog

le blog technique de la team weedo

  • Home
  • Ka on twitter
    • Edit
    • Delete
    • Tags
    • Autopost

    SQLSTATE[HY000]: General error: 2006 MySQL server has gone away

    Avoir accès à un objet PDO n'est pas suffisant pour être certain d'avoir une connexion à une bdd. Il arrive de passer une requête et d'obtenir l'erreur :

    Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 2006 MySQL server has gone away' in…

    Pour obtenir cette erreur, vous pouvez faire le test suivant :

    $pdo = new PDO($dsn, $user, $password);
    echo get_class ($pdo);
    // On a bien un objet PDO
    $pdo->query('select 1');
    // ça passe
    sleep(20);
    // Vous avez 20 secondes pour killer manuellement la connexion mysql. Faites-le pour les besoins du tests, 
    echo get_class ($pdo);
    // On a toujours un objet PDO, mais cet objet n'est pas informé que la connexion correspondante a été killée, ce qu'on va voir tout de suite : 
    $pdo->query('select 1');
    // !! ça casse : Erreur MySQL server has gone away. Pourtant, on avait bien un objet PDO

    Les raisons possibles de cette erreurs sont nombreuses : http://dev.mysql.com/doc/refman/5.0/en/gone-away.html

    En plus de/plutôt que/en attendant de résoudre le problème, j'ai trouvé 2 méthodes (assez proche) pour contourner le problème : On tente la connexion avec notre vieille connexion pdo, et si on obtient une erreur, on créé un nouvel objet pdo tout neuf.

    Méthode 1

    $sql = 'SELECT count(*) FROM `TABLE`;';
    for ($i = 1; $i <= 2; $i++) {
        try {
            $nb = $pdo->query($sql)->fetchColumn();
            if (is_int($nb)) {
                // C'est bon, ma vieille connexion a fonctionné.
                break;
            }
        } catch (PDOException $e) {
        //Oups, j'ai une erreur de connexion
            if ($i == 1) {
                // C'est la première fois ? OK, je recréé une connexion.
                $pdo = new PDO($dsn, $user, $password);
            } else {
                // C'est la 2eme fois ? OK, c'est mort.
                $nb = "(nombre inconnu)";
                echo 'PDO Connection failed: ' . $e->getMessage().'. ';
            }
        }
    }

    Méthode 2

    // Je test si ma vieille connexion est OK avec une requête toute simple
    try {
        $pdo->query('select 1;')
        //C'est bon;
    } catch (PDOException $e) {
        //Oups, j'ai une erreur de connexion
        // Je recréé une connexion.
        $pdo = new PDO($dsn, $user, $password);
    }
    // Ici j'ai plus de chance d'avoir un objet pdo viable que si je n'avais pas fait le petit try/catch au-dessus => Je fais ma requête
    $sql = 'SELECT count(*) FROM `TABLE`;';
    $nb = $pdo->query($sql)->fetchColumn();

    Comme d'hab, si quelqu'un a mieux, ce que j'espère, je suis preneur !

    • 27 July 2011
    • Views
    • 0 Comments
    • Permalink
    • Favorited 0 Times
    • Tweet
    • Tweet

    Comments 0 Comments

    Leave a Comment

  • About ka

    My Google Profile

  • Contributors

    • ka
    • Ballut Vincent
    • fix
    • Stevan Gaillard
  • Subscribe

    Subscribe to this posterous
    Unsubscribe
    Follow this posterous RSS
    You're a contributor here (Edit)
    This is your Space (Edit)
    Follow by email »
    Get the latest updates in your email box automatically.
  • Follow Me

      TwitterDelicious

Theme created for Posterous by Obox