Development > Coding and development discussion

[resolved] MySQL fails to reconnect if database server is not local

(1/1)

Khalem:
I just ran across this by accident tonight. I ha vent had time to test it or look into it any further atm, so I'm documenting it here so i dint forget (and in case someone else gets to it before me)

It seems the bot doesn't handle loosing the database server very gracefully, at least not if the database connection is to a remote host.
Spams: (MySQL server has gone away)
Does not appear to reconnect even after the server is back up again.

Khalem:
Easy diagnose.. the bot makes no attempt at reconnecting.
This might only be an issue when the mysql socket isnt being used though.

Should be an relatively easy fix. *adds to ToDo list*

Khalem:
Just comitted a fix to SVN along with a little revamp of error handeling.

New MySQL.php

--- Code: ---<?php
/*
* MySQL.php - MySQL interaction
*
* BeBot - An Anarchy Online Chat Automaton
* Copyright (C) 2004 Jonas Jax
* Copyright (C) 2005 Thomas StensÃ¥s and ShadowRealm Creations
*
* Developed by Blondengy (RK1)
* Special thanks goes out to Khalem (RK1) for his support.
*
*  This program is free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
*  USA
*
* File last changed at $LastChangedDate: 2006-02-01 22:17:03 +0100 (on, 01 feb 2006) $
* Revision: $Id: MySQL.php 71 2006-02-01 22:17:03 +0100 (on, 01 feb 2006) shadowmaster $
*/


class MySQL
{
var $CONN = "";
var $DBASE = "";
var $USER = "";
var $PASS = "";
var $SERVER = "";

function MySQL()
{
$this -> error_count = 0;
$this -> last_error = 0;
$this -> last_reconnect = 0;

/*
Load up config
*/
include "conf/MySQL.conf";

$this->USER = $user;
$this->PASS = $pass;
$this->SERVER = $server;
$this->DBASE = $dbase;

$this -> connect(true);

return true;
}

function connect($fatal = false)
{
$conn = mysql_connect($this -> SERVER, $this -> USER, $this -> PASS, true);

if (!$conn)
{
$this->error("Cannot connect to the database server!", $fatal);
return false;
}
if(!mysql_select_db($this -> DBASE, $conn))
{
$this->error("Database not found or insufficient priviledges!", $fatal);
return false;
}
                echo "Connected to MySQL\n";
$this->CONN = $conn;
$this->error_count = 0;
}


function error($text, $fatal = false)
{
// Check if more than 30 seconds has passed since the last error
if (time() >= ($this -> last_error + 30))
{
// If so reset the error count
$this -> error_count = 0;
}

// We display a maximum of 10 errors every 10 seconds to prevent flooding of the logs/console
if ($this -> error_count <= 10)
{
$msg = mysql_error();
echo "MySQL error (# " . $this -> error_count . ") on query: $text\n";
echo "$msg\n";

// If this error is occuring while we are trying to first connect to the database when starting
// rthe bot its a fatal error.
if ($fatal == true)
{
exit;
}

// Did we just loose the connection to the database server?
if (strcasecmp($msg, "MySQL server has gone away") == 0)
{
// We wait 30 seconds between each reconnect attempt
if (time () >= ($this -> last_reconnect + 30))
{
// Lets reconnect
echo "Attempting reconnect to MySQL server...\n";
$this -> last_reconnect = time();
$this -> connect(false);
}
}
$this -> error_count += 1;
$this -> last_error = time();
if ($this -> error_count == 11)
{
echo "Threshold of 10 errors in 30 seconds reached. Supressing error output for 30 seconds\n";
}
}

}


function select ($sql)
{
$data = "";
$result = mysql_query($sql, $this->CONN);

if (!$result)
{
$this -> error($sql);
return false;


if (empty($result))
{
return false;
}

$count = 0;

while ($row = mysql_fetch_array($result, MYSQL_NUM))
{
$data[$count] = $row;
$count++;
}

mysql_free_result($result);
return $data;
}


function query ($sql)
{

$return = mysql_query($sql, $this->CONN);

if (!$return)
{
$this -> error($sql);
}
}


function returnQuery ($sql)
{
return mysql_query($sql, $this->CONN);
}


function dropTable ($sql)
{
$result = mysql_query("DROP TABLE " . $sql, $this->CONN);
}
}
?>


--- End code ---

Navigation

[0] Message Index

Go to full version