From f204da4bff302ad76144729b4f4b3e360d670941 Mon Sep 17 00:00:00 2001 From: Nik Everett Date: Fri, 29 May 2015 18:07:27 -0400 Subject: [PATCH] Commit all connections after each job If you don't commit the slave connections then they keep their old snapshots. This clears the snapshots so they don't get out of date views of the world. Bug: T100838 Change-Id: I1f6f910d88324beb589b2ad9466d8786376eda55 --- includes/db/LBFactory.php | 9 +++++++++ includes/jobqueue/JobRunner.php | 15 +++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/includes/db/LBFactory.php b/includes/db/LBFactory.php index 4551e2d760..0742df279f 100644 --- a/includes/db/LBFactory.php +++ b/includes/db/LBFactory.php @@ -177,6 +177,15 @@ abstract class LBFactory { }, array( $methodName, $args ) ); } + /** + * Commit on all connections. Done for two reasons: + * 1. To commit changes to the masters. + * 2. To release the snapshot on all connections, master and slave. + */ + public function commitAll() { + $this->forEachLBCallMethod( 'commitAll' ); + } + /** * Commit changes on all master connections */ diff --git a/includes/jobqueue/JobRunner.php b/includes/jobqueue/JobRunner.php index b04ab280a4..bb12298cd8 100644 --- a/includes/jobqueue/JobRunner.php +++ b/includes/jobqueue/JobRunner.php @@ -128,7 +128,7 @@ class JobRunner implements LoggerAwareInterface { $group = JobQueueGroup::singleton(); // Flush any pending DB writes for sanity - wfGetLBFactory()->commitMasterChanges(); + wfGetLBFactory()->commitAll(); // Some jobs types should not run until a certain timestamp $backoffs = array(); // map of (type => UNIX expiry) @@ -190,6 +190,14 @@ class JobRunner implements LoggerAwareInterface { $error = get_class( $e ) . ': ' . $e->getMessage(); MWExceptionHandler::logException( $e ); } + // Commit all outstanding connections that are in a transaction + // to get a fresh repeatable read snapshot on every connection. + // This is important because if you have an old snapshot on the + // database you could run the job incorrectly. Its possible, for + // example, to pick up a RefreshLinksJob for a new page that isn't + // even visible to the snapshot. The snapshot could have been + // created before the page. Fresh snapshots will see the page. + wfGetLBFactory()->commitAll(); $timeMs = intval( ( microtime( true ) - $jobStartTime ) * 1000 ); $timeMsTotal += $timeMs; $profiler->scopedProfileOut( $psection ); @@ -410,7 +418,10 @@ class JobRunner implements LoggerAwareInterface { } /** - * Commit any DB master changes from a job on all load balancers + * Issue a commit on all masters who are currently in a transaction and have + * made changes to the database. It also supports sometimes waiting for the + * local wiki's slaves to catch up. See the documentation for + * $wgJobSerialCommitThreshold for more. * * @param Job $job * @throws DBError -- 2.20.1