Fix bug in BacklinkCache: the lack of an ORDER BY clause in getLinks(), combined with the lack of sensible indexes on the categorylinks table, was causing partition() to return starts and ends scaterred randomly across the result set. For large jobs, many partitions end up being large, causing HTMLCacheUpdate::doPartialUpdate() to repartition, thus requeueing jobs in an infinite recursive loop.
The BacklinkCache bug was there since r47317, but was relatively harmless until r54841 introduced the infinite loop issue.
This commit is contained in:
parent
cee6cff6f6
commit
1eae9941d9
2 changed files with 17 additions and 3 deletions
|
|
@ -661,6 +661,8 @@ Hopefully we will remove this configuration var soon)
|
|||
* (bug 18762) both redirects and links get fixed one after another if
|
||||
redirects-only switch is not present
|
||||
* (bug 20159) thumbnails rerendered if older that $wgThumbnailEpoch
|
||||
* Fixed a bug which in some situations causes the job queue to grow forever,
|
||||
due to an infinite loop of job requeues.
|
||||
|
||||
== API changes in 1.16 ==
|
||||
|
||||
|
|
|
|||
|
|
@ -53,13 +53,13 @@ class BacklinkCache {
|
|||
public function getLinks( $table, $startId = false, $endId = false ) {
|
||||
wfProfileIn( __METHOD__ );
|
||||
|
||||
$fromField = $this->getPrefix( $table ) . '_from';
|
||||
if ( $startId || $endId ) {
|
||||
// Partial range, not cached
|
||||
wfDebug( __METHOD__.": from DB (uncacheable range)\n" );
|
||||
$conds = $this->getConditions( $table );
|
||||
// Use the from field in the condition rather than the joined page_id,
|
||||
// because databases are stupid and don't necessarily propagate indexes.
|
||||
$fromField = $this->getPrefix( $table ) . '_from';
|
||||
if ( $startId ) {
|
||||
$conds[] = "$fromField >= " . intval( $startId );
|
||||
}
|
||||
|
|
@ -71,7 +71,10 @@ class BacklinkCache {
|
|||
array( 'page_namespace', 'page_title', 'page_id'),
|
||||
$conds,
|
||||
__METHOD__,
|
||||
array('STRAIGHT_JOIN') );
|
||||
array(
|
||||
'STRAIGHT_JOIN',
|
||||
'ORDER BY' => $fromField
|
||||
) );
|
||||
$ta = TitleArray::newFromResult( $res );
|
||||
wfProfileOut( __METHOD__ );
|
||||
return $ta;
|
||||
|
|
@ -84,7 +87,10 @@ class BacklinkCache {
|
|||
array( 'page_namespace', 'page_title', 'page_id' ),
|
||||
$this->getConditions( $table ),
|
||||
__METHOD__,
|
||||
array('STRAIGHT_JOIN') );
|
||||
array(
|
||||
'STRAIGHT_JOIN',
|
||||
'ORDER BY' => $fromField,
|
||||
) );
|
||||
$this->fullResultCache[$table] = $res;
|
||||
}
|
||||
$ta = TitleArray::newFromResult( $this->fullResultCache[$table] );
|
||||
|
|
@ -225,6 +231,12 @@ class BacklinkCache {
|
|||
$row = $res->fetchObject();
|
||||
$end = $row->page_id - 1;
|
||||
}
|
||||
|
||||
# Sanity check order
|
||||
if ( $start && $end && $start > $end ) {
|
||||
throw new MWException( __METHOD__.': Internal error: query result out of order' );
|
||||
}
|
||||
|
||||
$batches[] = array( $start, $end );
|
||||
}
|
||||
return array( 'numRows' => $numRows, 'batches' => $batches );
|
||||
|
|
|
|||
Loading…
Reference in a new issue