X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=maintenance%2FinitEditCount.php;h=f7ef7a28a2c778a7dcd0e301d793e540f498970d;hb=749f15c0a80fd181e795e85d7d68bac17abe0511;hp=96aea03472bff6545f0134d9282c41ec4fe0483b;hpb=f43fa6f4f0e2cb60b8543daad661b48a3e0653a9;p=lhc%2Fweb%2Fwiklou.git diff --git a/maintenance/initEditCount.php b/maintenance/initEditCount.php index 96aea03472..f7ef7a28a2 100644 --- a/maintenance/initEditCount.php +++ b/maintenance/initEditCount.php @@ -38,9 +38,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' ) ) { @@ -51,6 +51,17 @@ in the load balancer, usually indicating a replication environment.' ); $backgroundMode = wfGetLB()->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 ) { $this->output( "Using replication-friendly background mode...\n" ); @@ -62,15 +73,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,13 +144,48 @@ 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" ); } } -$maintClass = "InitEditCount"; +$maintClass = InitEditCount::class; require_once RUN_MAINTENANCE_IF_MAIN;