rdbms: make safeWaitForMasterPos() handle master connection failure
[lhc/web/wiklou.git] / includes / libs / rdbms / loadbalancer / LoadBalancer.php
index ca18122..9e4b15f 100644 (file)
@@ -85,7 +85,7 @@ class LoadBalancer implements ILoadBalancer {
        /** @var string Alternate ID string for the domain instead of DatabaseDomain::getId() */
        private $localDomainIdAlias;
        /** @var int */
-       private $maxLag = self::MAX_LAG_DEFAULT;
+       private $maxLag;
 
        /** @var string Current server name */
        private $hostname;
@@ -134,7 +134,7 @@ class LoadBalancer implements ILoadBalancer {
        const CONN_HELD_WARN_THRESHOLD = 10;
 
        /** @var int Default 'maxLag' when unspecified */
-       const MAX_LAG_DEFAULT = 10;
+       const MAX_LAG_DEFAULT = 6;
        /** @var int Default 'waitTimeout' when unspecified */
        const MAX_WAIT_DEFAULT = 10;
        /** @var int Seconds to cache master server read-only status */
@@ -200,9 +200,7 @@ class LoadBalancer implements ILoadBalancer {
                        $this->readOnlyReason = $params['readOnlyReason'];
                }
 
-               if ( isset( $params['maxLag'] ) ) {
-                       $this->maxLag = $params['maxLag'];
-               }
+               $this->maxLag = $params['maxLag'] ?? self::MAX_LAG_DEFAULT;
 
                $this->loadMonitorConfig = $params['loadMonitor'] ?? [ 'class' => 'LoadMonitorNull' ];
                $this->loadMonitorConfig += [ 'lagWarnThreshold' => $this->maxLag ];
@@ -307,7 +305,7 @@ class LoadBalancer implements ILoadBalancer {
 
                                $host = $this->getServerName( $i );
                                if ( $lag === false && !is_infinite( $maxServerLag ) ) {
-                                       $this->replLogger->error(
+                                       $this->replLogger->debug(
                                                __METHOD__ .
                                                ": server {host} is not replicating?", [ 'host' => $host ] );
                                        unset( $loads[$i] );
@@ -408,7 +406,7 @@ class LoadBalancer implements ILoadBalancer {
         * @return array (reader index, lagged replica mode) or false on failure
         */
        private function pickReaderIndex( array $loads, $domain = false ) {
-               if ( !count( $loads ) ) {
+               if ( $loads === [] ) {
                        throw new InvalidArgumentException( "Empty server array given to LoadBalancer" );
                }
 
@@ -476,7 +474,7 @@ class LoadBalancer implements ILoadBalancer {
                }
 
                // If all servers were down, quit now
-               if ( !count( $currentLoads ) ) {
+               if ( $currentLoads === [] ) {
                        $this->connLogger->error( __METHOD__ . ": all servers down" );
                }
 
@@ -1074,7 +1072,7 @@ class LoadBalancer implements ILoadBalancer {
         * Test if the specified index represents an open connection
         *
         * @param int $index Server index
-        * @access private
+        * @private
         * @return bool
         */
        private function isOpen( $index ) {
@@ -1844,12 +1842,6 @@ class LoadBalancer implements ILoadBalancer {
                }
        }
 
-       /**
-        * @param IDatabase $conn
-        * @param DBMasterPos|bool $pos
-        * @param int|null $timeout
-        * @return bool
-        */
        public function safeWaitForMasterPos( IDatabase $conn, $pos = false, $timeout = null ) {
                $timeout = max( 1, $timeout ?: $this->waitTimeout );
 
@@ -1864,6 +1856,12 @@ class LoadBalancer implements ILoadBalancer {
                                $pos = $masterConn->getMasterPos();
                        } else {
                                $masterConn = $this->openConnection( $this->getWriterIndex(), self::DOMAIN_ANY );
+                               if ( !$masterConn ) {
+                                       throw new DBReplicationWaitError(
+                                               null,
+                                               "Could not obtain a master database connection to get the position"
+                                       );
+                               }
                                $pos = $masterConn->getMasterPos();
                                $this->closeConnection( $masterConn );
                        }