Bug #1339 mysql_server_end hangs after accessing embedded InnoDB table
Submitted: 18 Sep 2003 12:09 Modified: 30 Jan 2004 5:25
Reporter: Robert McCarter Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S2 (Serious)
Version:4.1.0 alpha OS:Windows (Windows 2000 SP4)
Assigned to: Alexey Botchkov CPU Architecture:Any

[18 Sep 2003 12:09] Robert McCarter
Description:
Using the embedded database works wonderfully unless I access an InnoDB table which seems to cause mysql_server_end() to hang indefiniately.

If I never access an InnoDB table then everything works fine.

When I use the remote libmysql.dll to access an InnoDB table everything (obviously) works fine, so I do not believe this is a setup issue.

How to repeat:
int Error( MYSQL* _mysql );

// ////////////////////////////////////////////////////////////////////////////
// main
// ////////////////////////////////////////////////////////////////////////////
int main( int _argc, char* _argv[] ) {
    // Initialize Embedded Database /////////////////////////
    char* groups[]    = {"embedded", 0 };
    char* args[]    = { "--init-file=C:/WinNT/my.ini" };
    int result = mysql_server_init(1, args, groups );
    if( result!=0 ) return Error( 0 );

    // Initialize a MySQL Handle ////////////////////////////
    MYSQL* mySQL = mysql_init( 0 );
    if( mySQL==0 ) return Error(mySQL);

    // Connect to the embedded database /////////////////////
    MYSQL* connectResult =
        mysql_real_connect(mySQL,"localhost","program","password","test",0,0,0);
    if( connectResult==0 ) return Error(mySQL);

    // Perform a query //////////////////////////////////////
    string query; 
    // query = "SELECT * FROM SomeMyISAMTable"; // Works fine
    query = "SELECT * FROM SomeInnoDBTable"; // Hangs mysql_server_end()
    result = mysql_real_query(mySQL,query.c_str(),(unsigned long)query.size());
    if( result!=0 ) return Error(mySQL);

    // Retrieve the results //////////////////////////////////
    MYSQL_RES* resultHandle = mysql_store_result(mySQL);
    if( resultHandle==0 ) return Error(mySQL);

    // Free the result handle ///////////////////////////////
    mysql_free_result(resultHandle);

    // Close any transaction ////////////////////////////////
    query = "COMMIT";            // This doesn't help
    result = mysql_real_query(mySQL,query.c_str(),(unsigned long)query.size());
    if( result!=0 ) return Error(mySQL);

    // Close the MySQL Handle ///////////////////////////////
    mysql_close(mySQL);

    // Shutdown the Embedded Database ///////////////////////
    mysql_server_end();  // HANGS Indefinitely
    cout << endl << "Done!";
    return 0;
}//main

// ////////////////////////////////////////////////////////////////////////////
// Error Helper Function
// ////////////////////////////////////////////////////////////////////////////
int Error( MYSQL* _mysql ) {
    int    errorCode     = (int)mysql_errno(_mysql);
    string    mySQLMessage = mysql_error(_mysql);            
    cout << endl << errorCode << " - " << mySQLMessage;
    return (int)errorCode;
}

Suggested fix:
Stack at Hang:
	main()
	mysql_server_end()
	clean_up()
	table_cache_free()
	close_cached_tables()
	hash_delete()
	free_cache_entry()
	internal_close_table()
	closefrm()
	ha_innobase::close()
	my_no_flags_free()

The variable upd_buff in ha_innobase::close( ) (in ha_innodb.cpp)
does not seem to be a valid pointer as the data it is pointing to is:
"¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥"....
[18 Sep 2003 16:24] MySQL Verification Team
Thank you for the bug report I was able to repeat.
The stuck happens when free(ptr) is called at the 
code bellow:

/mysys/my_malloc.c

void my_no_flags_free(gptr ptr)
{
  DBUG_ENTER("my_free");
  DBUG_PRINT("my",("ptr: %lx",ptr));
  if (ptr)
    free(ptr);
..........

Below the stack trace:

my_no_flags_free(char * 0x02a4a5b0) line 59
ha_innobase::close() line 1532 + 15 bytes
closefrm(st_table * 0x02a49d50) line 728 + 17 bytes
intern_close_table(st_table * 0x02a49d50) line 205 + 9 bytes
free_cache_entry(st_table * 0x02a49d50) line 224 + 9 bytes
hash_delete(st_hash * 0x1047cec8, unsigned char * 0x02a49d50) line 433 + 10 bytes
close_cached_tables(THD * 0x00000000, int 0, st_table_list * 0x00000000) line 272 + 17 bytes
table_cache_free() line 60 + 11 bytes
clean_up(int 0) line 882
mysql_server_end() line 289 + 7 bytes
main(int 1, char * * 0x007e11a0) line 59
mainCRTStartup() line 206 + 25 bytes
[30 Jan 2004 5:25] Alexey Botchkov
Thank you for your bug report. This issue has already been fixed
in the latest released version of that product, which you can download at 
http://www.mysql.com/downloads/

Additional info:

I checked this with the 4.1.1
[19 Dec 2004 13:09] Piotr Pyrzanowski
I've got the same situation on mysql server version 4.1.7 and recently downloaded 4.1.8. I've been using both debug and release versions of libmysqld.dll (not with static library). I develop on WinXP with Dev-C++ and mingw 3.3.1 and I use InnoDB tables. My application calls mysql_server_init at the begining and mysql_server_end at the exit, if I do any query between, application hangs on mysql_server_end.
[2 Mar 2005 12:06] Wolfgang Rohdewald
I have 4.0.23 on debian unstable, it also hangs if a mysql_close() is missing.