X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=maintenance%2FinitEditCount.php;h=1b9dac068da4b08ec8854821677744e65d630619;hb=98f987241a798788817e87e2c4bec4c03ccdd8a5;hp=3c4336ff28e3db65fc2a0383d0b1c9406432219d;hpb=5c28dd51ebfe07232b9d082812b64445dcc5f207;p=lhc%2Fweb%2Fwiklou.git diff --git a/maintenance/initEditCount.php b/maintenance/initEditCount.php index 3c4336ff28..1b9dac068d 100644 --- a/maintenance/initEditCount.php +++ b/maintenance/initEditCount.php @@ -24,6 +24,8 @@ require_once __DIR__ . '/Maintenance.php'; +use MediaWiki\MediaWikiServices; + class InitEditCount extends Maintenance { public function __construct() { parent::__construct(); @@ -38,9 +40,9 @@ in the load balancer, usually indicating a replication environment.' ); } public function execute() { + global $wgActorTableSchemaMigrationStage; + $dbw = $this->getDB( DB_MASTER ); - $user = $dbw->tableName( 'user' ); - $revision = $dbw->tableName( 'revision' ); // Autodetect mode... if ( $this->hasOption( 'background' ) ) { @@ -48,7 +50,19 @@ in the load balancer, usually indicating a replication environment.' ); } elseif ( $this->hasOption( 'quick' ) ) { $backgroundMode = false; } else { - $backgroundMode = wfGetLB()->getServerCount() > 1; + $lb = MediaWikiServices::getInstance()->getDBLoadBalancer(); + $backgroundMode = $lb->getServerCount() > 1; + } + + $actorQuery = ActorMigration::newMigration()->getJoin( 'rev_user' ); + + $needSpecialQuery = ( $wgActorTableSchemaMigrationStage !== MIGRATION_OLD && + $wgActorTableSchemaMigrationStage !== MIGRATION_NEW ); + if ( $needSpecialQuery ) { + foreach ( $actorQuery['joins'] as &$j ) { + $j[0] = 'JOIN'; // replace LEFT JOIN + } + unset( $j ); } if ( $backgroundMode ) { @@ -62,15 +76,55 @@ in the load balancer, usually indicating a replication environment.' ); $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__ ); + + if ( $needSpecialQuery ) { + // Use separate subqueries to collect counts with the old + // and new schemas, to avoid having to do whole-table scans. + $result = $dbr->select( + [ + 'user', + 'rev1' => '(' + . $dbr->selectSQLText( + [ 'revision', 'revision_actor_temp' ], + [ 'rev_user', 'ct' => 'COUNT(*)' ], + [ + "rev_user > $min AND rev_user <= $max", + 'revactor_rev' => null, + ], + __METHOD__, + [ 'GROUP BY' => 'rev_user' ], + [ 'revision_actor_temp' => [ 'LEFT JOIN', 'revactor_rev = rev_id' ] ] + ) . ')', + 'rev2' => '(' + . $dbr->selectSQLText( + [ 'revision' ] + $actorQuery['tables'], + [ 'actor_user', 'ct' => 'COUNT(*)' ], + "actor_user > $min AND actor_user <= $max", + __METHOD__, + [ 'GROUP BY' => 'actor_user' ], + $actorQuery['joins'] + ) . ')', + ], + [ 'user_id', 'user_editcount' => 'COALESCE(rev1.ct,0) + COALESCE(rev2.ct,0)' ], + "user_id > $min AND user_id <= $max", + __METHOD__, + [], + [ + 'rev1' => [ 'LEFT JOIN', 'user_id = rev_user' ], + 'rev2' => [ 'LEFT JOIN', 'user_id = actor_user' ], + ] + ); + } else { + $revUser = $actorQuery['fields']['rev_user']; + $result = $dbr->select( + [ 'user', 'rev' => [ 'revision' ] + $actorQuery['tables'] ], + [ 'user_id', 'user_editcount' => "COUNT($revUser)" ], + "user_id > $min AND user_id <= $max", + __METHOD__, + [ 'GROUP BY' => 'user_id' ], + [ 'rev' => [ 'LEFT JOIN', "user_id = $revUser" ] ] + $actorQuery['joins'] + ); + } foreach ( $result as $row ) { $dbw->update( 'user', @@ -93,8 +147,43 @@ in the load balancer, usually indicating a replication environment.' ); } } else { $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 ); + + $user = $dbw->tableName( 'user' ); + if ( $needSpecialQuery ) { + $subquery1 = $dbw->selectSQLText( + [ 'revision', 'revision_actor_temp' ], + [ 'COUNT(*)' ], + [ + 'user_id = rev_user', + 'revactor_rev' => null, + ], + __METHOD__, + [], + [ 'revision_actor_temp' => [ 'LEFT JOIN', 'revactor_rev = rev_id' ] ] + ); + $subquery2 = $dbw->selectSQLText( + [ 'revision' ] + $actorQuery['tables'], + [ 'COUNT(*)' ], + 'user_id = actor_user', + __METHOD__, + [], + $actorQuery['joins'] + ); + $dbw->query( + "UPDATE $user SET user_editcount=($subquery1) + ($subquery2)", + __METHOD__ + ); + } else { + $subquery = $dbw->selectSQLText( + [ 'revision' ] + $actorQuery['tables'], + [ 'COUNT(*)' ], + [ 'user_id = ' . $actorQuery['fields']['rev_user'] ], + __METHOD__, + [], + $actorQuery['joins'] + ); + $dbw->query( "UPDATE $user SET user_editcount=($subquery)", __METHOD__ ); + } } $this->output( "Done!\n" );