Avoid useless delay and master connections in wfWaitForSlaves() in runJobs.php
authorAaron Schulz <aschulz@wikimedia.org>
Sat, 19 Jul 2014 22:19:36 +0000 (15:19 -0700)
committerAaron Schulz <aschulz@wikimedia.org>
Sat, 19 Jul 2014 22:19:40 +0000 (15:19 -0700)
* Some jobs, like Parsoid ones, do not actually do master DB updates

Change-Id: I1a8830eafd7760d081df966bb423030dcdc96408

includes/GlobalFunctions.php
includes/db/Database.php
maintenance/runJobs.php

index d0af179..fc99b58 100644 (file)
@@ -3798,11 +3798,14 @@ function wfGetNull() {
  * in maintenance scripts, to avoid causing too much lag.  Of course, this is
  * a no-op if there are no slaves.
  *
- * @param int|bool $maxLag (deprecated)
+ * @param float|null $ifWritesSince Only wait if writes were done since this UNIX timestamp
  * @param string|bool $wiki Wiki identifier accepted by wfGetLB
  * @param string|bool $cluster Cluster name accepted by LBFactory. Default: false.
  */
-function wfWaitForSlaves( $maxLag = false, $wiki = false, $cluster = false ) {
+function wfWaitForSlaves( $ifWritesSince = false, $wiki = false, $cluster = false ) {
+       // B/C: first argument used to be "max seconds of lag"; ignore such values
+       $ifWritesSince = ( $ifWritesSince > 1e9 ) ? $ifWritesSince : false;
+
        if ( $cluster !== false ) {
                $lb = wfGetLBFactory()->getExternalLB( $cluster );
        } else {
@@ -3812,7 +3815,13 @@ function wfWaitForSlaves( $maxLag = false, $wiki = false, $cluster = false ) {
        // bug 27975 - Don't try to wait for slaves if there are none
        // Prevents permission error when getting master position
        if ( $lb->getServerCount() > 1 ) {
+               if ( $ifWritesSince && !$lb->isOpen( DB_MASTER ) ) {
+                       return; // assume no writes done
+               }
                $dbw = $lb->getConnection( DB_MASTER, array(), $wiki );
+               if ( $ifWritesSince && $dbw->lastDoneWrites() < $ifWritesSince ) {
+                       return; // no writes since the last wait
+               }
                $pos = $dbw->getMasterPos();
                // The DBMS may not support getMasterPos() or the whole
                // load balancer might be fake (e.g. $wgAllDBsAreLocalhost).
index 7d8fbe9..5699a65 100644 (file)
@@ -600,7 +600,18 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
         * @return bool
         */
        public function doneWrites() {
-               return $this->mDoneWrites;
+               return (bool)$this->mDoneWrites;
+       }
+
+       /**
+        * Returns the last time the connection may have been used for write queries.
+        * Should return a timestamp if unsure.
+        *
+        * @return int|float UNIX timestamp or false
+        * @since 1.24
+        */
+       public function lastDoneWrites() {
+               return $this->mDoneWrites ?: false;
        }
 
        /**
@@ -1020,10 +1031,10 @@ abstract class DatabaseBase implements IDatabase, DatabaseType {
                global $wgUser, $wgDebugDBTransactions;
 
                $this->mLastQuery = $sql;
-               if ( !$this->mDoneWrites && $this->isWriteQuery( $sql ) ) {
+               if ( $this->isWriteQuery( $sql ) ) {
                        # Set a flag indicating that writes have been done
                        wfDebug( __METHOD__ . ': Writes done: ' . DatabaseBase::generalizeSQL( $sql ) . "\n" );
-                       $this->mDoneWrites = true;
+                       $this->mDoneWrites = microtime( true );
                }
 
                # Add a comment for easy SHOW PROCESSLIST interpretation
index 423ae61..e56640f 100644 (file)
@@ -86,7 +86,7 @@ class RunJobs extends Maintenance {
 
                $jobsRun = 0; // counter
                $flags = JobQueueGroup::USE_CACHE;
-               $lastTime = time(); // time since last slave check
+               $lastTime = microtime( true ); // time since last slave check
                do {
                        $backoffs = array_filter( $backoffs, $backoffExpireFunc );
                        $blacklist = $noThrottle ? array() : array_keys( $backoffs );
@@ -146,10 +146,10 @@ class RunJobs extends Maintenance {
                                }
 
                                // Don't let any of the main DB slaves get backed up
-                               $timePassed = time() - $lastTime;
+                               $timePassed = microtime( true ) - $lastTime;
                                if ( $timePassed >= 5 || $timePassed < 0 ) {
-                                       wfWaitForSlaves();
-                                       $lastTime = time();
+                                       wfWaitForSlaves( $lastTime );
+                                       $lastTime = microtime( true );
                                }
                                // Don't let any queue slaves/backups fall behind
                                if ( $jobsRun > 0 && ( $jobsRun % 100 ) == 0 ) {