if ( $sum == 0 ) {
# No loads on any of them
# In previous versions, this triggered an unweighted random selection,
- # but this feature has been removed as of April 2006 to allow for strict
- # separation of query groups.
+ # but this feature has been removed as of April 2006 to allow for strict
+ # separation of query groups.
return false;
}
$max = mt_getrandmax();
*/
function getReaderIndex( $group = false, $wiki = false ) {
global $wgReadOnly, $wgDBClusterTimeout, $wgDBAvgStatusPoll, $wgDBtype;
-
+
# FIXME: For now, only go through all this for mysql databases
if ($wgDBtype != 'mysql') {
return $this->getWriterIndex();
if ( count( $this->mServers ) == 1 ) {
# Skip the load balancing if there's only one server
return 0;
- } elseif ( $this->mReadIndex >= 0 ) {
+ } elseif ( $group === false and $this->mReadIndex >= 0 ) {
+ # Shortcut if generic reader exists already
return $this->mReadIndex;
}
$totalElapsed = 0;
# convert from seconds to microseconds
- $timeout = $wgDBClusterTimeout * 1e6;
+ $timeout = $wgDBClusterTimeout * 1e6;
# Find the relevant load array
if ( $group !== false ) {
$found = false;
$laggedSlaveMode = false;
- # First try quickly looking through the available servers for a server that
+ # First try quickly looking through the available servers for a server that
# meets our criteria
do {
$totalThreadsConnected = 0;
throw new MWException( __METHOD__.": unexpectedly found no overloaded servers" );
}
# Back off for a while
- # Scale the sleep time by the number of connected threads, to produce a
+ # Scale the sleep time by the number of connected threads, to produce a
# roughly constant global poll rate
$avgThreads = $totalThreadsConnected / $overloadedServers;
$totalElapsed += $this->sleep( $wgDBAvgStatusPoll * $avgThreads );
$this->mServers[$i]['slave pos'] = $conn->getSlavePos();
}
}
- if ( $i !== false ) {
+ if ( $this->mReadIndex <=0 && $this->mLoads[$i]>0 && $i !== false ) {
$this->mReadIndex = $i;
}
}
}
# Query groups
- if ( !is_array( $groups ) ) {
+ if ( $i == DB_MASTER ) {
+ $i = $this->getWriterIndex();
+ } elseif ( !is_array( $groups ) ) {
$groupIndex = $this->getReaderIndex( $groups, $wiki );
if ( $groupIndex !== false ) {
$serverName = $this->getServerName( $groupIndex );
# Operation-based index
if ( $i == DB_SLAVE ) {
$i = $this->getReaderIndex( false, $wiki );
- } elseif ( $i == DB_MASTER ) {
- $i = $this->getWriterIndex();
} elseif ( $i == DB_LAST ) {
# Just use $this->mLastIndex, which should already be set
$i = $this->mLastIndex;
}
/**
- * Mark a foreign connection as being available for reuse under a different
- * DB name or prefix. This mechanism is reference-counted, and must be called
+ * Mark a foreign connection as being available for reuse under a different
+ * DB name or prefix. This mechanism is reference-counted, and must be called
* the same number of times as getConnection() to work.
*/
public function reuseConnection( $conn ) {
* Index must be an actual index into the array.
* If the server is already open, returns it.
*
- * On error, returns false, and the connection which caused the
+ * On error, returns false, and the connection which caused the
* error will be available via $this->mErrorConnection.
*
* @param integer $i Server index
*/
function openConnection( $i, $wiki = false ) {
wfProfileIn( __METHOD__ );
-
if ( $wiki !== false ) {
- return $this->openForeignConnection( $i, $wiki );
+ $conn = $this->openForeignConnection( $i, $wiki );
+ wfProfileOut( __METHOD__);
+ return $conn;
}
if ( isset( $this->mConns['local'][$i][0] ) ) {
$conn = $this->mConns['local'][$i][0];
/**
* Open a connection to a foreign DB, or return one if it is already open.
*
- * Increments a reference count on the returned connection which locks the
- * connection to the requested wiki. This reference count can be
+ * Increments a reference count on the returned connection which locks the
+ * connection to the requested wiki. This reference count can be
* decremented by calling reuseConnection().
*
* If a connection is open to the appropriate server already, but with the wrong
* database, it will be switched to the right database and returned, as long as
* it has been freed first with reuseConnection().
*
- * On error, returns false, and the connection which caused the
+ * On error, returns false, and the connection which caused the
* error will be available via $this->mErrorConnection.
*
* @param integer $i Server index
* @return Database
*/
function openForeignConnection( $i, $wiki ) {
+ wfProfileIn(__METHOD__);
list( $dbName, $prefix ) = wfSplitWikiID( $wiki );
-
if ( isset( $this->mConns['foreignUsed'][$i][$wiki] ) ) {
// Reuse an already-used connection
$conn = $this->mConns['foreignUsed'][$i][$wiki];
// Reuse a connection from another wiki
$conn = reset( $this->mConns['foreignFree'][$i] );
$oldWiki = key( $this->mConns['foreignFree'][$i] );
-
+
if ( !$conn->selectDB( $dbName ) ) {
global $wguname;
- $this->mLastError = "Error selecting database $dbName on server " .
+ $this->mLastError = "Error selecting database $dbName on server " .
$conn->getServer() . " from client host {$wguname['nodename']}\n";
$this->mErrorConnection = $conn;
$conn = false;
$refCount = $conn->getLBInfo( 'foreignPoolRefCount' );
$conn->setLBInfo( 'foreignPoolRefCount', $refCount + 1 );
}
+ wfProfileOut(__METHOD__);
return $conn;
}
}
}
}
-
+
/* Issue COMMIT only on master, only if queries were done on connection */
function commitMasterChanges() {
// Always 0, but who knows.. :)
return $this->mLagTimes;
}
}
-
-