Aaron Schulz has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/178787

Change subject: Better avoid blocking on ChronologyProtecter check in 
LoadBalancer::getConnection()
......................................................................

Better avoid blocking on ChronologyProtecter check in 
LoadBalancer::getConnection()

Change-Id: Iccf324d87d117972cc6321b2abf1ff101d98fa65
---
M includes/db/DatabaseMysqlBase.php
M includes/db/DatabaseUtility.php
M includes/db/LoadBalancer.php
3 files changed, 34 insertions(+), 6 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/87/178787/1

diff --git a/includes/db/DatabaseMysqlBase.php 
b/includes/db/DatabaseMysqlBase.php
index 7dfae63..430b20c 100644
--- a/includes/db/DatabaseMysqlBase.php
+++ b/includes/db/DatabaseMysqlBase.php
@@ -1271,13 +1271,15 @@
 class MySQLMasterPos implements DBMasterPos {
        /** @var string */
        public $file;
-
-       /** @var int Timestamp */
+       /** @var int Position */
        public $pos;
+       /** @var float UNIX timestamp */
+       public $asOfTime = 0.0;
 
        function __construct( $file, $pos ) {
                $this->file = $file;
                $this->pos = $pos;
+               $this->asOfTime = microtime( true );
        }
 
        function __toString() {
@@ -1303,4 +1305,8 @@
 
                return ( $thisPos && $thatPos && $thisPos >= $thatPos );
        }
+
+       function asOfTime() {
+               return $this->asOfTime;
+       }
 }
diff --git a/includes/db/DatabaseUtility.php b/includes/db/DatabaseUtility.php
index c1e80d3..4e5ed08 100644
--- a/includes/db/DatabaseUtility.php
+++ b/includes/db/DatabaseUtility.php
@@ -339,4 +339,8 @@
  * The implementation details of this opaque type are up to the database 
subclass.
  */
 interface DBMasterPos {
+       /**
+        * @return float UNIX timestamp
+        */
+       public function asOfTime();
 }
diff --git a/includes/db/LoadBalancer.php b/includes/db/LoadBalancer.php
index 07645bd..6930039 100644
--- a/includes/db/LoadBalancer.php
+++ b/includes/db/LoadBalancer.php
@@ -151,17 +151,23 @@
        /**
         * @param array $loads
         * @param bool|string $wiki Wiki to get non-lagged for
+        * @param float $maxLag Restrict the maximum allowed lag to this many 
seconds
         * @return bool|int|string
         */
-       private function getRandomNonLagged( array $loads, $wiki = false ) {
-               # Unset excessively lagged servers
+       private function getRandomNonLagged( array $loads, $wiki = false, 
$maxLag = INF ) {
                $lags = $this->getLagTimes( $wiki );
+
+               # Unset excessively lagged servers
                foreach ( $lags as $i => $lag ) {
                        if ( $i != 0 ) {
+                               $maxServerLag = $maxLag;
+                               if ( isset( $this->mServers[$i]['max lag'] ) ) {
+                                       $maxServerLag = min( $maxServerLag, 
$this->mServers[$i]['max lag'] );
+                               }
                                if ( $lag === false ) {
                                        wfDebugLog( 'replication', "Server #$i 
is not replicating" );
                                        unset( $loads[$i] );
-                               } elseif ( isset( $this->mServers[$i]['max 
lag'] ) && $lag > $this->mServers[$i]['max lag'] ) {
+                               } elseif ( $lag > $maxServerLag ) {
                                        wfDebugLog( 'replication', "Server #$i 
is excessively lagged ($lag seconds)" );
                                        unset( $loads[$i] );
                                }
@@ -252,7 +258,19 @@
                        if ( $wgReadOnly || $this->mAllowLagged || 
$laggedSlaveMode ) {
                                $i = ArrayUtils::pickRandom( $currentLoads );
                        } else {
-                               $i = $this->getRandomNonLagged( $currentLoads, 
$wiki );
+                               $i = false;
+                               if ( $this->mWaitForPos && 
$this->mWaitForPos->asOfTime() ) {
+                                       # ChronologyProtecter causes 
mWaitForPos to be set via sessions.
+                                       # This triggers doWait() after connect, 
so it's especially good to
+                                       # avoid lagged servers so as to avoid 
just blocking in that method.
+                                       $ago = microtime( true ) - 
$this->mWaitForPos->asOfTime();
+                                       # Aim for <= 1 second of waiting (being 
too picky can backfire)
+                                       $i = $this->getRandomNonLagged( 
$currentLoads, $wiki, $ago + 1 );
+                               }
+                               if ( $i === false ) {
+                                       # Any server with less lag than it's 
'max lag' param is preferable
+                                       $i = $this->getRandomNonLagged( 
$currentLoads, $wiki );
+                               }
                                if ( $i === false && count( $currentLoads ) != 
0 ) {
                                        # All slaves lagged. Switch to 
read-only mode
                                        wfDebugLog( 'replication', "All slaves 
lagged. Switch to read-only mode" );

-- 
To view, visit https://gerrit.wikimedia.org/r/178787
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iccf324d87d117972cc6321b2abf1ff101d98fa65
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Aaron Schulz <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to