Index: bootstrap.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v retrieving revision 1.167 diff -u -r1.167 bootstrap.inc --- bootstrap.inc 25 May 2007 21:01:29 -0000 1.167 +++ bootstrap.inc 27 May 2007 22:45:36 -0000 @@ -263,7 +263,7 @@ global $base_url, $base_path, $base_root; // Export the following settings.php variables to the global namespace - global $db_url, $db_prefix, $cookie_domain, $conf, $installed_profile; + global $db_url, $db_slave_url, $db_prefix, $cookie_domain, $conf, $installed_profile; $conf = array(); if (file_exists('./'. conf_path() .'/settings.php')) { Index: database.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database.inc,v retrieving revision 1.69 diff -u -r1.69 database.inc --- database.inc 25 May 2007 12:46:43 -0000 1.69 +++ database.inc 27 May 2007 22:45:36 -0000 @@ -115,8 +115,8 @@ * @return the name of the previously active database or FALSE if non was found. */ function db_set_active($name = 'default') { - global $db_url, $db_type, $active_db; - static $db_conns; + global $db_url, $db_slave_url, $db_type, $active_db, $active_slave_db; + static $db_conns, $db_slave_conns; if (empty($db_url)) { include_once 'includes/install.inc'; @@ -124,12 +124,31 @@ } if (!isset($db_conns[$name])) { - // Initiate a new connection, using the named DB URL specified. + // If the $name doesn't have a corresponding URL, use the default. + if (!isset($db_url[$name])) { + $name = 'default'; + } + + // Initiate a new connection, using the specifed DB URL. if (is_array($db_url)) { - $connect_url = array_key_exists($name, $db_url) ? $db_url[$name] : $db_url['default']; + $connect_url = $db_url[$name]; + if (is_array($db_slave_url[$name])) { + $slave_index = mt_rand(0, count($db_slave_url[$name])); + $slave_connect_url = $db_slave_url[$name][$slave_index]; + } + else { + $slave_connect_url = $db_slave_url[$name]; + } } else { $connect_url = $db_url; + if (is_array($db_slave_url)) { + $slave_index = mt_rand(0, count($db_slave_url) - 1); + $slave_connect_url = $db_slave_url[$slave_index]; + } + else { + $slave_connect_url = $db_slave_url; + } } $db_type = substr($connect_url, 0, strpos($connect_url, '://')); @@ -147,11 +166,20 @@ } $db_conns[$name] = db_connect($connect_url); + if (!empty($slave_connect_url)) { + $db_slave_conns[$name] = db_connect($slave_connect_url); + } } $previous_db = $active_db; - // Set the active connection. + // Set the active connections. $active_db = $db_conns[$name]; + if (isset($db_slave_conns[$name])) { + $active_slave_db = $db_slave_conns[$name]; + } + else { + unset($active_slave_db); + } return array_search($previous_db, $db_conns); } Index: database.mysqli.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database.mysqli.inc,v retrieving revision 1.37 diff -u -r1.37 database.mysqli.inc --- database.mysqli.inc 25 May 2007 21:01:30 -0000 1.37 +++ database.mysqli.inc 27 May 2007 22:45:36 -0000 @@ -125,14 +125,19 @@ * Helper function for db_query(). */ function _db_query($query, $debug = 0) { - global $active_db, $queries; + global $active_db, $active_slave_db, $queries; if (variable_get('dev_query', 0)) { list($usec, $sec) = explode(' ', microtime()); $timer = (float)$usec + (float)$sec; } - $result = mysqli_query($active_db, $query); + if (isset($active_slave_db) && strtoupper(substr(ltrim($query), 0, 6)) == 'SELECT') { + $result = mysqli_query($active_slave_db, $query); + } + else { + $result = mysqli_query($active_db, $query); + } if (variable_get('dev_query', 0)) { $bt = debug_backtrace(); Index: database.mysql.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database.mysql.inc,v retrieving revision 1.73 diff -u -r1.73 database.mysql.inc --- database.mysql.inc 25 May 2007 21:01:30 -0000 1.73 +++ database.mysql.inc 27 May 2007 22:45:36 -0000 @@ -134,14 +134,19 @@ * Helper function for db_query(). */ function _db_query($query, $debug = 0) { - global $active_db, $queries; + global $active_db, $active_slave_db, $queries; if (variable_get('dev_query', 0)) { list($usec, $sec) = explode(' ', microtime()); $timer = (float)$usec + (float)$sec; } - $result = mysql_query($query, $active_db); + if (isset($active_slave_db) && strtoupper(substr(ltrim($query), 0, 6)) == 'SELECT') { + $result = mysql_query($active_slave_db, $query); + } + else { + $result = mysql_query($active_db, $query); + } if (variable_get('dev_query', 0)) { $bt = debug_backtrace(); Index: database.pgsql.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/database.pgsql.inc,v retrieving revision 1.46 diff -u -r1.46 database.pgsql.inc --- database.pgsql.inc 25 May 2007 12:46:43 -0000 1.46 +++ database.pgsql.inc 27 May 2007 22:45:36 -0000 @@ -115,14 +115,19 @@ * Helper function for db_query(). */ function _db_query($query, $debug = 0) { - global $active_db, $last_result, $queries; + global $active_db, $active_slave_db, $last_result, $queries; if (variable_get('dev_query', 0)) { list($usec, $sec) = explode(' ', microtime()); $timer = (float)$usec + (float)$sec; } - $last_result = pg_query($active_db, $query); + if (isset($active_slave_db) && strtoupper(substr(ltrim($query), 0, 6)) == 'SELECT') { + $result = pg_query($active_slave_db, $query); + } + else { + $result = pg_query($active_db, $query); + } if (variable_get('dev_query', 0)) { $bt = debug_backtrace(); Index: session.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/session.inc,v retrieving revision 1.40 diff -u -r1.40 session.inc --- session.inc 25 May 2007 15:04:41 -0000 1.40 +++ session.inc 27 May 2007 22:45:36 -0000 @@ -29,7 +29,7 @@ } // Otherwise, if the session is still active, we have a record of the client's session in the database. - $user = db_fetch_object(db_query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = '%s'", $key)); + $user = db_fetch_object(db_query("/* Master */ SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = '%s'", $key)); // We found the client's session record and they are an authenticated user if ($user && $user->uid > 0) { @@ -61,9 +61,9 @@ return TRUE; } - $result = db_query("SELECT sid FROM {sessions} WHERE sid = '%s'", $key); + db_query("UPDATE {sessions} SET uid = %d, cache = %d, hostname = '%s', session = '%s', timestamp = %d WHERE sid = '%s'", $user->uid, isset($user->cache) ? $user->cache : '', ip_address(), $value, time(), $key); - if (!db_num_rows($result)) { + if (!db_affected_rows()) { // Only save session data when when the browser sends a cookie. This keeps // crawlers out of session table. This reduces memory and server load, // and gives more useful statistics. We can't eliminate anonymous session @@ -73,8 +73,6 @@ } } else { - db_query("UPDATE {sessions} SET uid = %d, cache = %d, hostname = '%s', session = '%s', timestamp = %d WHERE sid = '%s'", $user->uid, isset($user->cache) ? $user->cache : '', ip_address(), $value, time(), $key); - // TODO: this can be an expensive query. Perhaps only execute it every x minutes. Requires investigation into cache expiration. if ($user->uid) { db_query("UPDATE {users} SET access = %d WHERE uid = %d", time(), $user->uid);