Make WordPress Core

Ticket #5932: 5932.7.diff

File 5932.7.diff, 5.9 KB (added by pento, 11 years ago)
  • src/wp-includes/wp-db.php

     
    158158        var $queries;
    159159
    160160        /**
     161         * The number of times to retry reconnecting before dying.
     162         *
     163         * @since 3.9.0
     164         * @access protected
     165         * @see wpdb::check_connection()
     166         * @var int
     167         */
     168        protected $reconnect_retries = 5;
     169
     170        /**
    161171         * WordPress table prefix
    162172         *
    163173         * You can set this to have multiple WordPress installations
     
    11301140         * Connect to and select database
    11311141         *
    11321142         * @since 3.0.0
     1143         *
     1144         * @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.
     1145         *
     1146         * @return bool true on successful connection, false on unsuccessful connection
    11331147         */
    1134         function db_connect() {
     1148        function db_connect( $allow_bail = true ) {
    11351149
    11361150                $this->is_mysql = true;
    11371151
     
    11521166                        $this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
    11531167                }
    11541168
    1155                 if ( !$this->dbh ) {
     1169                if ( ! $this->dbh && $allow_bail ) {
    11561170                        wp_load_translations_early();
    11571171
    11581172                        // Load custom DB error template, if present.
     
    11721186<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>
    11731187" ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' );
    11741188
    1175                         return;
     1189                        return false;
     1190                } else if ( $this->dbh ) {
     1191                        $this->set_charset( $this->dbh );
     1192                        $this->ready = true;
     1193                        $this->select( $this->dbname, $this->dbh );
     1194
     1195                        return true;
    11761196                }
    11771197
    1178                 $this->set_charset( $this->dbh );
     1198                return false;
     1199        }
    11791200
    1180                 $this->ready = true;
     1201        /**
     1202         * Check that the connection to the database is still up. If not, try to reconnect.
     1203         * If this function is unable to reconnect, it will forcibly die.
     1204         *
     1205         * @since 3.9.0
     1206         *
     1207         * @return bool true if the connection is up
     1208         */
     1209        function check_connection() {
     1210                if ( @mysql_ping( $this->dbh ) ) {
     1211                        return true;
     1212                }
    11811213
    1182                 $this->select( $this->dbname, $this->dbh );
     1214                $error_reporting = false;
     1215
     1216                // Disable warnings, as we don't want to see a multitude of "unable to connect" messages
     1217                if ( WP_DEBUG ) {
     1218                        $error_reporting = error_reporting();
     1219                        error_reporting( $error_reporting & ~E_WARNING );
     1220                }
     1221
     1222                for ( $tries = 1; $tries <= $this->reconnect_retries; $tries++ ) {
     1223                        // On the last try, re-enable warnings. We want to see a single instance of the
     1224                        // "unable to connect" message on the bail() screen, if it appears.
     1225                        if ( $this->reconnect_retries === $tries && WP_DEBUG ) {
     1226                                error_reporting( $error_reporting );
     1227                        }
     1228
     1229                        if ( $this->db_connect( false ) ) {
     1230                                if ( $error_reporting ) {
     1231                                        error_reporting( $error_reporting );
     1232                                }
     1233
     1234                                return true;
     1235                        }
     1236
     1237                        sleep( 1 );
     1238                }
     1239
     1240                // We weren't able to reconnect, so we better bail
     1241                $this->bail( sprintf( __( "
     1242<h1>Error reconnecting to the database</h1>
     1243<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>
     1244<ul>
     1245        <li>Are you sure that the database server is running?</li>
     1246        <li>Are you sure that the database server is not under particularly heavy load?</li>
     1247</ul>
     1248<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>
     1249" ), htmlspecialchars( $this->dbhost, ENT_QUOTES ) ), 'db_connect_fail' );
     1250
     1251                // If the bail didn't call wp_die, it's time to die, because the DB isn't coming back.
     1252                dead_db();
    11831253        }
    11841254
    11851255        /**
     
    12141284                // Keep track of the last query for debug..
    12151285                $this->last_query = $query;
    12161286
    1217                 if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES )
    1218                         $this->timer_start();
     1287                $this->_do_query( $query );
    12191288
    1220                 $this->result = @mysql_query( $query, $this->dbh );
    1221                 $this->num_queries++;
     1289                // MySQL server has gone away, try to reconnect
     1290                if ( empty( $this->dbh ) || 2006 == mysql_errno( $this->dbh ) ) {
     1291                        if ( $this->check_connection() ) {
     1292                                $this->_do_query( $query );
     1293                        }
     1294                }
    12221295
    1223                 if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES )
    1224                         $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() );
    1225 
    12261296                // If there is an error then take note of it..
    12271297                if ( $this->last_error = mysql_error( $this->dbh ) ) {
    12281298                        // Clear insert_id on a subsequent failed insert.
     
    12601330        }
    12611331
    12621332        /**
     1333         * Internal function to perform the mysql_query call
     1334         *
     1335         * @since 3.9.0
     1336         *
     1337         * @access private
     1338         * @see wpdb::query()
     1339         *
     1340         * @param string $query The query to run
     1341         */
     1342        private function _do_query( $query ) {
     1343                if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
     1344                        $this->timer_start();
     1345                }
     1346
     1347                $this->result = @mysql_query( $query, $this->dbh );
     1348                $this->num_queries++;
     1349
     1350                if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES ) {
     1351                        $this->queries[] = array( $query, $this->timer_stop(), $this->get_caller() );
     1352                }
     1353        }
     1354
     1355        /**
    12631356         * Insert a row into a table.
    12641357         *
    12651358         * <code>
  • tests/phpunit/tests/db.php

     
    4141        }
    4242
    4343        /**
     44         * Test that WPDB will reconnect when the DB link dies
     45         * @ticket 5932
     46         */
     47        public function test_db_reconnect() {
     48                global $wpdb;
     49
     50                $var = $wpdb->get_var( "SELECT ID FROM $wpdb->users LIMIT 1" );
     51                $this->assertGreaterThan( 0, $var );
     52
     53                mysql_close( $wpdb->dbh );
     54                unset( $wpdb->dbh );
     55
     56                $var = $wpdb->get_var( "SELECT ID FROM $wpdb->users LIMIT 1" );
     57                $this->assertGreaterThan( 0, $var );
     58        }
     59
     60        /**
    4461         * Test that floats formatted as "0,700" get sanitized properly by wpdb
    4562         * @global mixed $wpdb
    4663         *