@@ -1340,6 +1340,8 @@ protected function single_db_connect( $dbhname, $host, $user, $password ) {
13401340
13411341 return false ;
13421342 }
1343+
1344+ $ this ->update_heartbeat ( $ dbhname );
13431345 }
13441346
13451347 /**
@@ -1401,7 +1403,9 @@ public function set_sql_mode( $modes = array(), $dbh_or_table = false ) {
14011403
14021404 $ modes_str = implode ( ', ' , $ modes );
14031405
1404- mysqli_query ( $ dbh , "SET SESSION sql_mode=' {$ modes_str }' " );
1406+ if ( mysqli_query ( $ dbh , "SET SESSION sql_mode=' {$ modes_str }' " ) ) {
1407+ $ this ->update_heartbeat ( $ dbh );
1408+ }
14051409 }
14061410
14071411 /**
@@ -1427,6 +1431,10 @@ public function select( $db, $dbh_or_table = false ) {
14271431
14281432 $ success = mysqli_select_db ( $ dbh , $ db );
14291433
1434+ if ( $ success ) {
1435+ $ this ->update_heartbeat ( $ dbh );
1436+ }
1437+
14301438 return $ success ;
14311439 }
14321440
@@ -1608,6 +1616,7 @@ public function check_connection( $die_on_disconnect = true, $dbh_or_table = fal
16081616 &&
16091617 mysqli_ping ( $ dbh )
16101618 ) {
1619+ $ this ->update_heartbeat ( $ dbh );
16111620 return true ;
16121621 }
16131622
@@ -1803,6 +1812,20 @@ public function query( $query ) {
18031812
18041813 ++$ this ->num_queries ;
18051814
1815+ $ mysql_errno = mysqli_errno ( $ this ->dbh );
1816+ if ( $ mysql_errno && ! empty ( $ this ->check_dbh_heartbeats ) ) {
1817+ $ dbhname = $ this ->lookup_dbhs_name ( $ this ->dbh );
1818+
1819+ if ( ! empty ( $ dbhname ) ) {
1820+ $ this ->dbhname_heartbeats [ $ dbhname ]['last_errno ' ] = $ mysql_errno ;
1821+ }
1822+ }
1823+
1824+ // retry the server and all other servers if the connection went away
1825+ if ( in_array ( $ mysql_errno , array ( 2006 , 4031 ), true ) ) {
1826+ return $ this ->query ( $ query );
1827+ }
1828+
18061829 if ( preg_match ( '/^\s*SELECT\s+([A-Z_]+\s+)*SQL_CALC_FOUND_ROWS\s/i ' , $ query ) ) {
18071830 if ( false === strpos ( $ query , 'NO_SELECT_FOUND_ROWS ' ) ) {
18081831 $ this ->timer_start ();
@@ -1933,17 +1956,7 @@ protected function _do_query( $query, $dbh_or_table = false ) { // phpcs:ignore
19331956 }
19341957 }
19351958
1936- // Maybe log last used to heartbeats
1937- if ( ! empty ( $ this ->check_dbh_heartbeats ) ) {
1938-
1939- // Lookup name
1940- $ name = $ this ->lookup_dbhs_name ( $ dbh );
1941-
1942- // Set last used for this dbh
1943- if ( ! empty ( $ name ) ) {
1944- $ this ->dbhname_heartbeats [ $ name ]['last_used ' ] = microtime ( true );
1945- }
1946- }
1959+ $ this ->update_heartbeat ( $ dbh );
19471960
19481961 return $ result ;
19491962 }
@@ -2150,6 +2163,8 @@ public function db_server_info( $dbh_or_table = false ) {
21502163
21512164 $ server_info = mysqli_get_server_info ( $ dbh );
21522165
2166+ $ this ->update_heartbeat ( $ dbh );
2167+
21532168 return $ server_info ;
21542169 }
21552170
@@ -2369,13 +2384,19 @@ public function run_query_log_callbacks( $query = '', $retval = null ) {
23692384 * @return bool True if we should try to ping the MySQL host, false otherwise.
23702385 */
23712386 public function should_mysql_ping ( $ dbhname = '' ) {
2387+ if ( empty ( $ dbhname ) ) {
2388+ return false ;
2389+ }
23722390
2373- // Return false if empty handle or checks are disabled
23742391 if (
2375- empty ( $ dbhname )
2376- ||
23772392 empty ( $ this ->check_dbh_heartbeats )
2393+ &&
2394+ in_array ( mysqli_errno ( $ this ->dbhs [ $ dbhname ] ), array ( 2006 , 4031 ), true )
23782395 ) {
2396+ return true ;
2397+ }
2398+
2399+ if ( empty ( $ this ->check_dbh_heartbeats ) ) {
23792400 return false ;
23802401 }
23812402
@@ -2793,6 +2814,36 @@ protected function tcp_cache_delete( $key = '' ) {
27932814 return true ;
27942815 }
27952816
2817+ /**
2818+ * Update the heartbeat
2819+ *
2820+ * @param string|object $dbhname_or_dbh To update the heartbeat for
2821+ *
2822+ * @return void
2823+ */
2824+ protected function update_heartbeat ( $ dbhname_or_dbh ) {
2825+ if ( ! $ this ->check_dbh_heartbeats ) {
2826+ return ;
2827+ }
2828+
2829+ if ( is_string ( $ dbhname_or_dbh ) ) {
2830+ $ dbhname = $ dbhname_or_dbh ;
2831+ } else {
2832+ $ dbhname = $ this ->lookup_dbhs_name ( $ dbhname_or_dbh );
2833+ }
2834+
2835+ // Set last used for this dbh
2836+ if ( empty ( $ dbhname ) ) {
2837+ return ;
2838+ }
2839+
2840+ if ( ! isset ( $ this ->dbhname_heartbeats [ $ dbhname ] ) ) {
2841+ $ this ->dbhname_heartbeats [ $ dbhname ] = array ();
2842+ }
2843+
2844+ $ this ->dbhname_heartbeats [ $ dbhname ]['last_used ' ] = microtime ( true );
2845+ }
2846+
27962847 /**
27972848 * Find a dbh name value for a given $dbh object.
27982849 *
0 commit comments