|   | php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
| 
  [2002-09-20 13:28 UTC] sroussey at network54 dot com
 There is no easily repeatable test case, as this seems to only happen at high load, and it is intermittent. Randomly, mysql_query will fail (more specificly, mysql_db_query), and the error message is "Commands out of sync". MySQL info on error: http://www.mysql.com/doc/en/Commands_out_of_sync.html Other users have confirmed this back to version 4.2.1. We only use the built-in mysql client lib in PHP. PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits             | |||||||||||||||||||||||||||||||||||||
|  Copyright © 2001-2025 The PHP Group All rights reserved. | Last updated: Fri Oct 31 01:00:01 2025 UTC | 
I have been looking through CVS log at lxr.php.net to see what has changed in mysql support in PHP this last year. One change was the inclusion of mysql.connect_timeout. In the docs it says the default is 0. This is backed up by the default: 496 mysql_globals->connect_timeout = 0; However, I expected the line: 352 STD_PHP_INI_ENTRY_EX("mysql.connect_timeout","",... to have ("mysql.connect_timeout","0", Also, things seem odd to me: 651 if (connect_timeout != -1) 749 if (connect_timeout != -1) Why is it checking for the connect_timeout as to -1 rather than zero? I think telling mysql that the connect timeout is zero causes the problems: the connection closes really quick! Well, it seems to be a race condition anyhow. As a default. Ick. And exploited by the time the connect is reused. I set mysql.connect_timeout = -1 in the .ini file as a temp workaround. Seems to be working. I will wait a day and report if this indeed eliminates these errors.Last data point: the workaround in my last message works with 3.23.x but not 4.0.x as far as I can tell. Here is my test matrix: PHP client using built-in mysql libs. Server: 3.23.49a 4.0.2 -------- ---- connect OK OK pconnect fail fail pconnect OK fail w/ fixMySQL is complaining about things not being cleaned up. This is because any query that returns results (which one's don't -- any?) must get them. In case of an unbuffered query, we need to eat the rest of the rows before exiting (like we do when a new query is run when an old unbuffered query was not finished). I removed the warning in this case, but you all can change it as you please. The case that is hitting me (and EVERYONE out there using persistent connections with current revs) is that there is a rollback. But there is nothing to get the results of the rollback. This means, that the next script to use this persistent connection will generally fail on the first query, but might do alright on the others. For this reason, I recommend anyone use PHP 4.2.3 (maybe earlier versions as well) to turn off persistent connections for now. Also, in CVS there is something to reset AUTOCOMMIT. It also did not clean up and that causes additional issues. I removed it rather than fixed it. Who says AUTOCOMMIT=1 should be the default for a certain server? That is user configurable on the server side. Personally, I like the idea of resetting all the variables that might have been changed (including that one). There are a lot. No good way to do it right now. Oh, what else? Ah.. the code in CVS for mysql.connection.timeout. That rocks! However, it sets the default to zero and then checks for -1 as a sign not to include the option. Oops. So the default timeout value is set to nothing when the user doesn't do anything. That is a unpredictable change in behavior. I have some changes below. My first time even looking at this code, so look for any mistakes. static int _restore_connection_defaults(zend_rsrc_list_entry *rsrc TSRMLS_DC) { php_mysql_conn *link; char query[128]; char user[128]; char passwd[128]; /* check if its a persistent link */ if (Z_TYPE_P(rsrc) != le_plink) return 0; link = (php_mysql_conn *) rsrc->ptr; if (link->active_result_id) do { int type; MYSQL_RES *mysql_result; mysql_result = (MYSQL_RES *) zend_list_find(link->active_result_id, &type); if (mysql_result && type==le_result) { if (!mysql_eof(mysql_result)) { while (mysql_fetch_row(mysql_result)); } zend_list_delete(link->active_result_id); link->active_result_id = 0; } } while(0); /* rollback possible transactions */ strcpy (query, "ROLLBACK"); if (mysql_real_query(&link->conn, query, strlen(query)) !=0 ) { MYSQL_RES *mysql_result=mysql_store_result(&link->conn); mysql_free_result(mysql_result); } /* unset the current selected db */ #if MYSQL_VERSION_ID > 32329 strcpy (user, (char *)(&link->conn)->user); strcpy (passwd, (char *)(&link->conn)->passwd); mysql_change_user(&link->conn, user, passwd, ""); #endif return 0; } And change the two copies of this: if (connect_timeout != -1) to if (connect_timeout <= 0) My 2 cents for the day.