Bug #51970 Problem reconnecting with C API
Submitted: 11 Mar 2010 20:26 Modified: 21 Aug 2010 18:00
Reporter: Robert Gebis Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server: C API (client library) Severity:S1 (Critical)
Version:5.5.2-m2, 5.5.5-m3 OS:Windows (Windows 7 x64)
Assigned to: CPU Architecture:Any
Tags: API, C, reconnect, reinitialize

[11 Mar 2010 20:26] Robert Gebis
Description:
When trying to reinitialize connection (my allocation is going into restart mode)
I get this message after mysql_real_connect(). Please note the double \\ in windows path.

"Can't initialize character set latin1 (path: c:\Program Files\MySQL\MySQL Server 5.5\\share\charsets\". Such path exists here it is taken from cmd.exe

C:\Program Files\MySQL\MySQL Server 5.5\share\charsets

It connect every time fine on initial process restart

How to repeat:
1. Connect to server
2. Disconnect
        mysql_close( m_pMySql ); 
        delete m_pMySql;
        m_pMySql = 0L;
        mysql_library_end();

3. Reconnect in the same process
        m_pMySql = new MYSQL;
        mysql_init( m_pMySql)
        my_bool  my_true = TRUE;
        mysql_options( m_pMySql, MYSQL_OPT_RECONNECT, &my_true)
        mysql_real_connect() <----- ERROR
        mysql_error( m_pMySql ) - > c:\Program Files\MySQL\MySQL Server 5.5\\share\charsets\
[11 Mar 2010 20:31] MySQL Verification Team
Thank you for the bug report. Could you please provide the complete C/C++ test code. Thanks in advance.
[11 Mar 2010 21:33] Robert Gebis
I have to create one and post it tomorrow.
[15 Mar 2010 22:56] Robert Gebis
Is there anything else I can help with?
[15 Mar 2010 22:58] Robert Gebis
Is there anything else I can help with?
[8 Jul 2010 11:28] pascal sautot
I had the same problem.

here a the simple src code I used

static bool testMySQL()
{
	bool x,ok(true);
	int s;

	const int n(10);
	// MySQL
	int i=0;
	for(; (i<n)&& ok; i++)
	{
	s = mysql_library_init(0,0,0);
	x= (s == 0); ok &= x;
	cout<<"mysql_library_init "<<x<<endl;

		MYSQL * sql = 0;
		sql=mysql_init(0);

		x= (sql != 0); ok &= x;
		cout<<"mysql_init "<<x<<endl;
		if(!x) break;

		my_bool reconnect = 1;
		mysql_options(sql,MYSQL_OPT_RECONNECT,&reconnect);
		
		MYSQL *c = mysql_real_connect(sql,"localhost","capsys_user","pilou","test",3306,0,0);
		x= (c != 0); ok &= x;
		cout<<"mysql_real_connect "<<x<<endl;
		if (!x) { mysql_close(sql); break; }

		mysql_close(sql); 
	mysql_library_end();
	}
	x=(i==n);
	ok &= x; 
	cout<<"- mysql "<<ok<<endl; 

	return ok;
}

if the calls to mysql_library_init() and mysql_library_end() are pooled out the loop this is ok, otherwise this fails for the second iteration.

I guess both mysql_library_init() and mysql_library_end() must be called only once per process execution. Here is a citation from the documentation
 
"In a nonmulti-threaded environment, the call to mysql_library_init() may be omitted, because mysql_init() will invoke
it automatically as necessary. However, mysql_library_init() is not thread-safe in a multi-threaded environment, and
thus neither is mysql_init(), which calls mysql_library_init(). You must either call mysql_library_init()
prior to spawning any threads, or else use a mutex to protect the call, whether you invoke mysql_library_init() or indirectly
via mysql_init(). This should be done prior to any other client library call."

Hope this helps
[2 Aug 2010 12:17] Sveta Smirnova
Robert,

please try Pascal's suggestion and inform us if it works.
[2 Aug 2010 17:07] Robert Gebis
I am not using mysql_library_init. On the other I was calling mysql_library_end multiple of times per each Disconnect() in my mysql wrapper. Moving it to class destructor made thing happier. Now even this make things work better it is still a little problem if I construct and destruct my mysql wrapper class multiple times while process is running (Teardown/ReInit). For not I just have to avoid doing so. Which is OK I guess for now. One this that normally I could call mysql_library_end when my program exits but in my case all my mysql code is in shared object that is loaded and unloaded without process going down. Do you see my point? Thank you temp fix :)
[2 Aug 2010 17:12] Robert Gebis
I just want to point out that I moved to 5.5.5-m3 from 5.5.2-m2. So I have only tested above suggestion on latest build since I do not have access to 5.5.2-m2 anymore. Not sure if this was fixed in-between builds or what was suggested is a proper thing to do. I leave this decision to you guys...
[21 Aug 2010 18:00] Sveta Smirnova
Thank you for the feedback.

If I understood correctly fixing of your code fixes the problem. This means problem was not result of the MySQL bug. Closing report as such.