populateRevisionLength: Read from slaves when possible
authorBartosz Dziewoński <matma.rex@gmail.com>
Sun, 22 May 2016 20:48:11 +0000 (22:48 +0200)
committerBartosz Dziewoński <matma.rex@gmail.com>
Sun, 22 May 2016 20:48:11 +0000 (22:48 +0200)
The references to revision content stored in 'revision' and 'archive'
tables are immutable (outside of other maintenance scripts), so we can
safely query them from slave databases.

Also:
* Avoid transactions with no operations inside them
* Improve documentation

Bug: T135414
Change-Id: I3e1407e18e09cf01f105c1cae6d6c23bfde747e6

maintenance/populateRevisionLength.php

index 10408ec..dcb9933 100644 (file)
@@ -1,7 +1,6 @@
 <?php
 /**
- * Populates the rev_len and ar_len fields for old revisions created
- * before MW 1.10.
+ * Populates the rev_len and ar_len fields when they are NULL.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,8 +24,9 @@
 require_once __DIR__ . '/Maintenance.php';
 
 /**
- * Maintenance script that populates the rev_len and ar_len fields
- * for old revisions created before MW 1.10.
+ * Maintenance script that populates the rev_len and ar_len fields when they are NULL.
+ * This is the case for all revisions created before MW 1.10, as well as those affected
+ * by T18748 (MW 1.10-1.13) and those affected by T135414 (MW 1.21-1.24).
  *
  * @ingroup Maintenance
  */
@@ -42,12 +42,12 @@ class PopulateRevisionLength extends LoggedUpdateMaintenance {
        }
 
        public function doDBUpdates() {
-               $db = $this->getDB( DB_MASTER );
-               if ( !$db->tableExists( 'revision' ) ) {
+               $dbw = $this->getDB( DB_MASTER );
+               if ( !$dbw->tableExists( 'revision' ) ) {
                        $this->error( "revision table does not exist", true );
-               } elseif ( !$db->tableExists( 'archive' ) ) {
+               } elseif ( !$dbw->tableExists( 'archive' ) ) {
                        $this->error( "archive table does not exist", true );
-               } elseif ( !$db->fieldExists( 'revision', 'rev_len', __METHOD__ ) ) {
+               } elseif ( !$dbw->fieldExists( 'revision', 'rev_len', __METHOD__ ) ) {
                        $this->output( "rev_len column does not exist\n\n", true );
 
                        return false;
@@ -73,9 +73,10 @@ class PopulateRevisionLength extends LoggedUpdateMaintenance {
         * @return int
         */
        protected function doLenUpdates( $table, $idCol, $prefix, $fields ) {
-               $db = $this->getDB( DB_MASTER );
-               $start = $db->selectField( $table, "MIN($idCol)", false, __METHOD__ );
-               $end = $db->selectField( $table, "MAX($idCol)", false, __METHOD__ );
+               $dbr = $this->getDB( DB_SLAVE );
+               $dbw = $this->getDB( DB_MASTER );
+               $start = $dbw->selectField( $table, "MIN($idCol)", false, __METHOD__ );
+               $end = $dbw->selectField( $table, "MAX($idCol)", false, __METHOD__ );
                if ( !$start || !$end ) {
                        $this->output( "...$table table seems to be empty.\n" );
 
@@ -89,7 +90,7 @@ class PopulateRevisionLength extends LoggedUpdateMaintenance {
 
                while ( $blockStart <= $end ) {
                        $this->output( "...doing $idCol from $blockStart to $blockEnd\n" );
-                       $res = $db->select(
+                       $res = $dbr->select(
                                $table,
                                $fields,
                                [
@@ -100,14 +101,16 @@ class PopulateRevisionLength extends LoggedUpdateMaintenance {
                                __METHOD__
                        );
 
-                       $this->beginTransaction( $db, __METHOD__ );
-                       # Go through and update rev_len from these rows.
-                       foreach ( $res as $row ) {
-                               if ( $this->upgradeRow( $row, $table, $idCol, $prefix ) ) {
-                                       $count++;
+                       if ( $res->numRows() > 0 ) {
+                               $this->beginTransaction( $dbw, __METHOD__ );
+                               # Go through and update rev_len from these rows.
+                               foreach ( $res as $row ) {
+                                       if ( $this->upgradeRow( $row, $table, $idCol, $prefix ) ) {
+                                               $count++;
+                                       }
                                }
+                               $this->commitTransaction( $dbw, __METHOD__ );
                        }
-                       $this->commitTransaction( $db, __METHOD__ );
 
                        $blockStart += $this->mBatchSize;
                        $blockEnd += $this->mBatchSize;
@@ -125,7 +128,7 @@ class PopulateRevisionLength extends LoggedUpdateMaintenance {
         * @return bool
         */
        protected function upgradeRow( $row, $table, $idCol, $prefix ) {
-               $db = $this->getDB( DB_MASTER );
+               $dbw = $this->getDB( DB_MASTER );
 
                $rev = ( $table === 'archive' )
                        ? Revision::newFromArchiveRow( $row )
@@ -141,7 +144,7 @@ class PopulateRevisionLength extends LoggedUpdateMaintenance {
                }
 
                # Update the row...
-               $db->update( $table,
+               $dbw->update( $table,
                        [ "{$prefix}_len" => $content->getSize() ],
                        [ $idCol => $row->$idCol ],
                        __METHOD__