Skip to content
Snippets Groups Projects
Commit de27d2b6 authored by lechuck's avatar lechuck Committed by lechuck
Browse files

Upgrade hyperdb

parent 3486ccfa
Branches
Tags
No related merge requests found
......@@ -141,6 +141,12 @@ class hyperdb extends wpdb {
*/
var $open_connections = array();
/**
* Lookup array (dbhname => host:port)
* @var array
*/
var $dbh2host = array();
/**
* The last server used and the database name selected
* @var array
......@@ -245,7 +251,7 @@ class hyperdb extends wpdb {
// Remove characters that can legally trail the table name
$q = rtrim($q, ';/-#');
// allow (select...) union [...] style queries. Use the first queries table name.
$q = ltrim($q, "\t (");
$q = ltrim($q, "\t (");
// Quickly match most common queries
if ( preg_match('/^\s*(?:'
......@@ -261,10 +267,11 @@ class hyperdb extends wpdb {
if ( preg_match('/^\s*SELECT.*?\s+FOUND_ROWS\(\)/is', $q) )
return $this->last_table;
// SHOW TABLE STATUS LIKE and SHOW TABLE STATUS WHERE Name =
if ( preg_match('/^\s*'
// SHOW TABLE STATUS and SHOW TABLES
if ( preg_match('/^\s*(?:'
. 'SHOW\s+TABLE\s+STATUS.+(?:LIKE\s+|WHERE\s+Name\s*=\s*)'
. '\W(\w+)\W/is', $q, $maybe) )
. '|SHOW\s+(?:FULL\s+)?TABLES.+(?:LIKE\s+|WHERE\s+Name\s*=\s*)'
. ')\W(\w+)\W/is', $q, $maybe) )
return $maybe[1];
// Big pattern for the rest of the table-related queries in MySQL 5.0
......@@ -313,7 +320,7 @@ class hyperdb extends wpdb {
* of them returns something other than null.
*/
function run_callbacks( $group, $args = null) {
if ( !is_array( $this->hyper_callbacks[ $group ] ) )
if ( !isset( $this->hyper_callbacks[ $group ] ) || !is_array( $this->hyper_callbacks[ $group ] ) )
return null;
if ( !isset($args) ) {
......@@ -336,7 +343,7 @@ class hyperdb extends wpdb {
* @param string query
* @return resource mysql database connection
*/
function &db_connect( $query = '' ) {
function db_connect( $query = '' ) {
$connect_function = $this->persistent ? 'mysql_pconnect' : 'mysql_connect';
if ( empty( $this->hyper_servers ) ) {
if ( is_resource( $this->dbh ) )
......@@ -385,7 +392,7 @@ class hyperdb extends wpdb {
$this->dataset = $dataset;
// Determine whether the query must be sent to the master (a writable server)
if ( $use_master || $this->srtm === true || isset($this->srtm[$this->table]) ) {
if ( !empty( $use_master ) || $this->srtm === true || isset($this->srtm[$this->table]) ) {
$use_master = true;
} elseif ( $is_write = $this->is_write_query($query) ) {
$use_master = true;
......@@ -393,11 +400,14 @@ class hyperdb extends wpdb {
$this->srtm[$this->table] = true;
} elseif ( !isset($use_master) && is_array($this->srtm) && !empty($this->srtm) ) {
// Detect queries that have a join in the srtm array.
$pattern = '/' . implode('|', array_keys($this->srtm)) . '/i';
if ( preg_match($pattern, substr($query, 0, 1000)) )
$use_master = true;
else
$use_master = false;
$use_master = false;
$query_match = substr( $query, 0, 1000 );
foreach ( $this->srtm as $key => $value ) {
if ( false !== stripos( $query_match, $key ) ) {
$use_master = true;
break;
}
}
} else {
$use_master = false;
}
......@@ -411,7 +421,7 @@ class hyperdb extends wpdb {
}
// Try to reuse an existing connection
while ( is_resource($this->dbhs[$dbhname]) ) {
while ( isset( $this->dbhs[$dbhname] ) && is_resource( $this->dbhs[$dbhname] ) ) {
// Find the connection for incrementing counters
foreach ( array_keys($this->db_connections) as $i )
if ( $this->db_connections[$i]['dbhname'] == $dbhname )
......@@ -423,7 +433,11 @@ class hyperdb extends wpdb {
if ( $name != $this->used_servers[$dbhname]['name'] ) {
if ( !mysql_select_db($name, $this->dbhs[$dbhname]) ) {
// this can happen when the user varies and lacks permission on the $name database
++$conn['disconnect (select failed)'];
if ( isset( $conn['disconnect (select failed)'] ) )
++$conn['disconnect (select failed)'];
else
$conn['disconnect (select failed)'] = 1;
$this->disconnect($dbhname);
break;
}
......@@ -445,17 +459,24 @@ class hyperdb extends wpdb {
$this->last_connection = compact('dbhname', 'name');
if ( !mysql_ping($this->dbhs[$dbhname]) ) {
++$conn['disconnect (ping failed)'];
if ( isset( $conn['disconnect (ping failed)'] ) )
++$conn['disconnect (ping failed)'];
else
$conn['disconnect (ping failed)'] = 1;
$this->disconnect($dbhname);
break;
}
++$conn['queries'];
if ( isset( $conn['queries'] ) )
++$conn['queries'];
else
$conn['queries'] = 1;
return $this->dbhs[$dbhname];
}
if ( $this->write && defined( "MASTER_DB_DEAD" ) ) {
if ( $use_master && defined( "MASTER_DB_DEAD" ) ) {
return $this->bail("We're updating the database, please try back in 5 minutes. If you are posting to your blog please hit the refresh button on your browser in a few minutes to post the data again. It will be posted as soon as the database is back online again.");
}
......@@ -500,8 +521,7 @@ class hyperdb extends wpdb {
// $host, $user, $password, $name, $read, $write [, $lag_threshold, $connect_function, $timeout ]
extract($this->hyper_servers[$dataset][$operation][$group][$key], EXTR_OVERWRITE);
list($host, $port) = explode(':', $host);
$port = null;
// Split host:port into $host and $port
if ( strpos($host, ':') )
......@@ -537,13 +557,13 @@ class hyperdb extends wpdb {
&& ( $lagged_status = $this->get_lag_cache() ) === HYPERDB_LAG_BEHIND
) {
// If it is the last lagged slave and it is with the best preference we will ignore its lag
if ( !isset( $unique_lagged_slaves[ "$host:$port" ] )
if ( !isset( $unique_lagged_slaves["$host:$port"] )
&& $unique_servers == count( $unique_lagged_slaves ) + 1
&& $group == $min_group )
{
$this->lag_threshold = null;
} else {
$unique_lagged_slaves["$host.$port"] = $this->lag;
$unique_lagged_slaves["$host:$port"] = $this->lag;
continue;
}
}
......@@ -572,7 +592,7 @@ class hyperdb extends wpdb {
&& $lagged_status !== HYPERDB_LAG_OK
&& ( $lagged_status = $this->get_lag() ) === HYPERDB_LAG_BEHIND
&& !(
!isset( $unique_lagged_slaves[ "$host:$port" ] )
!isset( $unique_lagged_slaves["$host:$port"] )
&& $unique_servers == count( $unique_lagged_slaves ) + 1
&& $group == $min_group
)
......@@ -590,8 +610,7 @@ class hyperdb extends wpdb {
$this->dbh2host[$dbhname] = "$host:$port";
$queries = 1;
$lag = isset( $this->lag ) ? $this->lag : 0;
$this->last_connection = compact('dbhname', 'host', 'port', 'user', 'name', 'tcp', 'elapsed', 'success', 'querie
s', 'lag');
$this->last_connection = compact('dbhname', 'host', 'port', 'user', 'name', 'tcp', 'elapsed', 'success', 'queries', 'lag');
$this->db_connections[] = $this->last_connection;
$this->open_connections[] = $dbhname;
break;
......@@ -601,7 +620,6 @@ s', 'lag');
$success = false;
$this->last_connection = compact('dbhname', 'host', 'port', 'user', 'name', 'tcp', 'elapsed', 'success');
$this->db_connections[] = $this->last_connection;
$msg = date( "Y-m-d H:i:s" ) . " Can't select $dbhname - \n";
$msg .= "'referrer' => '{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}',\n";
$msg .= "'server' => {$server},\n";
......@@ -621,7 +639,7 @@ s', 'lag');
$tries_remaining = count( $servers );
continue;
}
$error_details = array(
'host' => $host,
'port' => $port,
......@@ -638,6 +656,12 @@ s', 'lag');
break;
} while ( true );
if ( !isset( $charset ) )
$charset = null;
if ( !isset( $collate ) )
$collate = null;
$this->set_charset($this->dbhs[$dbhname], $charset, $collate);
$this->dbh = $this->dbhs[$dbhname]; // needed by $wpdb->_real_escape()
......@@ -901,11 +925,39 @@ s', 'lag');
* Check the responsiveness of a tcp/ip daemon
* @return (bool) true when $host:$post responds within $float_timeout seconds, else (bool) false
*/
function check_tcp_responsiveness($host, $port, $float_timeout) {
$socket = @ fsockopen($host, $port, $errno, $errstr, $float_timeout);
if ( $socket === false )
function check_tcp_responsiveness( $host, $port, $float_timeout ) {
if ( function_exists( 'apc_store' ) ) {
$use_apc = true;
$apc_key = "{$host}{$port}";
$apc_ttl = 10;
} else {
$use_apc = false;
}
if ( $use_apc ) {
$cached_value = apc_fetch( $apc_key );
switch ( $cached_value ) {
case 'up':
$this->tcp_responsive = 'true';
return true;
case 'down':
$this->tcp_responsive = 'false';
return false;
}
}
$socket = @ fsockopen( $host, $port, $errno, $errstr, $float_timeout );
if ( $socket === false ) {
if ( $use_apc )
apc_store( $apc_key, 'down', $apc_ttl );
return "[ > $float_timeout ] ($errno) '$errstr'";
fclose($socket);
}
fclose( $socket );
if ( $use_apc )
apc_store( $apc_key, 'up', $apc_ttl );
return true;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment