When the MySQL server has "gone away," attempt to reconnect and retry the query.
props pento. see #5932. git-svn-id: https://develop.svn.wordpress.org/trunk@27075 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
e993ef0249
commit
194d6a94b7
|
@ -157,6 +157,16 @@ class wpdb {
|
||||||
*/
|
*/
|
||||||
var $queries;
|
var $queries;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of times to retry reconnecting before dying.
|
||||||
|
*
|
||||||
|
* @since 3.9.0
|
||||||
|
* @access protected
|
||||||
|
* @see wpdb::check_connection()
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $reconnect_retries = 5;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WordPress table prefix
|
* WordPress table prefix
|
||||||
*
|
*
|
||||||
|
@ -1192,11 +1202,17 @@ class wpdb {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect to and select database
|
* Connect to and select database.
|
||||||
*
|
*
|
||||||
* @since 3.0.0
|
* @since 3.0.0
|
||||||
|
*
|
||||||
|
* @param bool $allow_bail Optional. Allows the function to bail, default true. If this is set
|
||||||
|
* to false, you will need to handle the lack of database connection
|
||||||
|
* manually. Available since 3.9.0.
|
||||||
|
*
|
||||||
|
* @return bool True with a successful connection, false on failure.
|
||||||
*/
|
*/
|
||||||
function db_connect() {
|
function db_connect( $allow_bail = true ) {
|
||||||
|
|
||||||
$this->is_mysql = true;
|
$this->is_mysql = true;
|
||||||
|
|
||||||
|
@ -1217,7 +1233,7 @@ class wpdb {
|
||||||
$this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
|
$this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !$this->dbh ) {
|
if ( ! $this->dbh && $allow_bail ) {
|
||||||
wp_load_translations_early();
|
wp_load_translations_early();
|
||||||
|
|
||||||
// Load custom DB error template, if present.
|
// Load custom DB error template, if present.
|
||||||
|
@ -1237,16 +1253,72 @@ class wpdb {
|
||||||
<p>If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href='http://wordpress.org/support/'>WordPress Support Forums</a>.</p>
|
<p>If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href='http://wordpress.org/support/'>WordPress Support Forums</a>.</p>
|
||||||
" ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' );
|
" ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' );
|
||||||
|
|
||||||
return;
|
return false;
|
||||||
|
} else if ( $this->dbh ) {
|
||||||
|
$this->set_charset( $this->dbh );
|
||||||
|
$this->set_sql_mode();
|
||||||
|
$this->ready = true;
|
||||||
|
$this->select( $this->dbname, $this->dbh );
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->set_charset( $this->dbh );
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$this->set_sql_mode();
|
/**
|
||||||
|
* Check that the connection to the database is still up. If not, try to reconnect.
|
||||||
|
*
|
||||||
|
* If this function is unable to reconnect, it will forcibly die.
|
||||||
|
*
|
||||||
|
* @since 3.9.0
|
||||||
|
*
|
||||||
|
* @return bool True if the connection is up.
|
||||||
|
*/
|
||||||
|
function check_connection() {
|
||||||
|
if ( @mysql_ping( $this->dbh ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
$this->ready = true;
|
$error_reporting = false;
|
||||||
|
|
||||||
$this->select( $this->dbname, $this->dbh );
|
// Disable warnings, as we don't want to see a multitude of "unable to connect" messages
|
||||||
|
if ( WP_DEBUG ) {
|
||||||
|
$error_reporting = error_reporting();
|
||||||
|
error_reporting( $error_reporting & ~E_WARNING );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( $tries = 1; $tries <= $this->reconnect_retries; $tries++ ) {
|
||||||
|
// On the last try, re-enable warnings. We want to see a single instance of the
|
||||||
|
// "unable to connect" message on the bail() screen, if it appears.
|
||||||
|
if ( $this->reconnect_retries === $tries && WP_DEBUG ) {
|
||||||
|
error_reporting( $error_reporting );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $this->db_connect( false ) ) {
|
||||||
|
if ( $error_reporting ) {
|
||||||
|
error_reporting( $error_reporting );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// We weren't able to reconnect, so we better bail.
|
||||||
|
$this->bail( sprintf( ( "
|
||||||
|
<h1>Error reconnecting to the database</h1>
|
||||||
|
<p>This means that we lost contact with the database server at <code>%s</code>. This could mean your host's database server is down.</p>
|
||||||
|
<ul>
|
||||||
|
<li>Are you sure that the database server is running?</li>
|
||||||
|
<li>Are you sure that the database server is not under particularly heavy load?</li>
|
||||||
|
</ul>
|
||||||
|
<p>If you're unsure what these terms mean you should probably contact your host. If you still need help you can always visit the <a href='http://wordpress.org/support/'>WordPress Support Forums</a>.</p>
|
||||||
|
" ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' );
|
||||||
|
|
||||||
|
// Call dead_db() if bail didn't die, because this database is no more. It has ceased to be (at least temporarily).
|
||||||
|
dead_db();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1262,6 +1334,7 @@ class wpdb {
|
||||||
function query( $query ) {
|
function query( $query ) {
|
||||||
if ( ! $this->ready )
|
if ( ! $this->ready )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter the database query.
|
* Filter the database query.
|
||||||
*
|
*
|
||||||
|
@ -1281,14 +1354,14 @@ class wpdb {
|
||||||
// Keep track of the last query for debug..
|
// Keep track of the last query for debug..
|
||||||
$this->last_query = $query;
|
$this->last_query = $query;
|
||||||
|
|
||||||
if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES )
|
$this->_do_query( $query );
|
||||||
$this->timer_start();
|
|
||||||
|
|
||||||
$this->result = @mysql_query( $query, $this->dbh );
|
// MySQL server has gone away, try to reconnect
|
||||||
$this->num_queries++;
|
if ( empty( $this->dbh ) || 2006 == mysql_errno( $this->dbh ) ) {
|
||||||
|
if ( $this->check_connection() ) {
|
||||||
if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES )
|
$this->_do_query( $query );
|
||||||
$this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() );
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If there is an error then take note of it..
|
// If there is an error then take note of it..
|
||||||
if ( $this->last_error = mysql_error( $this->dbh ) ) {
|
if ( $this->last_error = mysql_error( $this->dbh ) ) {
|
||||||
|
@ -1326,6 +1399,29 @@ class wpdb {
|
||||||
return $return_val;
|
return $return_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal function to perform the mysql_query call
|
||||||
|
*
|
||||||
|
* @since 3.9.0
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @see wpdb::query()
|
||||||
|
*
|
||||||
|
* @param string $query The query to run
|
||||||
|
*/
|
||||||
|
private function _do_query( $query ) {
|
||||||
|
if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
|
||||||
|
$this->timer_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->result = @mysql_query( $query, $this->dbh );
|
||||||
|
$this->num_queries++;
|
||||||
|
|
||||||
|
if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
|
||||||
|
$this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a row into a table.
|
* Insert a row into a table.
|
||||||
*
|
*
|
||||||
|
|
|
@ -40,6 +40,23 @@ class Tests_DB extends WP_UnitTestCase {
|
||||||
return $sql;
|
return $sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that WPDB will reconnect when the DB link dies
|
||||||
|
* @ticket 5932
|
||||||
|
*/
|
||||||
|
public function test_db_reconnect() {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
$var = $wpdb->get_var( "SELECT ID FROM $wpdb->users LIMIT 1" );
|
||||||
|
$this->assertGreaterThan( 0, $var );
|
||||||
|
|
||||||
|
mysql_close( $wpdb->dbh );
|
||||||
|
unset( $wpdb->dbh );
|
||||||
|
|
||||||
|
$var = $wpdb->get_var( "SELECT ID FROM $wpdb->users LIMIT 1" );
|
||||||
|
$this->assertGreaterThan( 0, $var );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that floats formatted as "0,700" get sanitized properly by wpdb
|
* Test that floats formatted as "0,700" get sanitized properly by wpdb
|
||||||
* @global mixed $wpdb
|
* @global mixed $wpdb
|
||||||
|
|
Loading…
Reference in New Issue