From: Timo Tijhof Date: Fri, 24 Feb 2017 22:56:31 +0000 (-0800) Subject: resourceloader: Add purgeModuleDeps.php maintenance script X-Git-Tag: 1.31.0-rc.0~3917^2 X-Git-Url: http://git.heureux-cyclage.org/?a=commitdiff_plain;h=bb33522e2675858de39907060f8cee3e54fa4b49;p=lhc%2Fweb%2Fwiklou.git resourceloader: Add purgeModuleDeps.php maintenance script Based on cleanupRemovedModules.php. Update both to use safer batching, based on known selection instead of recursing until the table is empty (which may end up deleting new rows from live traffic). Bug: T158105 Change-Id: I05f650a0cfa8ca647f143a40e1087338adbef6da --- diff --git a/autoload.php b/autoload.php index e5879d944a..ad442738cd 100644 --- a/autoload.php +++ b/autoload.php @@ -1128,6 +1128,7 @@ $wgAutoloadLocalClasses = [ 'PurgeChangedPages' => __DIR__ . '/maintenance/purgeChangedPages.php', 'PurgeJobUtils' => __DIR__ . '/includes/jobqueue/utils/PurgeJobUtils.php', 'PurgeList' => __DIR__ . '/maintenance/purgeList.php', + 'PurgeModuleDeps' => __DIR__ . '/maintenance/purgeModuleDeps.php', 'PurgeOldText' => __DIR__ . '/maintenance/purgeOldText.php', 'PurgeParserCache' => __DIR__ . '/maintenance/purgeParserCache.php', 'QueryPage' => __DIR__ . '/includes/specialpage/QueryPage.php', diff --git a/maintenance/cleanupRemovedModules.php b/maintenance/cleanupRemovedModules.php index 863d74afb4..83ab35c339 100644 --- a/maintenance/cleanupRemovedModules.php +++ b/maintenance/cleanupRemovedModules.php @@ -38,31 +38,43 @@ class CleanupRemovedModules extends Maintenance { parent::__construct(); $this->addDescription( 'Remove cache entries for removed ResourceLoader modules from the database' ); - $this->addOption( 'batchsize', 'Delete rows in batches of this size. Default: 500', false, true ); + $this->setBatchSize( 500 ); } public function execute() { + $this->output( "Cleaning up module_deps table...\n" ); + $dbw = $this->getDB( DB_MASTER ); $rl = new ResourceLoader( MediaWikiServices::getInstance()->getMainConfig() ); $moduleNames = $rl->getModuleNames(); - $moduleList = implode( ', ', array_map( [ $dbw, 'addQuotes' ], $moduleNames ) ); - $limit = max( 1, intval( $this->getOption( 'batchsize', 500 ) ) ); + $res = $dbw->select( 'module_deps', + [ 'md_module', 'md_skin' ], + $moduleNames ? 'md_module NOT IN (' . $dbw->makeList( $moduleNames ) . ')' : '1=1', + __METHOD__ + ); + $rows = iterator_to_array( $res, false ); - $this->output( "Cleaning up module_deps table...\n" ); - $i = 1; $modDeps = $dbw->tableName( 'module_deps' ); - do { - // $dbw->delete() doesn't support LIMIT :( - $where = $moduleList ? "md_module NOT IN ($moduleList)" : '1=1'; - $dbw->query( "DELETE FROM $modDeps WHERE $where LIMIT $limit", __METHOD__ ); + $i = 1; + foreach ( array_chunk( $rows, $this->mBatchSize ) as $chunk ) { + // WHERE ( mod=A AND skin=A ) OR ( mod=A AND skin=B) .. + $conds = array_map( function ( stdClass $row ) use ( $dbw ) { + return $dbw->makeList( (array)$row, IDatabase::LIST_AND ); + }, $chunk ); + $conds = $dbw->makeList( $conds, IDatabase::LIST_OR ); + + $this->beginTransaction( $dbw, __METHOD__ ); + $dbw->query( "DELETE FROM $modDeps WHERE $conds", __METHOD__ ); $numRows = $dbw->affectedRows(); $this->output( "Batch $i: $numRows rows\n" ); + $this->commitTransaction( $dbw, __METHOD__ ); + $i++; - wfWaitForSlaves(); - } while ( $numRows > 0 ); - $this->output( "done\n" ); + } + + $this->output( "Done\n" ); } } -$maintClass = "CleanupRemovedModules"; +$maintClass = 'CleanupRemovedModules'; require_once RUN_MAINTENANCE_IF_MAIN; diff --git a/maintenance/purgeModuleDeps.php b/maintenance/purgeModuleDeps.php new file mode 100644 index 0000000000..3088baad09 --- /dev/null +++ b/maintenance/purgeModuleDeps.php @@ -0,0 +1,72 @@ +addDescription( + 'Remove all cache entries for ResourceLoader modules from the database' ); + $this->setBatchSize( 500 ); + } + + public function execute() { + $this->output( "Cleaning up module_deps table...\n" ); + + $dbw = $this->getDB( DB_MASTER ); + $res = $dbw->select( 'module_deps', [ 'md_module', 'md_skin' ], [], __METHOD__ ); + $rows = iterator_to_array( $res, false ); + + $modDeps = $dbw->tableName( 'module_deps' ); + $i = 1; + foreach ( array_chunk( $rows, $this->mBatchSize ) as $chunk ) { + // WHERE ( mod=A AND skin=A ) OR ( mod=A AND skin=B) .. + $conds = array_map( function ( stdClass $row ) use ( $dbw ) { + return $dbw->makeList( (array)$row, IDatabase::LIST_AND ); + }, $chunk ); + $conds = $dbw->makeList( $conds, IDatabase::LIST_OR ); + + $this->beginTransaction( $dbw, __METHOD__ ); + $dbw->query( "DELETE FROM $modDeps WHERE $conds", __METHOD__ ); + $numRows = $dbw->affectedRows(); + $this->output( "Batch $i: $numRows rows\n" ); + $this->commitTransaction( $dbw, __METHOD__ ); + + $i++; + } + + $this->output( "Done\n" ); + } +} + +$maintClass = 'PurgeModuleDeps'; +require_once RUN_MAINTENANCE_IF_MAIN;