|  |  | 
 
  |  |  |  |  
  |  |  |  |  
  |  |  |  |  
  |  |  |  |  
  |  | 
	
	
		
	
	
 
  |  |  |  |  
	| 
			
			 
			
				05-03-2011, 05:59 AM
			
			
			
		 |  
	| 
		
			
			| Hill Giant |  | 
					Join Date: Apr 2011 Location: Germany 
						Posts: 163
					      |  |  
	| 
				 COMMITTED: UCS crash fix 
 Okay, I think it makes sense to post my fix here, since my UCS isnt crashing anymore. 
	Quote: 
	
		| I think I found the bug in UCS that is causing a crash. 
 Debugging showed up a halt in DBCore::Open() after a call of mysql_real_connect() using an uninitialized mysql struct.
 
 The struct gets uninitialized whenever theres a connection error of some sort, because mysql.close() makes it invalid. Without another call to mysql.init() all following sql connects/commands will fail, resulting in a crash.
 
 So we just need to enter a single line of code... :
 
 (May need some more testing, but mine is running stable now for 20 hours.)
 
 
 
	Code: bool DBcore::Open(int32* errnum, char* errbuf) {
	if (errbuf)
		errbuf[0] = 0;
	LockMutex lock(&MDatabase);
	if (GetStatus() == Connected)
		return true;
	if (GetStatus() == Error)
	{
		mysql_close(&mysql);          // <- Makes struct 'mysql' invalid!
		mysql_init(&mysql);        //   <- Initialize structure again
	}
	if (!pHost)
		return false;
	/*
	Quagmire - added CLIENT_FOUND_ROWS flag to the connect
	otherwise DB update calls would say 0 rows affected when the value already equalled
	what the function was tring to set it to, therefore the function would think it failed 
	*/
	int32 flags = CLIENT_FOUND_ROWS;
	if (pCompress)
		flags |= CLIENT_COMPRESS;
	if (pSSL)
		flags |= CLIENT_SSL;
	// crashed here, because 'mysql' wasnt valid after an error followed by mysql.close() 
	if (mysql_real_connect(&mysql, pHost, pUser, pPassword, pDatabase, pPort, 0, flags)) { 
		pStatus = Connected;
		return true;
	}
	else {
		if (errnum)
			*errnum = mysql_errno(&mysql);
		if (errbuf)
			snprintf(errbuf, MYSQL_ERRMSG_SIZE, "#%i: %s", mysql_errno(&mysql), mysql_error(&mysql));
		pStatus = Error;
		return false;
	}
} | 
			
			
			
			
				  |  
 
  |  |  |  |  
	
		
	
	
	| 
			
			 
			
				05-03-2011, 06:23 AM
			
			
			
		 |  
	| 
		
			|  | Developer |  | 
					Join Date: Aug 2006 Location: USA 
						Posts: 5,946
					      |  |  
	| 
 Sounds good to me.  I will give it a shot and commit it when I have a few minutes.  Thanks for the submission! |  
	
		
	
	
	| 
			
			 
			
				05-03-2011, 06:30 AM
			
			
			
		 |  
	| 
		
			
			| Hill Giant |  | 
					Join Date: Apr 2011 Location: Germany 
						Posts: 163
					      |  |  
	| 
 Sure thing, happy to contribute to this project. |  
	
		
	
	
	| 
			
			 
			
				05-03-2011, 11:42 AM
			
			
			
		 |  
	| 
		
			
			| Dragon |  | 
					Join Date: May 2010 
						Posts: 965
					      |  |  
	| 
 My UCS has been running for 24+ hours now after this change. (Windows server) |  
	
		
	
	
	| 
			
			 
			
				05-03-2011, 03:23 PM
			
			
			
		 |  
	| 
		
			|  | Demi-God |  | 
					Join Date: May 2007 Location: b 
						Posts: 1,449
					      |  |  
	| 
 Shouldn't you just return false, then initialize the mysql connection after that if it is false? That makes more sense to me. |  
	
		
	
	
	| 
			
			 
			
				05-04-2011, 02:19 AM
			
			
			
		 |  
	| 
		
			
			| Hill Giant |  | 
					Join Date: Apr 2011 Location: Germany 
						Posts: 163
					      |  |  
	| 
 I guess youre right regarding the return false. With my quick and dirty fix you may not get any database error messages again (some may think thats a good thing though LOL). But on the other hand that way its possible that the UCS will just quit clean after it encounters a database error. I am not sure about that.
 
 I would leave init where it is, since its the only place where the mysql struct gets closed (except in the destructor), so theres no reason to call it elsewhere.
 |  
	
		
	
	
	| 
			
			 
			
				05-04-2011, 08:55 AM
			
			
			
		 |  
	| 
		
			|  | Developer |  | 
					Join Date: Mar 2003 
						Posts: 1,500
					      |  |  
	| 
 I think what he may be saying is that instead of closing mysql, return false instead? Then the connection wouldn't need to be re-initialized. |  
	
		
	
	
	| 
			
			 
			
				05-04-2011, 11:54 AM
			
			
			
		 |  
	| 
		
			
			| Dragon |  | 
					Join Date: May 2010 
						Posts: 965
					      |  |  
	| 
 came down to my office and looked at the PC running my test server and noticed that UCS crashed over night. :( |  
	
		
	
	
	| 
			
			 
			
				05-04-2011, 02:40 PM
			
			
			
		 |  
	| 
		
			
			| Hill Giant |  | 
					Join Date: Apr 2011 Location: Germany 
						Posts: 163
					      |  |  
	| 
 Were any players on during that time? |  
	
		
	
	
	| 
			
			 
			
				05-04-2011, 03:29 PM
			
			
			
		 |  
	| 
		
			
			| Dragon |  | 
					Join Date: May 2010 
						Posts: 965
					      |  |  
	| 
 Not when i came down no. It is mainly just used by me to test things.I had toons in and out yesterday most of the day and it was running.
 Went to bed early and when i came down to my office this morning UCS was crashed.
 
 UCS only crashes on a new log in that I've noticed, but then the times that I've seen it actually crash were when I logged in a toon after being offline for hours and no one else had logged in during the interim.
 
 I restarted the UCS right when I seen it crashed this morning and I have had a couple toons in and out of my server this afternoon and it hasn't crashed again yet.
 |  
	
		
	
	
	| 
			
			 
			
				05-04-2011, 03:52 PM
			
			
			
		 |  
	| 
		
			
			| Hill Giant |  | 
					Join Date: Apr 2011 Location: Germany 
						Posts: 163
					      |  |  
	| 
 My UCS is running in visual studio debug mode all of the time. Got a database error actually today, but no crash. |  
	
		
	
	
 
  |  |  |  |  
	| 
			
			 
			
				05-05-2011, 02:34 AM
			
			
			
		 |  
	| 
		
			
			| Hill Giant |  | 
					Join Date: Apr 2011 Location: Germany 
						Posts: 163
					      |  |  
	| 
				  
 I analyzed the UCS code a bit further and I am now 99.99%    sure that my fix is the way it is supposed to be. 
 
When the function dbcore::RunQuery() results in a connection/database error, it is calling itself again for exactly 1 retry, but on that 2nd call it checks for the status. If pStatus = error then dbcore::Open() is called. 
 
Open() calls mysql_close() on any error status and is supposed to reconnect in the same call, but will definitetely fail without mysql_init(). So placing a FALSE after the "close" or "init" would prevent Open() to reconnect.
 
All that is missing now is a confirmation message, that the recovery of the encountered error was successful.
 
	Code: bool DBcore::RunQuery(const char* query, int32 querylen, char* errbuf, MYSQL_RES** result, int32* affected_rows, int32* last_insert_id, int32* errnum, bool retry) {
	_CP(DBcore_RunQuery);
	if (errnum)
		*errnum = 0;
	if (errbuf)
		errbuf[0] = 0;
	bool ret = false;
	LockMutex lock(&MDatabase);
	if (pStatus != Connected)
		Open();
#if DEBUG_MYSQL_QUERIES >= 1
	char tmp[120];
	strn0cpy(tmp, query, sizeof(tmp));
	cout << "QUERY: " << tmp << endl;
#endif
	if (mysql_real_query(&mysql, query, querylen)) {
		if (mysql_errno(&mysql) == CR_SERVER_GONE_ERROR)
			pStatus = Error;
		if (mysql_errno(&mysql) == CR_SERVER_LOST || mysql_errno(&mysql) == CR_SERVER_GONE_ERROR) {
			if (retry) {
				cout << "Database Error: Lost connection, attempting to recover...." << endl;
				ret = RunQuery(query, querylen, errbuf, result, affected_rows, last_insert_id, errnum, false);
				if ( !ret )
					cout << "Reconnection to database successful." << endl;
			}
			else {
...
...
... Unfortunetely, that doesn't explain the latest crash of yours, sorvani. This may be an other error I have not encountered yet .
			
			
			
			
				  |  
 
  |  |  |  |  
	
		
	
	
	| 
			
			 
			
				05-05-2011, 09:50 AM
			
			
			
		 |  
	| 
		
			
			| Dragon |  | 
					Join Date: May 2010 
						Posts: 965
					      |  |  
	| 
 Looked at my server this morning and the chat service was still running. Looked at the character_ table and it look like only a single random toon signed on after the last time I was on. 
I started my client and connected. As soon I clicked enter world the UCS crashed. With the standard WIndows XP please report dialog box. 
In the command window:
 
	Code: Database Error: Lost connection, attempting to recover.... 
	Code: Character	TimeLastOn
TestBeasti	1304535868 <- working
GMSorvani	1304535876 <- working
XXXXXX		1304540215 <- working
TestBeasti	1304602955 <- crashed at enter world |  
	
		
	
	
	| 
			
			 
			
				05-05-2011, 09:54 AM
			
			
			
		 |  
	| 
		
			
			| Hill Giant |  | 
					Join Date: Apr 2011 Location: Germany 
						Posts: 163
					      |  |  
	| 
 Aye, thats the error I encountered last time, but for me it doesnt crash, it actually recovers now. |  
	
		
	
	
	| 
			
			 
			
				05-05-2011, 10:12 AM
			
			
			
		 |  
	| 
		
			
			| Dragon |  | 
					Join Date: May 2010 
						Posts: 965
					      |  |  
	| 
 Looked at my build again and found an error on my side. When I added the mysql_init I had a syntax error. Rebuilt and restarted. |  
	
		
	
	
	
	
	| 
	|  Posting Rules |  
	| 
		
		You may not post new threads You may not post replies You may not post attachments You may not edit your posts 
 HTML code is Off 
 |  |  |  All times are GMT -4. The time now is 02:31 PM.
 
 |  |  
    |  |  |  |  
    |  |  |  |  
     |  |  |  |  
 |  |