Merge "mediawiki.mixins.rotation: Remove unnecessary @-o-keyframes"
[lhc/web/wiklou.git] / includes / db / loadbalancer / LoadBalancer.php
index 19b2d1c..b5a79a9 100644 (file)
@@ -40,9 +40,9 @@ class LoadBalancer {
        private $mAllowLagged;
        /** @var integer Seconds to spend waiting on slave lag to resolve */
        private $mWaitTimeout;
-
        /** @var array LBFactory information */
        private $mParentInfo;
+
        /** @var string The LoadMonitor subclass name */
        private $mLoadMonitorClass;
        /** @var LoadMonitor */
@@ -67,6 +67,9 @@ class LoadBalancer {
        /** @var integer Total connections opened */
        private $connsOpened = 0;
 
+       /** @var TransactionProfiler */
+       protected $trxProfiler;
+
        /** @var integer Warn when this many connection are held */
        const CONN_HELD_WARN_THRESHOLD = 10;
        /** @var integer Default 'max lag' when unspecified */
@@ -127,6 +130,12 @@ class LoadBalancer {
                }
 
                $this->srvCache = ObjectCache::getLocalServerInstance();
+
+               if ( isset( $params['trxProfiler'] ) ) {
+                       $this->trxProfiler = $params['trxProfiler'];
+               } else {
+                       $this->trxProfiler = new TransactionProfiler();
+               }
        }
 
        /**
@@ -181,11 +190,13 @@ class LoadBalancer {
                                if ( isset( $this->mServers[$i]['max lag'] ) ) {
                                        $maxServerLag = min( $maxServerLag, $this->mServers[$i]['max lag'] );
                                }
+
+                               $host = $this->getServerName( $i );
                                if ( $lag === false ) {
-                                       wfDebugLog( 'replication', "Server #$i is not replicating" );
+                                       wfDebugLog( 'replication', "Server $host (#$i) is not replicating?" );
                                        unset( $loads[$i] );
                                } elseif ( $lag > $maxServerLag ) {
-                                       wfDebugLog( 'replication', "Server #$i is excessively lagged ($lag seconds)" );
+                                       wfDebugLog( 'replication', "Server $host (#$i) has >= $lag seconds of lag" );
                                        unset( $loads[$i] );
                                }
                        }
@@ -670,9 +681,7 @@ class LoadBalancer {
         *
         * @param int $i Server index
         * @param string|bool $wiki Wiki ID, or false for the current wiki
-        * @return DatabaseBase
-        *
-        * @access private
+        * @return DatabaseBase|bool Returns false on errors
         */
        public function openConnection( $i, $wiki = false ) {
                if ( $wiki !== false ) {
@@ -816,11 +825,14 @@ class LoadBalancer {
                        $server['dbname'] = $dbNameOverride;
                }
 
+               // Let the handle know what the cluster master is (e.g. "db1052")
+               $masterName = $this->getServerName( 0 );
+               $server['clusterMasterHost'] = $masterName;
+
                // Log when many connection are made on requests
                if ( ++$this->connsOpened >= self::CONN_HELD_WARN_THRESHOLD ) {
-                       $masterAddr = $this->getServerName( 0 );
                        wfDebugLog( 'DBPerformance', __METHOD__ . ": " .
-                               "{$this->connsOpened}+ connections made (master=$masterAddr)\n" .
+                               "{$this->connsOpened}+ connections made (master=$masterName)\n" .
                                wfBacktrace( true ) );
                }
 
@@ -834,6 +846,10 @@ class LoadBalancer {
                }
 
                $db->setLBInfo( $server );
+               $db->setLazyMasterHandle(
+                       $this->getLazyConnectionRef( DB_MASTER, array(), $db->getWikiID() )
+               );
+               $db->setTransactionProfiler( $this->trxProfiler );
 
                return $db;
        }
@@ -1021,14 +1037,15 @@ class LoadBalancer {
 
        /**
         * Commit transactions on all open connections
+        * @param string $fname Caller name
         */
-       public function commitAll() {
+       public function commitAll( $fname = __METHOD__ ) {
                foreach ( $this->mConns as $conns2 ) {
                        foreach ( $conns2 as $conns3 ) {
                                /** @var DatabaseBase[] $conns3 */
                                foreach ( $conns3 as $conn ) {
                                        if ( $conn->trxLevel() ) {
-                                               $conn->commit( __METHOD__, 'flush' );
+                                               $conn->commit( $fname, 'flush' );
                                        }
                                }
                        }
@@ -1036,9 +1053,10 @@ class LoadBalancer {
        }
 
        /**
-        *  Issue COMMIT only on master, only if queries were done on connection
+        * Issue COMMIT only on master, only if queries were done on connection
+        * @param string $fname Caller name
         */
-       public function commitMasterChanges() {
+       public function commitMasterChanges( $fname = __METHOD__ ) {
                $masterIndex = $this->getWriterIndex();
                foreach ( $this->mConns as $conns2 ) {
                        if ( empty( $conns2[$masterIndex] ) ) {
@@ -1047,7 +1065,7 @@ class LoadBalancer {
                        /** @var DatabaseBase $conn */
                        foreach ( $conns2[$masterIndex] as $conn ) {
                                if ( $conn->trxLevel() && $conn->writesOrCallbacksPending() ) {
-                                       $conn->commit( __METHOD__, 'flush' );
+                                       $conn->commit( $fname, 'flush' );
                                }
                        }
                }
@@ -1055,9 +1073,11 @@ class LoadBalancer {
 
        /**
         * Issue ROLLBACK only on master, only if queries were done on connection
+        * @param string $fname Caller name
+        * @throws DBExpectedError
         * @since 1.23
         */
-       public function rollbackMasterChanges() {
+       public function rollbackMasterChanges( $fname = __METHOD__ ) {
                $failedServers = array();
 
                $masterIndex = $this->getWriterIndex();
@@ -1069,7 +1089,7 @@ class LoadBalancer {
                        foreach ( $conns2[$masterIndex] as $conn ) {
                                if ( $conn->trxLevel() && $conn->writesOrCallbacksPending() ) {
                                        try {
-                                               $conn->rollback( __METHOD__, 'flush' );
+                                               $conn->rollback( $fname, 'flush' );
                                        } catch ( DBError $e ) {
                                                MWExceptionHandler::logException( $e );
                                                $failedServers[] = $conn->getServer();
@@ -1148,6 +1168,29 @@ class LoadBalancer {
                        || $this->lastMasterChangeTimestamp() > microtime( true ) - $age );
        }
 
+       /**
+        * Get the list of callers that have pending master changes
+        *
+        * @return array
+        * @since 1.27
+        */
+       public function pendingMasterChangeCallers() {
+               $fnames = array();
+
+               $masterIndex = $this->getWriterIndex();
+               foreach ( $this->mConns as $conns2 ) {
+                       if ( empty( $conns2[$masterIndex] ) ) {
+                               continue;
+                       }
+                       /** @var DatabaseBase $conn */
+                       foreach ( $conns2[$masterIndex] as $conn ) {
+                               $fnames = array_merge( $fnames, $conn->pendingWriteCallers() );
+                       }
+               }
+
+               return $fnames;
+       }
+
        /**
         * @param mixed $value
         * @return mixed