r23186 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r23185‎ | r23186 | r23187 >
Date:23:09, 21 June 2007
Author:aaron
Status:old
Tags:
Comment:
*Use job queue for revision,recentchanges table updates for large wikis/in miser mode
Modified paths:
  • /trunk/extensions/Renameuser/RenameUserJob.php (added) (history)
  • /trunk/extensions/Renameuser/SpecialRenameuser.php (modified) (history)
  • /trunk/extensions/Renameuser/SpecialRenameuser_body.php (modified) (history)

Diff [purge]

Index: trunk/extensions/Renameuser/RenameUserJob.php
@@ -0,0 +1,20 @@
 2+<?php
 3+
 4+class RenameUserJob extends Job {
 5+ function __construct($title,$params) {
 6+ parent::__construct('renameUser', $title, $params);
 7+ }
 8+
 9+ function run() {
 10+ $dbw = wfGetDB( DB_MASTER );
 11+ // Our keyId param will be an array of ids
 12+ $dbw->update( $this->params['table'],
 13+ array( $this->params['column'] => $this->params['newname'] ),
 14+ array( $this->params['column'] => $this->params['oldname'],
 15+ $this->params['uniqueKey'] => $this->params['keyId'] )
 16+ #,array( $dbw->lowPriorityOption() )
 17+ );
 18+ }
 19+}
 20+
 21+?>
Index: trunk/extensions/Renameuser/SpecialRenameuser_body.php
@@ -279,18 +279,23 @@
280280 $this->new = $new;
281281 $this->uid = $uid;
282282
 283+ // 1.5 schema
283284 $this->tables = array(
284 - // 1.5 schema
285 - 'user' => 'user_name',
286 - 'revision' => 'rev_user_text',
287285 'image' => 'img_user_text',
288 - 'oldimage' => 'oi_user_text',
289 -
290 - // Very hot table, causes lag and deadlocks to update like this
291 - /*'recentchanges' => 'rc_user_text'*/
 286+ 'oldimage' => 'oi_user_text'
292287 );
 288+ $this->tablesJob = array();
 289+ // See if this is for large tables on large, busy, wikis
 290+ if( wfQueriesMustScale() ) {
 291+ $this->tablesJob['revision'] = array('rev_user_text','rev_id');
 292+ $this->tablesJob['recentchanges'] = array('rc_user_text','rc_id');
 293+ } else {
 294+ $this->tables['revision'] = 'rev_user_text';
 295+ $this->tables['recentchanges'] = 'rc_user_text';
 296+ }
293297
294298 global $wgRenameUserQuick;
 299+ // As of 1.10, usernames are not indexed here; too slow for large wikis
295300 if( !$wgRenameUserQuick )
296301 $this->tables['archive'] = 'ar_user_text';
297302
@@ -307,8 +312,16 @@
308313 wfProfileIn( $fname );
309314
310315 $dbw =& wfGetDB( DB_MASTER );
 316+ // Rename and touch the user before re-attributing edits,
 317+ // this avoids users still being login in and making new edits while
 318+ // being renamed, which leaves edits at the old name.
 319+ $dbw->update( 'user',
 320+ array( 'user_name' => $this->new, 'user_touched' => $dbw->timestamp() ),
 321+ array( 'user_name' => $this->old ),
 322+ $fname
 323+ );
311324
312 - foreach ($this->tables as $table => $field) {
 325+ foreach( $this->tables as $table => $field ) {
313326 $dbw->update( $table,
314327 array( $field => $this->new ),
315328 array( $field => $this->old ),
@@ -316,16 +329,60 @@
317330 #,array( $dbw->lowPriorityOption() )
318331 );
319332 }
 333+
 334+ foreach( $this->tablesJob as $table => $params ) {
 335+ $res = $dbw->select( $table,
 336+ array( $params[0], $params[1] ),
 337+ array( $params[0] => $this->old )
 338+ );
 339+
 340+ global $wgUpdateRowsPerJob;
 341+
 342+ $batchSize = 500; // Lets not flood the job table!
 343+ $jobSize = $wgUpdateRowsPerJob; // How many rows per job?
320344
321 - $dbw->update( 'user',
322 - array( 'user_touched' => $dbw->timestamp() ),
323 - array( 'user_name' => $this->new ),
324 - $fname
325 - );
326 -
 345+ $key = $params[1];
 346+ $jobParams = array();
 347+ $jobParams['table'] = $table;
 348+ $jobParams['column'] = $params[0];
 349+ $jobParams['uniqueKey'] = $key;
 350+ $jobParams['oldname'] = $this->old;
 351+ $jobParams['newname'] = $this->new;
 352+
 353+ $jobParams['keyId'] = array();
 354+ $jobRows = 0;
 355+ $done = false;
 356+ while ( !$done ) {
 357+ $jobs = array();
 358+ for ( $i = 0; $i < $batchSize; $i++ ) {
 359+ $row = $dbw->fetchObject( $res );
 360+ if ( !$row ) {
 361+ # If there are any job rows left, add it to the queue as a job
 362+ if( $jobRows > 0 ) {
 363+ $jobs[] = Job::factory( 'renameUser', Title::newMainPage(), $jobParams );
 364+ $jobRows = 0;
 365+ $jobParams['keyId'] = array();
 366+ }
 367+ $done = true;
 368+ break;
 369+ }
 370+ $jobParams['keyId'][] = $row->$key;
 371+ $jobRows++;
 372+ # Once a job has $jobSize rows, add it to the queue
 373+ if( $jobRows >= $jobSize ) {
 374+ $jobs[] = Job::factory( 'renameUser', Title::newMainPage(), $jobParams );
 375+ $jobRows = 0;
 376+ $jobParams['keyId'] = array();
 377+ }
 378+ }
 379+ Job::batchInsert( $jobs );
 380+ }
 381+ $dbw->freeResult( $res );
 382+ }
 383+
327384 // Clear the user cache
328385 $wgMemc->delete( "$wgDBname:user:id:{$this->uid}" );
329 -
 386+
330387 // Inform authentication plugin of the change
331388 $user = User::newFromId( $this->uid );
332389 $wgAuth->updateExternalDB( $user );
Index: trunk/extensions/Renameuser/SpecialRenameuser.php
@@ -39,6 +39,9 @@
4040 $wgLogHeaders['renameuser'] = 'renameuserlogpagetext';
4141 $wgLogActions['renameuser/renameuser'] = 'renameuserlogentry';
4242
 43+$wgJobClasses['renameUser'] = 'RenameUserJob';
 44+$wgAutoloadClasses['RenameUserJob'] = dirname(__FILE__) . '/RenameUserJob.php';
 45+
4346 /**
4447 * If this is set to true, then the archive table (deleted revisions) will
4548 * not be updated. Defaults to the value of $wgMiserMode, since if that's on,

Status & tagging log