So, I'm getting the following error:
Error Number: 2006
MySQL server has gone away
I can all but guarantee this is because the script takes a bazillion minutes to run, and then more queries are run in the middle of the script. Considering this is an admin-only, huge file-writing script, this is to be expected. (and is perfectly acceptable) I think the MySQL connection is getting closed because PHP / MySQL / something isn't holding it open. However, I can't for the life of me figure out how to stop this timeout from occurring!
I have the following at the top of my PHP script, but it doesn't appear to be helping.
ini_set('default_socket_timeout', -1);
ini_set('max_execution_time', -1);
ini_set('memory_limit', -1);
ini_set('mysql.connect_timeout', -1);
Any idea how I can fix this problem? Thanks!
I think a viable option would be to mysql_connect everytime before you call mysql_query. This ensures that there will be a live connection before every query.
But a much better approach is to first check for the connection status, and only then reconnect if necessary. mysql_ping is useful for checking the connection status, so you can use this to check if re-connection is required. Example code present in #galador's answer.
Thanks #diolemo and #galador.
Related
I've got a script that does heavy database manipulation.
it worked all okay untill i reached a higher number of databases where to fire the manipulations. now i collide with the max_script_execution timeout.
is it possible to handle the databases one by one when i redirect to the same script with a param for the next db by header location?
or would this not affect the max_script_execution and timeout anyway?
Try this,
Add this line in the top of your php script.
ini_set('max_execution_time', 0);
But, one thing remember, it is not a good trick to follow. You should check you script to minimize the execution time.
What the flippedy hell is wrong with that error, and where does it come from ?
I'm in charge of renovating a website and the page was covered in errors because of the use of mysql_connect, so I switched to mysqli_connect and got this error in the process.
EDIT: Here's the code of "mysql.php":
<?php
$db = mysqli_connect("host","username","password","database");
#session_start();
?>
(The session start is here because hte file is called at the start of every page. The informations in "..." has obviously been modified)
The error lies in the mysqli_connect. Question answered.
However to trouble shoot your problem(what you are acutally asking) try the following steps:
if you make a blank php page and connect to the database, does it also give errors?
Is the database server up and running?
Is the database corrupted?
is there a backup database?
Is mysqli even installed on that server?
What's the PHP version? Does it support mysqli?
Did all mysql_real_escape_string get transformed to the mysqli variant?
I have some code that I know will reach max timeout at some point.
I tried using try-catch to handle this error, but I have just been informed timeouts can't be caught this way.
Is there a way I can catch the error, or count processing time and handle the error just before it reaches timeout?
As rightly mentioned by iTom, first you need to figure out, why your code is taking 30 seconds.
If it is expected & you are doing some sort to database updation then in drupal, we have provision to handle this. You need to use Drupal batch APIs.
Check here for more details: https://api.drupal.org/api/drupal/includes!form.inc/group/batch/7
Functions allowing forms processing to be spread out over several page
requests, thus ensuring that the processing does not get interrupted
because of a PHP timeout, while allowing the user to receive feedback
on the progress of the ongoing operations.
Maximum execution time is a PHP Error not a PHP Exception, therefore your error handling code will be unable to catch an exception that doesn't actually exist. The Execution time limit is really a last resort for the PHP Server to kill a function that's basically gone out of control.
You really need to look into why your database code is taking 30~ seconds to execute and resolve the code/database issue. Another (not recommended) option would be to increase the Maximum execution time in PHP to something suitable for your code.
You can echo time() at before and after of function to count processing
I am a paranoid kind of guy and even though I included mysql_close() in my PHP functions after I do something, is there a way I can check (besides another query) to see if the connection is still open, just for assurance.
The mysql_close() function returns true if it succeeded. By adding an extra check outside of checking the return value of mysql_close(), you aren't doing anything helpful, and adding another place bugs can crop up in your code.
In any case, non-persistent connections are closed automatically when your script finishes, so it isn't necessary, unless you have some specific reason to kill off the resource ahead of time.
You may want to try mysql_ping()
Here is an excerpt from that page:
bool mysql_ping ([ resource $link_identifier ] )
Checks whether or not the connection to the server is working.
If it has gone down, an automatic reconnection is attempted.
This function can be used by scripts that remain idle for a long while,
to check whether or not the server has closed the connection and
reconnect if necessary.
Note: Since MySQL 5.0.13, automatic reconnection feature is disabled.
As for this excerpt, I do not know whether the automatic reconnection feature is disabled comment refers to mysql or PHP. You will have to experiment with it to find out. If this reconnection issue is indeed true, then #Brad's answer is paranoid-proof since you could run mysql_close immediately after querying the data and fetching it. You can be sure at that point that there is no valid connection since you explicitly closed it. Consequently, you would have to run mysql_connect for your next query.
However, letting non-persistent connections close on there own is not always a good idea because this could potentially stockpile TIME_WAITs in the DB Server's netstat. This would fool webservers into thinking that DB Connections are no longer available because MySQL ran out where the OS would actually be the cause since it would delay releasing Connection Resources. To be better safe that sorry, run mysql_close when done and mysql_connect/mysql_query for the next query.
If you are willing, you could construct a try-catch paradigm or a set of if-then-else stataments to first run mysql_ping on an established connection. If true, use it with mysql_query. Otherwise, run mysql_close/mysql_connect/mysql_query.
$con = mysql_connect("localhost" ,"name", "pass");
/* your code*/
if ($con){
mysql_close();
}
AFAIK if you open mysql connection with mysql_pconnect(), they don't really clossed after mysql_close(), it's just return to connection pool
What happens if MySQL database is not closed? How do we know if it is closed properly?
I do have a page which has 11 tables on a page..so what I did is I open database on top of page before script starts and close where the scripts(PHP) ends...
the ending is mysql_close($db);...is this fair enough or do I need to give only mysql_close();
I can't say for sure if all PHP/Mysql versions on all server platforms behave the same way. For tcp connections to the database - unless you call mysql_close($db), you'll have a dangling tcp connection just sitting there waiting to be used for half a minute after the script ends. Then it'll just go away on its own.
I can't say if this is PHP's garbage collection taking a full 30 seconds to complete, or if the tcp connection is set to expire after 30 seconds on its own once you call connect.
Mysql_close($db) instantly kills the tcp connection though. So yeah, I'd say always call mysql_close($db) immediately after you no longer need a database connection in your script.
There isn't a point in closing a connection at the end of the script because that is done for you when the script terminates. The only time you should really call the close function explicitly is if you're running a daemon or something and don't want to hold onto a connection for the entire run length.
PDO is considered the modern database access library for PHP (you really should be using this instead of the mysql_* functions, but that's another story) and even that doesn't have a close function, just to drive the point home.