From 01a5c6013e4a59815678b56bea21b94c0975d338 Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Tue, 7 Apr 2015 11:04:17 -0700 Subject: [PATCH] Made wfReadOnly() more robust at handling the lagged-slave case * Previously if it was called before a DB_SLAVE connection, it would not be set. This is fixed now. * Also set mLaggedSlaveMode in LoadBalancer as appropriate. Before, it was only set in the "too lagged for ChronologyProtector" case. Change-Id: Ic4dc555cf762653f157df1795f53f3577c1e587a --- includes/GlobalFunctions.php | 6 ++++++ includes/db/LoadBalancer.php | 15 ++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index 7c4ebc27e2..3be43b39cc 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -1344,6 +1344,12 @@ function wfReadOnlyReason() { } else { $wgReadOnly = false; } + // Callers use this method to be aware that data presented to a user + // may be very stale and thus allowing submissions can be problematic. + if ( $wgReadOnly === false && wfGetLB()->getLaggedSlaveMode() ) { + $wgReadOnly = 'The database has been automatically locked ' . + 'while the slave database servers catch up to the master'; + } } return $wgReadOnly; diff --git a/includes/db/LoadBalancer.php b/includes/db/LoadBalancer.php index d9584e147b..bc17911f9a 100644 --- a/includes/db/LoadBalancer.php +++ b/includes/db/LoadBalancer.php @@ -214,7 +214,7 @@ class LoadBalancer { * @return bool|int|string */ public function getReaderIndex( $group = false, $wiki = false ) { - global $wgReadOnly, $wgDBtype; + global $wgDBtype; # @todo FIXME: For now, only go through all this for mysql databases if ( $wgDBtype != 'mysql' ) { @@ -258,7 +258,7 @@ class LoadBalancer { # meets our criteria $currentLoads = $nonErrorLoads; while ( count( $currentLoads ) ) { - if ( $wgReadOnly || $this->mAllowLagged || $laggedSlaveMode ) { + if ( $this->mAllowLagged || $laggedSlaveMode ) { $i = ArrayUtils::pickRandom( $currentLoads ); } else { $i = false; @@ -277,8 +277,6 @@ class LoadBalancer { if ( $i === false && count( $currentLoads ) != 0 ) { # All slaves lagged. Switch to read-only mode wfDebugLog( 'replication', "All slaves lagged. Switch to read-only mode" ); - $wgReadOnly = 'The database has been automatically locked ' . - 'while the slave database servers catch up to the master'; $i = ArrayUtils::pickRandom( $currentLoads ); $laggedSlaveMode = true; } @@ -330,6 +328,10 @@ class LoadBalancer { } if ( $this->mReadIndex <= 0 && $this->mLoads[$i] > 0 && $group === false ) { $this->mReadIndex = $i; + # Record if the generic reader index is in "lagged slave" mode + if ( $laggedSlaveMode ) { + $this->mLaggedSlaveMode = true; + } } $serverName = $this->getServerName( $i ); wfDebug( __METHOD__ . ": using server $serverName for group '$group'\n" ); @@ -1096,9 +1098,12 @@ class LoadBalancer { } /** - * @return bool + * @return bool Whether the generic connection for reads is highly "lagged" */ public function getLaggedSlaveMode() { + # Get a generic reader connection + $this->getConnection( DB_SLAVE ); + return $this->mLaggedSlaveMode; } -- 2.20.1