Merge "rdbms: make safeWaitForMasterPos() respect "waitTimeout""
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 9 Feb 2018 23:41:45 +0000 (23:41 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 9 Feb 2018 23:41:45 +0000 (23:41 +0000)
1  2 
includes/libs/rdbms/loadbalancer/LoadBalancer.php

@@@ -49,7 -49,7 +49,7 @@@ class LoadBalancer implements ILoadBala
        /** @var bool Whether to disregard replica DB lag as a factor in replica DB selection */
        private $mAllowLagged;
        /** @var int Seconds to spend waiting on replica DB lag to resolve */
-       private $mWaitTimeout;
+       private $waitTimeout;
        /** @var array The LoadMonitor configuration */
        private $loadMonitorConfig;
        /** @var array[] $aliases Map of (table => (dbname, schema, prefix) map) */
                        : DatabaseDomain::newUnspecified();
                $this->setLocalDomain( $localDomain );
  
-               $this->mWaitTimeout = isset( $params['waitTimeout'] )
+               $this->waitTimeout = isset( $params['waitTimeout'] )
                        ? $params['waitTimeout']
                        : self::MAX_WAIT_DEFAULT;
  
        }
  
        public function waitForAll( $pos, $timeout = null ) {
-               $timeout = $timeout ?: $this->mWaitTimeout;
+               $timeout = $timeout ?: $this->waitTimeout;
  
                $oldPos = $this->mWaitForPos;
                try {
         * Wait for a given replica DB to catch up to the master pos stored in $this
         * @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
+        * @param int $timeout Max seconds to wait; default is "waitTimeout" given to __construct()
         * @return bool
         */
        protected function doWait( $index, $open = false, $timeout = null ) {
-               $timeout = max( 1, $timeout ?: $this->mWaitTimeout );
+               $timeout = max( 1, $timeout ?: $this->waitTimeout );
  
                // Check if we already know that the DB has reached this point
                $server = $this->getServerName( $index );
                        throw new DBAccessError();
                }
  
 -              if ( $domainOverride->getDatabase() !== null ) {
 +              // Handle $domainOverride being a specified or an unspecified domain
 +              if ( $domainOverride->getDatabase() === null ) {
 +                      // Normally, an RDBMS requires a DB name specified on connection and the $server
 +                      // configuration array is assumed to already specify an appropriate DB name.
 +                      if ( $server['type'] === 'mysql' ) {
 +                              // For MySQL, DATABASE and SCHEMA are synonyms, connections need not specify a DB,
 +                              // and the DB name in $server might not exist due to legacy reasons (the default
 +                              // domain used to ignore the local LB domain, even when mismatched).
 +                              $server['dbname'] = null;
 +                      }
 +              } else {
                        $server['dbname'] = $domainOverride->getDatabase();
                        $server['schema'] = $domainOverride->getSchema();
                }
                $this->trxRoundId = false;
                $this->forEachOpenMasterConnection(
                        function ( IDatabase $conn ) use ( $fname, $restore ) {
 -                              if ( $conn->writesOrCallbacksPending() ) {
 +                              if ( $conn->writesOrCallbacksPending() || $conn->explicitTrxActive() ) {
                                        $conn->rollback( $fname, $conn::FLUSHING_ALL_PEERS );
                                }
                                if ( $restore ) {
        }
  
        public function hasOrMadeRecentMasterChanges( $age = null ) {
-               $age = ( $age === null ) ? $this->mWaitTimeout : $age;
+               $age = ( $age === null ) ? $this->waitTimeout : $age;
  
                return ( $this->hasMasterChanges()
                        || $this->lastMasterChangeTimestamp() > microtime( true ) - $age );
        /**
         * @param IDatabase $conn
         * @param DBMasterPos|bool $pos
-        * @param int $timeout
+        * @param int|null $timeout
         * @return bool
         */
-       public function safeWaitForMasterPos( IDatabase $conn, $pos = false, $timeout = 10 ) {
+       public function safeWaitForMasterPos( IDatabase $conn, $pos = false, $timeout = null ) {
+               $timeout = max( 1, $timeout ?: $this->waitTimeout );
                if ( $this->getServerCount() <= 1 || !$conn->getLBInfo( 'replica' ) ) {
                        return true; // server is not a replica DB
                }