From de0b371aac3904e28c830a6796512bb46e560e30 Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Fri, 2 Sep 2016 11:06:56 -0700 Subject: [PATCH] Add flushReplicaSnapshots() method for just clearing snapshots 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 | 10 +++++++ includes/db/loadbalancer/LoadBalancer.php | 32 +++++++++++++++++++++++ includes/jobqueue/JobRunner.php | 2 +- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/includes/db/loadbalancer/LBFactory.php b/includes/db/loadbalancer/LBFactory.php index 2e6f602ce5..6b5161b0b1 100644 --- a/includes/db/loadbalancer/LBFactory.php +++ b/includes/db/loadbalancer/LBFactory.php @@ -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. diff --git a/includes/db/loadbalancer/LoadBalancer.php b/includes/db/loadbalancer/LoadBalancer.php index c554f17109..41e3631520 100644 --- a/includes/db/loadbalancer/LoadBalancer.php +++ b/includes/db/loadbalancer/LoadBalancer.php @@ -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 * diff --git a/includes/jobqueue/JobRunner.php b/includes/jobqueue/JobRunner.php index f25c1ba5c5..112696b5e3 100644 --- a/includes/jobqueue/JobRunner.php +++ b/includes/jobqueue/JobRunner.php @@ -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 ); -- 2.20.1