Add flushReplicaSnapshots() method for just clearing snapshots
authorAaron Schulz <aschulz@wikimedia.org>
Fri, 2 Sep 2016 18:06:56 +0000 (11:06 -0700)
committerAaron Schulz <aschulz@wikimedia.org>
Fri, 2 Sep 2016 18:06:56 +0000 (11:06 -0700)
This is better than having to use the less safe commitAll(),
which also checks and commits masters with writes.

Change-Id: I01c95f1ebae6927ed5acf0c23dd19b5c2413f661

includes/db/loadbalancer/LBFactory.php
includes/db/loadbalancer/LoadBalancer.php
includes/jobqueue/JobRunner.php

index 2e6f602..6b5161b 100644 (file)
@@ -248,6 +248,16 @@ abstract class LBFactory implements DestructibleService {
                $this->forEachLBCallMethod( 'beginMasterChanges', [ $fname ] );
        }
 
+       /**
+        * Commit all replica DB transactions so as to flush any REPEATABLE-READ or SSI snapshot
+        *
+        * @param string $fname Caller name
+        * @since 1.28
+        */
+       public function flushReplicaSnapshots( $fname = __METHOD__ ) {
+               $this->forEachLBCallMethod( 'flushReplicaSnapshots', [ $fname ] );
+       }
+
        /**
         * Commit on all connections. Done for two reasons:
         * 1. To commit changes to the masters.
index c554f17..41e3631 100644 (file)
@@ -1317,6 +1317,18 @@ class LoadBalancer {
                }
        }
 
+       /**
+        * Commit all replica DB transactions so as to flush any REPEATABLE-READ or SSI snapshot
+        *
+        * @param string $fname Caller name
+        * @since 1.28
+        */
+       public function flushReplicaSnapshots( $fname = __METHOD__ ) {
+               $this->forEachOpenReplicaConnection( function ( DatabaseBase $conn ) {
+                       $conn->clearSnapshot( __METHOD__ );
+               } );
+       }
+
        /**
         * @return bool Whether a master connection is already open
         * @since 1.24
@@ -1559,6 +1571,26 @@ class LoadBalancer {
                }
        }
 
+       /**
+        * Call a function with each open replica DB connection object
+        * @param callable $callback
+        * @param array $params
+        * @since 1.28
+        */
+       public function forEachOpenReplicaConnection( $callback, array $params = [] ) {
+               foreach ( $this->mConns as $connsByServer ) {
+                       foreach ( $connsByServer as $i => $serverConns ) {
+                               if ( $i === $this->getWriterIndex() ) {
+                                       continue; // skip master
+                               }
+                               foreach ( $serverConns as $conn ) {
+                                       $mergedParams = array_merge( [ $conn ], $params );
+                                       call_user_func_array( $callback, $mergedParams );
+                               }
+                       }
+               }
+       }
+
        /**
         * Get the hostname and lag time of the most-lagged slave
         *
index f25c1ba..112696b 100644 (file)
@@ -289,7 +289,7 @@ class JobRunner implements LoggerAwareInterface {
                // Commit all outstanding connections that are in a transaction
                // to get a fresh repeatable read snapshot on every connection.
                // Note that jobs are still responsible for handling slave lag.
-               $lbFactory->commitAll( __METHOD__ );
+               $lbFactory->flushReplicaSnapshots( __METHOD__ );
                // Clear out title cache data from prior snapshots
                LinkCache::singleton()->clear();
                $timeMs = intval( ( microtime( true ) - $jobStartTime ) * 1000 );