From 104c99f2c84485a03577e35c700d566e61c09e9f Mon Sep 17 00:00:00 2001 From: Urban Müller Date: Fri, 6 Jun 2008 15:11:37 +0000 Subject: reconnect if mysql server goes away --- it_dbi.class | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/it_dbi.class b/it_dbi.class index 3bc82c9..396ff84 100644 --- a/it_dbi.class +++ b/it_dbi.class @@ -34,7 +34,6 @@ class it_dbi 'safety' => 1, # 0= never die, 1=die if query invalid, 2=die also if no results #'keyfield' => 'ID', # Don't set to null here, filled later by _get_field_info() 'classprefix' => "", - 'persistent' => false, 'getfieldinfo' => true, # do not read schema. only select() allowed ); @@ -113,7 +112,7 @@ function createclasses($p = array()) $dbi->_connect($p); if (!($tables = mysql_list_tables($p['db'], $dbi->_link))) - $dbi->_fatal("it_dbi::createclasses(): can't list on tables \"{$p['db']}\""); + $dbi->_fatal("createclasses(): can't list on tables \"{$p['db']}\""); for ($i = 0; $i < mysql_num_rows($tables); $i++) it_dbi::createclass(array('table' => mysql_tablename($tables, $i)) + $p); @@ -170,27 +169,28 @@ function createclass($p) function _connect($p = array()) { $p += $this->_p; - if (!($this->_link = $GLOBALS['it_dbi']->_state[$p['dbid']]['link'])) + + if ($p['reconnect'] || !($this->_link = $GLOBALS['it_dbi']->_state[$p['dbid']]['link'])) { - # Use persistent connections but prevent reuse if only DB differs - if (!$p['persistent'] || $GLOBALS['it_dbi']->_connected["{$p['server']}/{$p['user']}"]++) + # Force new link if same server/user was seen before (mysql ignores selected db) + if ($GLOBALS['it_dbi']->_connected["{$p['server']}/{$p['user']}"]++) $this->_link = @mysql_connect($p['server'], $p['user'], $p['pw'], true); else $this->_link = @mysql_connect($p['server'], $p['user'], $p['pw']); if (!$this->_link) { - # One retry after a short delay (always non-persistent) + # One retry after a short delay it::log('sqllog', "it_dbi(): retrying DB link (mysql_connect {$p['server']}, {$p['db']}): " . mysql_error()); sleep(1); $this->_link = @mysql_connect($p['server'], $p['user'], $p['pw'], true); } if (!$this->_link) - $this->_fatal("it_dbi(): can't create DB link (mysql_connect {$p['user']}@{$p['server']}, {$p['db']})"); + $this->_fatal("_connect(): can't create DB link (mysql_connect {$p['user']}@{$p['server']}, {$p['db']})"); if (!(@mysql_select_db($p['db'], $this->_link))) - $this->_fatal("it_dbi(): can't select database \"{$p['db']}\""); + $this->_fatal("_connect(): can't select database \"{$p['db']}\""); $GLOBALS['it_dbi']->_state[$p['dbid']]['link'] = $this->_link; } @@ -327,10 +327,15 @@ function _where($params = "", $link = null, $omit_where = false) */ function _fatal($text) { - if ($this->_link && ($t = mysql_error($this->_link))) - $mysql_error = ", mysql_error=$t"; + $text .= ", server=" . $this->_p['server']; + + if ($this->_link && ($res = @mysql_fetch_row(mysql_query('select database()', $this->_link)))) # dont create extra errs + $text .= ", db=" . $res[0]; + + if ($this->_link && ($errno = mysql_errno($this->_link)) && ($errstr = mysql_error($this->_link))) + $text .= ", error=$errno ($errstr)"; - it::fatal(get_class($this).'::'.$text . $mysql_error); + it::fatal(get_class($this).'::'.$text); /* NOT REACHED */ } @@ -390,12 +395,19 @@ function query($query) if (!($result = mysql_query($query, $this->_link)) && $this->_p['safety']) { - if (($this->_p['safety'] < 2) && (mysql_errno($this->_link) == 1062)) # Duplicate entry + $errno = mysql_errno($this->_link); + if (($this->_p['safety'] < 2) && ($errno == 1062)) # Duplicate entry return false; - $error = mysql_errno($this->_link).' ('.mysql_error($this->_link).')'; - $res = @mysql_fetch_row(mysql_query('select database()', $this->_link)); # dont create extra errs - $this->_fatal("query(\"$query\") on {$res[0]} failed: $error"); + if ($errno == 2006) # mysql server has gone away: retry + { + it::log('sqllog', "it_dbi(): reconnecting mysql_connect {$this->_p['server']}, {$this->_p['db']}"); + $this->_connect(array('reconnect' => true)); + $result = mysql_query($query, $this->_link); + } + + if (!$result) + $this->_fatal("query(\"$query\") failed"); } -- cgit v1.2.3