X-Git-Url: https://git.cyclocoop.org/?a=blobdiff_plain;f=maintenance%2FinitEditCount.php;h=3ca067cb82f6c8a6889187dd27ecd2bc49307c0e;hb=ecf56c33fae16e8a7a8f7ab56e7b6aba3720ceeb;hp=d26349bbe40c85bfbe059f9c5738503332f9492c;hpb=087a9f70c5c152b72dc6c539cf64e334a0f2d029;p=lhc%2Fweb%2Fwiklou.git diff --git a/maintenance/initEditCount.php b/maintenance/initEditCount.php index d26349bbe4..3ca067cb82 100644 --- a/maintenance/initEditCount.php +++ b/maintenance/initEditCount.php @@ -1,89 +1,107 @@ addOption( 'quick', 'Force the update to be done in a single query' ); + $this->addOption( 'background', 'Force replication-friendly mode; may be inefficient but + avoids locking tables or lagging slaves with large updates; + calculates counts on a slave if possible. Background mode will be automatically used if the server is MySQL 4.0 (which does not support subqueries) or if multiple servers are listed -in \$wgDBservers, usually indicating a replication environment. +in $wgDBservers, usually indicating a replication environment.' ); + $this->mDescription = "Batch-recalculate user_editcount fields from the revision table"; + } -"); -} -$dbw = wfGetDB( DB_MASTER ); -$user = $dbw->tableName( 'user' ); -$revision = $dbw->tableName( 'revision' ); + public function execute() { + global $wgDBservers; + $dbw = wfGetDB( DB_MASTER ); + $user = $dbw->tableName( 'user' ); + $revision = $dbw->tableName( 'revision' ); -$dbver = $dbw->getServerVersion(); + $dbver = $dbw->getServerVersion(); -// Autodetect mode... -$backgroundMode = count( $wgDBservers ) > 1 || - ($dbw instanceof DatabaseMySql && version_compare( $dbver, '4.1' ) < 0); + // Autodetect mode... + $backgroundMode = count( $wgDBservers ) > 1 || + ( $dbw instanceof DatabaseMysql && version_compare( $dbver, '4.1' ) < 0 ); + + if ( $this->hasOption( 'background' ) ) { + $backgroundMode = true; + } elseif ( $this->hasOption( 'quick' ) ) { + $backgroundMode = false; + } -if( isset( $options['background'] ) ) { - $backgroundMode = true; -} elseif( isset( $options['quick'] ) ) { - $backgroundMode = false; -} + if ( $backgroundMode ) { + $this->output( "Using replication-friendly background mode...\n" ); -if( $backgroundMode ) { - echo "Using replication-friendly background mode...\n"; - - $dbr = wfGetDB( DB_SLAVE ); - $chunkSize = 100; - $lastUser = $dbr->selectField( 'user', 'MAX(user_id)', '', __FUNCTION__ ); - - $start = microtime( true ); - $migrated = 0; - for( $min = 0; $min <= $lastUser; $min += $chunkSize ) { - $max = $min + $chunkSize; - $result = $dbr->query( - "SELECT - user_id, - COUNT(rev_user) AS user_editcount - FROM $user - LEFT OUTER JOIN $revision ON user_id=rev_user - WHERE user_id > $min AND user_id <= $max - GROUP BY user_id", - __FUNCTION__ ); - - while( $row = $dbr->fetchObject( $result ) ) { - $dbw->update( 'user', - array( 'user_editcount' => $row->user_editcount ), - array( 'user_id' => $row->user_id ), - __FUNCTION__ ); - ++$migrated; + $dbr = wfGetDB( DB_SLAVE ); + $chunkSize = 100; + $lastUser = $dbr->selectField( 'user', 'MAX(user_id)', '', __METHOD__ ); + + $start = microtime( true ); + $migrated = 0; + for ( $min = 0; $min <= $lastUser; $min += $chunkSize ) { + $max = $min + $chunkSize; + $result = $dbr->query( + "SELECT + user_id, + COUNT(rev_user) AS user_editcount + FROM $user + LEFT OUTER JOIN $revision ON user_id=rev_user + WHERE user_id > $min AND user_id <= $max + GROUP BY user_id", + __METHOD__ ); + + foreach ( $result as $row ) { + $dbw->update( 'user', + array( 'user_editcount' => $row->user_editcount ), + array( 'user_id' => $row->user_id ), + __METHOD__ ); + ++$migrated; + } + + $delta = microtime( true ) - $start; + $rate = ( $delta == 0.0 ) ? 0.0 : $migrated / $delta; + $this->output( sprintf( "%s %d (%0.1f%%) done in %0.1f secs (%0.3f accounts/sec).\n", + wfWikiID(), + $migrated, + min( $max, $lastUser ) / $lastUser * 100.0, + $delta, + $rate ) ); + + wfWaitForSlaves( 10 ); + } + } else { + // Subselect should work on modern MySQLs etc + $this->output( "Using single-query mode...\n" ); + $sql = "UPDATE $user SET user_editcount=(SELECT COUNT(*) FROM $revision WHERE rev_user=user_id)"; + $dbw->query( $sql ); } - $dbr->freeResult( $result ); - - $delta = microtime( true ) - $start; - $rate = ($delta == 0.0) ? 0.0 : $migrated / $delta; - printf( "%s %d (%0.1f%%) done in %0.1f secs (%0.3f accounts/sec).\n", - $wgDBname, - $migrated, - min( $max, $lastUser ) / $lastUser * 100.0, - $delta, - $rate ); - - wfWaitForSlaves( 10 ); + + $this->output( "Done!\n" ); } -} else { - // Subselect should work on modern MySQLs etc - echo "Using single-query mode...\n"; - $sql = "UPDATE $user SET user_editcount=(SELECT COUNT(*) FROM $revision WHERE rev_user=user_id)"; - $dbw->query( $sql ); } -echo "Done!\n"; - - +$maintClass = "InitEditCount"; +require_once( DO_MAINTENANCE );