Reinstate small category refresh logic in LinksDeletionUpdate
Add new Category::refreshCountsIfSmall() method that will do a non-locking SELECT with LIMIT before deciding whether to do a full locking SELECT and refresh. Call this from LinksDeletionUpdate. Bug: T18036 Change-Id: I9de8311565988453b8e29a7f3d95d758182fcec1
This commit is contained in:
parent
05c510ff9c
commit
d2331a6823
2 changed files with 46 additions and 15 deletions
|
|
@ -41,6 +41,8 @@ class Category {
|
|||
const LOAD_ONLY = 0;
|
||||
const LAZY_INIT_ROW = 1;
|
||||
|
||||
const ROW_COUNT_SMALL = 100;
|
||||
|
||||
private function __construct() {
|
||||
}
|
||||
|
||||
|
|
@ -431,28 +433,57 @@ class Category {
|
|||
* @since 1.32
|
||||
*/
|
||||
public function refreshCountsIfEmpty() {
|
||||
return $this->refreshCountsIfSmall( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Call refreshCounts() if there are few entries in the categorylinks table
|
||||
*
|
||||
* Due to lock errors or other failures, the precomputed counts can get out of sync,
|
||||
* making it hard to know when to delete the category row without checking the
|
||||
* categorylinks table.
|
||||
*
|
||||
* This method will do a non-locking select first to reduce contention.
|
||||
*
|
||||
* @param int $maxSize Only refresh if there are this or less many backlinks
|
||||
* @return bool Whether links were refreshed
|
||||
* @since 1.34
|
||||
*/
|
||||
public function refreshCountsIfSmall( $maxSize = self::ROW_COUNT_SMALL ) {
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$dbw->startAtomic( __METHOD__ );
|
||||
|
||||
$hasLink = $dbw->selectField(
|
||||
$typeOccurances = $dbw->selectFieldValues(
|
||||
'categorylinks',
|
||||
'1',
|
||||
'cl_type',
|
||||
[ 'cl_to' => $this->getName() ],
|
||||
__METHOD__
|
||||
__METHOD__,
|
||||
[ 'LIMIT' => $maxSize + 1 ]
|
||||
);
|
||||
if ( !$hasLink ) {
|
||||
$this->refreshCounts(); // delete any category table entry
|
||||
|
||||
return true;
|
||||
if ( !$typeOccurances ) {
|
||||
$doRefresh = true; // delete any category table entry
|
||||
} elseif ( count( $typeOccurances ) <= $maxSize ) {
|
||||
$countByType = array_count_values( $typeOccurances );
|
||||
$doRefresh = !$dbw->selectField(
|
||||
'category',
|
||||
'1',
|
||||
[
|
||||
'cat_title' => $this->getName(),
|
||||
'cat_pages' => $countByType['page'] ?? 0,
|
||||
'cat_subcats' => $countByType['subcat'] ?? 0,
|
||||
'cat_files' => $countByType['file'] ?? 0
|
||||
],
|
||||
__METHOD__
|
||||
);
|
||||
} else {
|
||||
$doRefresh = false; // category is too big
|
||||
}
|
||||
|
||||
$hasBadRow = $dbw->selectField(
|
||||
'category',
|
||||
'1',
|
||||
[ 'cat_title' => $this->getName(), 'cat_pages <= 0' ],
|
||||
__METHOD__
|
||||
);
|
||||
if ( $hasBadRow ) {
|
||||
$this->refreshCounts(); // clean up this row
|
||||
$dbw->endAtomic( __METHOD__ );
|
||||
|
||||
if ( $doRefresh ) {
|
||||
$this->refreshCounts(); // update the row
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ class LinksDeletionUpdate extends LinksUpdate implements EnqueueableDataUpdate {
|
|||
// T166757: do the update after the main job DB commit
|
||||
DeferredUpdates::addCallableUpdate( function () use ( $title ) {
|
||||
$cat = Category::newFromName( $title->getDBkey() );
|
||||
$cat->refreshCountsIfEmpty();
|
||||
$cat->refreshCountsIfSmall();
|
||||
} );
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue