X-Git-Url: https://git.heureux-cyclage.org/?p=lhc%2Fweb%2Fwiklou.git;a=blobdiff_plain;f=includes%2Fdb%2FLoadBalancer.php;h=2ea2487501a88447cbb0adb599e0c8891e9b1978;hp=d9584e147bae96b0eb3081ef5b1ab2e9d8c7aa25;hb=35d9ad550f2f443455b3b76495d9cebfafdfaf37;hpb=5efccbed2a8db2a2b210d6116bd608da01342030 diff --git a/includes/db/LoadBalancer.php b/includes/db/LoadBalancer.php index d9584e147b..2ea2487501 100644 --- a/includes/db/LoadBalancer.php +++ b/includes/db/LoadBalancer.php @@ -214,7 +214,7 @@ class LoadBalancer { * @return bool|int|string */ public function getReaderIndex( $group = false, $wiki = false ) { - global $wgReadOnly, $wgDBtype; + global $wgDBtype; # @todo FIXME: For now, only go through all this for mysql databases if ( $wgDBtype != 'mysql' ) { @@ -258,7 +258,7 @@ class LoadBalancer { # meets our criteria $currentLoads = $nonErrorLoads; while ( count( $currentLoads ) ) { - if ( $wgReadOnly || $this->mAllowLagged || $laggedSlaveMode ) { + if ( $this->mAllowLagged || $laggedSlaveMode ) { $i = ArrayUtils::pickRandom( $currentLoads ); } else { $i = false; @@ -277,8 +277,6 @@ class LoadBalancer { if ( $i === false && count( $currentLoads ) != 0 ) { # All slaves lagged. Switch to read-only mode wfDebugLog( 'replication', "All slaves lagged. Switch to read-only mode" ); - $wgReadOnly = 'The database has been automatically locked ' . - 'while the slave database servers catch up to the master'; $i = ArrayUtils::pickRandom( $currentLoads ); $laggedSlaveMode = true; } @@ -330,6 +328,10 @@ class LoadBalancer { } if ( $this->mReadIndex <= 0 && $this->mLoads[$i] > 0 && $group === false ) { $this->mReadIndex = $i; + # Record if the generic reader index is in "lagged slave" mode + if ( $laggedSlaveMode ) { + $this->mLaggedSlaveMode = true; + } } $serverName = $this->getServerName( $i ); wfDebug( __METHOD__ . ": using server $serverName for group '$group'\n" ); @@ -356,6 +358,37 @@ class LoadBalancer { } } + /** + * Set the master wait position and wait for a "generic" slave to catch up to it + * + * This can be used a faster proxy for waitForAll() + * + * @param DBMasterPos $pos + * @param int $timeout Max seconds to wait; default is mWaitTimeout + * @return bool Success (able to connect and no timeouts reached) + * @since 1.26 + */ + public function waitForOne( $pos, $timeout = null ) { + $this->mWaitForPos = $pos; + + $i = $this->mReadIndex; + if ( $i <= 0 ) { + // Pick a generic slave if there isn't one yet + $readLoads = $this->mLoads; + unset( $readLoads[$this->getWriterIndex()] ); // slaves only + $readLoads = array_filter( $readLoads ); // with non-zero load + $i = ArrayUtils::pickRandom( $readLoads ); + } + + if ( $i > 0 ) { + $ok = $this->doWait( $i, true, $timeout ); + } else { + $ok = true; // no applicable loads + } + + return $ok; + } + /** * Set the master wait position and wait for ALL slaves to catch up to it * @param DBMasterPos $pos @@ -812,8 +845,9 @@ class LoadBalancer { /** * @return int + * @since 1.26 */ - private function getWriterIndex() { + public function getWriterIndex() { return 0; } @@ -1096,9 +1130,12 @@ class LoadBalancer { } /** - * @return bool + * @return bool Whether the generic connection for reads is highly "lagged" */ public function getLaggedSlaveMode() { + # Get a generic reader connection + $this->getConnection( DB_SLAVE ); + return $this->mLaggedSlaveMode; } @@ -1236,49 +1273,3 @@ class LoadBalancer { $this->mProcCache->clear( 'slave_lag' ); } } - -/** - * Helper class to handle automatically marking connections as reusable (via RAII pattern) - * as well handling deferring the actual network connection until the handle is used - * - * @ingroup Database - * @since 1.22 - */ -class DBConnRef implements IDatabase { - /** @var LoadBalancer */ - private $lb; - - /** @var DatabaseBase|null */ - private $conn; - - /** @var array|null */ - private $params; - - /** - * @param LoadBalancer $lb - * @param DatabaseBase|array $conn Connection or (server index, group, wiki ID) array - */ - public function __construct( LoadBalancer $lb, $conn ) { - $this->lb = $lb; - if ( $conn instanceof DatabaseBase ) { - $this->conn = $conn; - } else { - $this->params = $conn; - } - } - - public function __call( $name, $arguments ) { - if ( $this->conn === null ) { - list( $db, $groups, $wiki ) = $this->params; - $this->conn = $this->lb->getConnection( $db, $groups, $wiki ); - } - - return call_user_func_array( array( $this->conn, $name ), $arguments ); - } - - public function __destruct() { - if ( $this->conn !== null ) { - $this->lb->reuseConnection( $this->conn ); - } - } -}