X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fdb%2FLoadBalancer.php;h=db4ed602b6a8db421d67d581f894c9eef6a4df71;hb=fea832ae52ad17bd68637559134942f57a35c925;hp=b3f92101205eff21b36ee154f8e74184acdcacb4;hpb=e3e8659cfc2bc1ffe775a52671acc0d10dbb8527;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/db/LoadBalancer.php b/includes/db/LoadBalancer.php index b3f9210120..db4ed602b6 100644 --- a/includes/db/LoadBalancer.php +++ b/includes/db/LoadBalancer.php @@ -43,7 +43,7 @@ class LoadBalancer { private $mLoadMonitorClass, $mLoadMonitor; /** - * @param array $params with keys: + * @param array $params Array with keys: * servers Required. Array of server info structures. * loadMonitor Name of a class used to fetch server lag and load. * @throws MWException @@ -331,17 +331,23 @@ class LoadBalancer { /** * Set the master wait position and wait for ALL slaves to catch up to it * @param DBMasterPos $pos + * @param int $timeout Max seconds to wait; default is mWaitTimeout + * @return bool Success (able to connect and no timeouts reached) */ - public function waitForAll( $pos ) { + public function waitForAll( $pos, $timeout = null ) { wfProfileIn( __METHOD__ ); $this->mWaitForPos = $pos; $serverCount = count( $this->mServers ); + + $ok = true; for ( $i = 1; $i < $serverCount; $i++ ) { if ( $this->mLoads[$i] > 0 ) { - $this->doWait( $i, true ); + $ok = $this->doWait( $i, true, $timeout ) && $ok; } } wfProfileOut( __METHOD__ ); + + return $ok; } /** @@ -363,11 +369,12 @@ class LoadBalancer { /** * Wait for a given slave to catch up to the master pos stored in $this - * @param int $index - * @param bool $open + * @param int $index Server index + * @param bool $open Check the server even if a new connection has to be made + * @param int $timeout Max seconds to wait; default is mWaitTimeout * @return bool */ - protected function doWait( $index, $open = false ) { + protected function doWait( $index, $open = false, $timeout = null ) { # Find a connection to wait on $conn = $this->getAnyOpenConnection( $index ); if ( !$conn ) { @@ -386,7 +393,8 @@ class LoadBalancer { } wfDebug( __METHOD__ . ": Waiting for slave #$index to catch up...\n" ); - $result = $conn->masterPosWait( $this->mWaitForPos, $this->mWaitTimeout ); + $timeout = $timeout ?: $this->mWaitTimeout; + $result = $conn->masterPosWait( $this->mWaitForPos, $timeout ); if ( $result == -1 || is_null( $result ) ) { # Timed out waiting for slave, use master instead @@ -948,6 +956,14 @@ class LoadBalancer { } } + /** + * @return bool Whether a master connection is already open + * @since 1.24 + */ + function hasMasterConnection() { + return $this->isOpen( $this->getWriterIndex() ); + } + /** * Determine if there are any pending changes that need to be rolled back * or committed. @@ -1048,8 +1064,22 @@ class LoadBalancer { $maxLag = -1; $host = ''; $maxIndex = 0; - if ( $this->getServerCount() > 1 ) { // no replication = no lag + + if ( $this->getServerCount() <= 1 ) { // no replication = no lag + return array( $host, $maxLag, $maxIndex ); + } + + // Try to get the max lag info from the server cache + $key = 'loadbalancer:maxlag:cluster:' . $this->mServers[0]['host']; + $cache = ObjectCache::newAccelerator( array(), 'hash' ); + $maxLagInfo = $cache->get( $key ); // (host, lag, index) + + // Fallback to connecting to each slave and getting the lag + if ( !$maxLagInfo ) { foreach ( $this->mServers as $i => $conn ) { + if ( $i == $this->getWriterIndex() ) { + continue; // nothing to check + } $conn = false; if ( $wiki === false ) { $conn = $this->getAnyOpenConnection( $i ); @@ -1067,9 +1097,11 @@ class LoadBalancer { $maxIndex = $i; } } + $maxLagInfo = array( $host, $maxLag, $maxIndex ); + $cache->set( $key, $maxLagInfo, 5 ); } - return array( $host, $maxLag, $maxIndex ); + return $maxLagInfo; } /**