Make getCacheSetOptions() and WAN cache handle broken replication
authorAaron Schulz <aschulz@wikimedia.org>
Sat, 28 Nov 2015 12:13:27 +0000 (04:13 -0800)
committerAaron Schulz <aschulz@wikimedia.org>
Wed, 2 Dec 2015 23:38:23 +0000 (15:38 -0800)
TTL_LAGGED now triggers if the slave or I/O threads stopped

Change-Id: I5e7bf2d33b8d3a60182ec53a93d65f7e55f02222

includes/db/Database.php
includes/libs/objectcache/WANObjectCache.php

index c0cf067..68f94b6 100644 (file)
@@ -3820,7 +3820,7 @@ abstract class DatabaseBase implements IDatabase {
         * @param IDatabase $db1
         * @param IDatabase ...
         * @return array Map of values:
-        *   - lag: highest lag of any of the DBs
+        *   - lag: highest lag of any of the DBs or false on error (e.g. replication stopped)
         *   - since: oldest UNIX timestamp of any of the DB lag estimates
         *   - pending: whether any of the DBs have uncommitted changes
         * @since 1.27
@@ -3830,7 +3830,11 @@ abstract class DatabaseBase implements IDatabase {
                foreach ( func_get_args() as $db ) {
                        /** @var IDatabase $db */
                        $status = $db->getSessionLagStatus();
-                       $res['lag'] = max( $res['lag'], $status['lag'] );
+                       if ( $status['lag'] === false ) {
+                               $res['lag'] = false;
+                       } elseif ( $res['lag'] !== false ) {
+                               $res['lag'] = max( $res['lag'], $status['lag'] );
+                       }
                        $res['since'] = min( $res['since'], $status['since'] );
                        $res['pending'] = $res['pending'] ?: $db->writesPending();
                }
index 16e894e..5cd57b7 100644 (file)
@@ -378,7 +378,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
 
                $wrapExtra = array(); // additional wrapped value fields
                // Check if there's a risk of writing stale data after the purge tombstone expired
-               if ( ( $lag + $age ) > self::MAX_READ_LAG ) {
+               if ( $lag === false || ( $lag + $age ) > self::MAX_READ_LAG ) {
                        // Case A: read lag with "lockTSE"; save but record value as stale
                        if ( $lockTSE >= 0 ) {
                                $ttl = max( 1, (int)$lockTSE ); // set() expects seconds
@@ -389,7 +389,7 @@ class WANObjectCache implements IExpiringStore, LoggerAwareInterface {
 
                                return true; // no-op the write for being unsafe
                        // Case C: high replication lag; lower TTL instead of ignoring all set()s
-                       } elseif ( $lag > self::MAX_READ_LAG ) {
+                       } elseif ( $lag === false || $lag > self::MAX_READ_LAG ) {
                                $ttl = $ttl ? min( $ttl, self::TTL_LAGGED ) : self::TTL_LAGGED;
                                $this->logger->warning( "Lowered set() TTL for $key due to replication lag." );
                        // Case D: medium length request with medium replication lag; ignore this set()