X-Git-Url: https://git.cyclocoop.org/%28%28?a=blobdiff_plain;f=includes%2Flibs%2Frdbms%2Floadbalancer%2FLoadBalancer.php;h=6878712d55f5a275018729c77231e23cbad8cb54;hb=64df456b39647723f1aac44e4ba7db69e8404d0d;hp=3442b7319c38685c7ce2bc99b56e626228438df2;hpb=74d0c079bfdf461a960a8a200cb4acfa4255d19d;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/libs/rdbms/loadbalancer/LoadBalancer.php b/includes/libs/rdbms/loadbalancer/LoadBalancer.php index 3442b7319c..6878712d55 100644 --- a/includes/libs/rdbms/loadbalancer/LoadBalancer.php +++ b/includes/libs/rdbms/loadbalancer/LoadBalancer.php @@ -20,13 +20,29 @@ * @file * @ingroup Database */ +namespace Wikimedia\Rdbms; + use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; use Wikimedia\ScopedCallback; -use Wikimedia\Rdbms\TransactionProfiler; -use Wikimedia\Rdbms\ILoadMonitor; -use Wikimedia\Rdbms\DatabaseDomain; -use Wikimedia\Rdbms\ILoadBalancer; +use IDatabase; +use Database; +use DBConnRef; +use MaintainableDBConnRef; +use BagOStuff; +use EmptyBagOStuff; +use WANObjectCache; +use ArrayUtils; +use DBError; +use DBAccessError; +use DBExpectedError; +use DBUnexpectedError; +use DBTransactionError; +use DBTransactionSizeError; +use DBConnectionError; +use InvalidArgumentException; +use RuntimeException; +use Exception; /** * Database connection, tracking, load balancing, and transaction manager for a cluster @@ -36,7 +52,7 @@ use Wikimedia\Rdbms\ILoadBalancer; class LoadBalancer implements ILoadBalancer { /** @var array[] Map of (server index => server config array) */ private $mServers; - /** @var IDatabase[][][] Map of local/foreignUsed/foreignFree => server index => IDatabase array */ + /** @var \Database[][][] Map of local/foreignUsed/foreignFree => server index => IDatabase array */ private $mConns; /** @var float[] Map of (server index => weight) */ private $mLoads; @@ -72,8 +88,8 @@ class LoadBalancer implements ILoadBalancer { /** @var LoggerInterface */ protected $perfLogger; - /** @var bool|IDatabase Database connection that caused a problem */ - private $mErrorConnection; + /** @var \Database Database connection that caused a problem */ + private $errorConnection; /** @var integer The generic (not query grouped) replica DB index (of $mServers) */ private $mReadIndex; /** @var bool|DBMasterPos False if not set */ @@ -145,7 +161,6 @@ class LoadBalancer implements ILoadBalancer { ]; $this->mLoads = []; $this->mWaitForPos = false; - $this->mErrorConnection = false; $this->mAllowLagged = false; if ( isset( $params['readOnlyReason'] ) && is_string( $params['readOnlyReason'] ) ) { @@ -217,9 +232,9 @@ class LoadBalancer implements ILoadBalancer { private function getLoadMonitor() { if ( !isset( $this->loadMonitor ) ) { $compat = [ - 'LoadMonitor' => Wikimedia\Rdbms\LoadMonitor::class, - 'LoadMonitorNull' => Wikimedia\Rdbms\LoadMonitorNull::class, - 'LoadMonitorMySQL' => Wikimedia\Rdbms\LoadMonitorMySQL::class, + 'LoadMonitor' => LoadMonitor::class, + 'LoadMonitorNull' => LoadMonitorNull::class, + 'LoadMonitorMySQL' => LoadMonitorMySQL::class, ]; $class = $this->loadMonitorConfig['class']; @@ -487,10 +502,13 @@ class LoadBalancer implements ILoadBalancer { // Check if we already know that the DB has reached this point $server = $this->getServerName( $index ); - $key = $this->srvCache->makeGlobalKey( __CLASS__, 'last-known-pos', $server ); + $key = $this->srvCache->makeGlobalKey( __CLASS__, 'last-known-pos', $server, 'v1' ); /** @var DBMasterPos $knownReachedPos */ $knownReachedPos = $this->srvCache->get( $key ); - if ( $knownReachedPos && $knownReachedPos->hasReached( $this->mWaitForPos ) ) { + if ( + $knownReachedPos instanceof DBMasterPos && + $knownReachedPos->hasReached( $this->mWaitForPos ) + ) { $this->replLogger->debug( __METHOD__ . ": replica DB $server known to be caught up (pos >= $knownReachedPos)." ); return true; @@ -718,17 +736,17 @@ class LoadBalancer implements ILoadBalancer { $this->mConns['local'][$i][0] = $conn; } else { $this->connLogger->warning( "Failed to connect to database $i at '$serverName'." ); - $this->mErrorConnection = $conn; + $this->errorConnection = $conn; $conn = false; } } - if ( $conn && !$conn->isOpen() ) { + if ( $conn instanceof IDatabase && !$conn->isOpen() ) { // Connection was made but later unrecoverably lost for some reason. // Do not return a handle that will just throw exceptions on use, // but let the calling code (e.g. getReaderIndex) try another server. // See DatabaseMyslBase::ping() for how this can happen. - $this->mErrorConnection = $conn; + $this->errorConnection = $conn; $conn = false; } @@ -747,7 +765,7 @@ class LoadBalancer implements ILoadBalancer { * it has been freed first with reuseConnection(). * * On error, returns false, and the connection which caused the - * error will be available via $this->mErrorConnection. + * error will be available via $this->errorConnection. * * @note If disable() was called on this LoadBalancer, this method will throw a DBAccessError. * @@ -779,7 +797,7 @@ class LoadBalancer implements ILoadBalancer { if ( strlen( $dbName ) && !$conn->selectDB( $dbName ) ) { $this->mLastError = "Error selecting database '$dbName' on server " . $conn->getServer() . " from client host {$this->host}"; - $this->mErrorConnection = $conn; + $this->errorConnection = $conn; $conn = false; } else { $conn->tablePrefix( $prefix ); @@ -800,7 +818,7 @@ class LoadBalancer implements ILoadBalancer { $conn = $this->reallyOpenConnection( $server, $dbName ); if ( !$conn->isOpen() ) { $this->connLogger->warning( __METHOD__ . ": connection error for $i/$domain" ); - $this->mErrorConnection = $conn; + $this->errorConnection = $conn; $conn = false; } else { $conn->tablePrefix( $prefix ); @@ -810,7 +828,7 @@ class LoadBalancer implements ILoadBalancer { } // Increment reference count - if ( $conn ) { + if ( $conn instanceof IDatabase ) { $refCount = $conn->getLBInfo( 'foreignPoolRefCount' ); $conn->setLBInfo( 'foreignPoolRefCount', $refCount + 1 ); } @@ -908,22 +926,13 @@ class LoadBalancer implements ILoadBalancer { * @throws DBConnectionError */ private function reportConnectionError() { - $conn = $this->mErrorConnection; // the connection which caused the error + $conn = $this->errorConnection; // the connection which caused the error $context = [ 'method' => __METHOD__, 'last_error' => $this->mLastError, ]; - if ( !is_object( $conn ) ) { - // No last connection, probably due to all servers being too busy - $this->connLogger->error( - "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 { + if ( $conn instanceof IDatabase ) { $context['db_server'] = $conn->getServer(); $this->connLogger->warning( "Connection error: {last_error} ({db_server})", @@ -932,6 +941,15 @@ class LoadBalancer implements ILoadBalancer { // throws DBConnectionError $conn->reportConnectionError( "{$this->mLastError} ({$context['db_server']})" ); + } else { + // No last connection, probably due to all servers being too busy + $this->connLogger->error( + "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 ); } } @@ -1351,7 +1369,7 @@ class LoadBalancer implements ILoadBalancer { /** * @param string $domain Domain ID, or false for the current domain - * @param IDatabase|null DB master connectionl used to avoid loops [optional] + * @param IDatabase|null $conn DB master connectionl used to avoid loops [optional] * @return bool */ private function masterRunningReadOnly( $domain, IDatabase $conn = null ) { @@ -1587,3 +1605,5 @@ class LoadBalancer implements ILoadBalancer { $this->disable(); } } + +class_alias( LoadBalancer::class, 'LoadBalancer' );