BigCommerce - Hosted Ecommerce Software by Interspire

Interspire Forum

 
Go Back   Interspire Forum > Interspire Email Marketer Community Forum > Customization and Integration

Reply
 
Thread Tools Display Modes
  #1  
Old 10-13-2011, 10:11 AM
vimmaniac + vimmaniac is offline
Interspire Customer
 
Join Date: Apr 2011
Location: Bangladesh
Posts: 87
Send a message via Skype™ to vimmaniac
Default [IEM 6.1.1/6.1.2] Call stack exhaustion if a particular mysql error(2006) occurs.

##########
Bug Report
################################################## ###################
Call stack exhaustion after "MYSQL Error 2006: Server has gone away."
################################################## ###################


================================================== ===================
File: [iem_root]/admin/com/ext/database/mysql.php
================================================== ===================
PHP Code:
class MySQLDb extends Db
{
    ...

        function 
Connect($hostname=null$username=null$password=null$databasename=null)
        {
            ... 

            if (
$this->_retry && is_resource($this->connection)) {
                
$this->Disconnect($this->connection);
            }

            ...

            
// Set the character set if we have one
            
if($this->charset) {
                
$this->Query('SET NAMES '.$this->charset);
                
$this->Query("SET CHARACTER SET " .$this->charset);
            }

            
// Do we have a timezone? Set it
            
if($this->timezone) {
                
$this->Query("SET time_zone = '".$this->timezone."'");
            }

            ...
        }

    ...

        function 
Query($query='')
        {
            
// if we're retrying a query, we have to kill the old connection and grab it again.
            // if we don't, we get a cached connection which won't work.
            
if ($this->_retry) {
                
$this->Connect();
            }

            ...

            if (!
$result) {
                ...
                
$errorno mysql_errorno($this->connection);

                ...

                if (
$this->_retry || $errno !== 2006) {
                    
$this->_retry false;
                    return 
false;
                }

                ...


                if (
$errno === 2006) {
                    
$this->_retry true;
                    return 
$this->Query($query);
                }

                ...

        }

    ...

================================================== ===================



Condition:
================================================== ===================
1) Let's say, we have a query that failed with a
"MySQL Error: 2006 Server has gone away." in method 'Query()'.

PHP Code:
$errorno mysql_errorno($this->connection); // $errorno == 2006 


2) Then, 'Query()' will call itself after setting
'$this->_retry' to true.
PHP Code:
        if ($errno === 2006) {
            
$this->_retry true;
            return 
$this->Query($query);
        } 

3) Next call to 'Query()' will see that '$this->_retry'
is true, so it will call 'Connect()'.
PHP Code:
        if ($this->_retry) {
            
$this->Connect();
        } 
4) After successfully reconnection, 'Connect()' will try to call 'Query()'
to set charset and timezone, given '$this->charset' or '$this->timezone'
properties are set.
PHP Code:
        // Set the character set if we have one
        
if($this->charset) {
            
$this->Query('SET NAMES '.$this->charset);
            
$this->Query("SET CHARACTER SET " .$this->charset);
        }

        
// Do we have a timezone? Set it
        
if($this->timezone) {
            
$this->Query("SET time_zone = '".$this->timezone."'");
        } 
5) Interpreter is back to step 2 with still having '$this->_retry' set to true.
Mutual recursion continues until call stack is exhausted or php maximum
allowed memory limit is reached.



Affected version:
================================================== =========================
This bug creeps in IEM 6.1.1 and 6.1.2, but not in 6.1.0. My speculation
is that '$this->charset' and '$this->timezone' is not used prior to 6.1.1.



Solution:
================================================== =================
One simple solution is to set '$this->_retry' to false right after
the disconnection in 'Connect()' method.
PHP Code:
        function Connect($hostname=null$username=null$password=null$databasename=null)
        {
            ... 

            if (
$this->_retry && is_resource($this->connection)) {
                
$this->Disconnect($this->connection);
                
$this->_retry false;
            }
            ...
       } 
__________________
Sysadmin/Postmaster
Reply With Quote
Reply

Tags
bug, bug fix, mysql

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On

Forum Jump