* @ingroup Database
*/
class LoadBalancer {
- /** @var array Map of (server index => server config array) */
+ /** @var array[] Map of (server index => server config array) */
private $mServers;
- /** @var array Map of (local/foreignUsed/foreignFree => server index => DatabaseBase array) */
+ /** @var array[] Map of (local/foreignUsed/foreignFree => server index => DatabaseBase array) */
private $mConns;
/** @var array Map of (server index => weight) */
private $mLoads;
- /** @var array Map of (group => server index => weight) */
+ /** @var array[] Map of (group => server index => weight) */
private $mGroupLoads;
/** @var bool Whether to disregard slave lag as a factor in slave selection */
private $mAllowLagged;
* loadMonitor Name of a class used to fetch server lag and load.
* @throws MWException
*/
- function __construct( $params ) {
+ function __construct( array $params ) {
if ( !isset( $params['servers'] ) ) {
throw new MWException( __CLASS__ . ': missing servers parameter' );
}
* @param array $weights
* @return bool|int|string
*/
- function pickRandom( $weights ) {
+ function pickRandom( array $weights ) {
return ArrayUtils::pickRandom( $weights );
}
* @param bool|string $wiki Wiki to get non-lagged for
* @return bool|int|string
*/
- function getRandomNonLagged( $loads, $wiki = false ) {
+ function getRandomNonLagged( array $loads, $wiki = false ) {
# Unset excessively lagged servers
$lags = $this->getLagTimes( $wiki );
foreach ( $lags as $i => $lag ) {
* always return a consistent index during a given invocation
*
* Side effect: opens connections to databases
- * @param bool|string $group
- * @param bool|string $wiki
+ * @param string|bool $group Query group, or false for the generic reader
+ * @param string|bool $wiki Wiki ID, or false for the current wiki
* @throws MWException
* @return bool|int|string
*/
return $this->mReadIndex;
}
- $section = new ProfileSection( __METHOD__ );
+ new ProfileSection( __METHOD__ );
# Find the relevant load array
if ( $group !== false ) {
return $i;
}
- /**
- * Wait for a specified number of microseconds, and return the period waited
- * @param int $t
- * @return int
- */
- function sleep( $t ) {
- wfProfileIn( __METHOD__ );
- wfDebug( __METHOD__ . ": waiting $t us\n" );
- usleep( $t );
- wfProfileOut( __METHOD__ );
-
- return $t;
- }
-
/**
* Set the master wait position
* If a DB_SLAVE connection has been opened already, waits
if ( $result == -1 || is_null( $result ) ) {
# Timed out waiting for slave, use master instead
- wfDebug( __METHOD__ . ": Timed out waiting for slave #$index pos {$this->mWaitForPos}\n" );
+ $server = $this->mServers[$index]['host'];
+ $msg = __METHOD__ . ": Timed out waiting on $server pos {$this->mWaitForPos}";
+ wfDebug( "$msg\n" );
+ wfDebugLog( 'DBPerformance', "$msg:\n" . wfBacktrace( true ) );
$ok = false;
} else {
wfDebug( __METHOD__ . ": Done\n" );
* This is the main entry point for this class.
*
* @param int $i Server index
- * @param array $groups Query groups
- * @param bool|string $wiki Wiki ID
+ * @param array|string|bool $groups Query group(s), or false for the generic reader
+ * @param string|bool $wiki Wiki ID, or false for the current wiki
*
* @throws MWException
* @return DatabaseBase
* @see LoadBalancer::getConnection() for parameter information
*
* @param int $db
- * @param mixed $groups
- * @param bool|string $wiki
+ * @param array|string|bool $groups Query group(s), or false for the generic reader
+ * @param string|bool $wiki Wiki ID, or false for the current wiki
* @return DBConnRef
*/
public function getConnectionRef( $db, $groups = array(), $wiki = false ) {
* @see LoadBalancer::getConnection() for parameter information
*
* @param int $db
- * @param mixed $groups
- * @param bool|string $wiki
+ * @param array|string|bool $groups Query group(s), or false for the generic reader
+ * @param string|bool $wiki Wiki ID, or false for the current wiki
* @return DBConnRef
*/
public function getLazyConnectionRef( $db, $groups = array(), $wiki = false ) {
* error will be available via $this->mErrorConnection.
*
* @param int $i Server index
- * @param bool|string $wiki Wiki ID to open
+ * @param string|bool $wiki Wiki ID, or false for the current wiki
* @return DatabaseBase
*
* @access private
$conn = reset( $this->mConns['foreignFree'][$i] );
$oldWiki = key( $this->mConns['foreignFree'][$i] );
- if ( !$conn->selectDB( $dbName ) ) {
+ // The empty string as a DB name means "don't care".
+ // DatabaseMysqlBase::open() already handle this on connection.
+ if ( $dbName !== '' && !$conn->selectDB( $dbName ) ) {
$this->mLastError = "Error selecting database $dbName on server " .
$conn->getServer() . " from client host " . wfHostname() . "\n";
$this->mErrorConnection = $conn;
*/
private function reportConnectionError() {
$conn = $this->mErrorConnection; // The connection which caused the error
+ $context = array(
+ 'method' => __METHOD__,
+ 'last_error' => $this->mLastError,
+ );
if ( !is_object( $conn ) ) {
// No last connection, probably due to all servers being too busy
- wfLogDBError( "LB failure with no last connection. Connection error: {$this->mLastError}" );
+ wfLogDBError(
+ "LB failure with no last connection. Connection error: {last_error}",
+ $context
+ );
// If all servers were busy, mLastError will contain something sensible
throw new DBConnectionError( null, $this->mLastError );
} else {
- $server = $conn->getProperty( 'mServer' );
- wfLogDBError( "Connection error: {$this->mLastError} ({$server})" );
- $conn->reportConnectionError( "{$this->mLastError} ({$server})" ); // throws DBConnectionError
+ $context['db_server'] = $conn->getProperty( 'mServer' );
+ wfLogDBError(
+ "Connection error: {last_error} ({db_server})",
+ $context
+ );
+ $conn->reportConnectionError( "{$this->mLastError} ({$context['db_server']})" ); // throws DBConnectionError
}
return false; /* not reached */
* @param int $i
* @param array $serverInfo
*/
- function setServerInfo( $i, $serverInfo ) {
+ function setServerInfo( $i, array $serverInfo ) {
$this->mServers[$i] = $serverInfo;
}
* @param callable $callback
* @param array $params
*/
- function forEachOpenConnection( $callback, $params = array() ) {
+ function forEachOpenConnection( $callback, array $params = array() ) {
foreach ( $this->mConns as $conns2 ) {
foreach ( $conns2 as $conns3 ) {
foreach ( $conns3 as $conn ) {
* Results are cached for a short time in memcached/process cache
*
* @param string|bool $wiki
- * @return array Map of (server index => seconds)
+ * @return int[] Map of (server index => seconds)
*/
function getLagTimes( $wiki = false ) {
if ( $this->getServerCount() <= 1 ) {