From 3d4fc2b7a3af1161ae1886518a6244efec33fc0b Mon Sep 17 00:00:00 2001 From: Aaron Schulz Date: Fri, 3 Apr 2015 10:03:19 -0700 Subject: [PATCH] Cut down on deadlocks in invalidatePages() Bug: T94992 Change-Id: I70f9d931b624e46ccc19f890d61de8d11326e686 --- includes/deferred/SqlDataUpdate.php | 69 +++++++++++++++-------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/includes/deferred/SqlDataUpdate.php b/includes/deferred/SqlDataUpdate.php index 5823b2e56f..49164e3373 100644 --- a/includes/deferred/SqlDataUpdate.php +++ b/includes/deferred/SqlDataUpdate.php @@ -111,39 +111,40 @@ abstract class SqlDataUpdate extends DataUpdate { return; } - /** - * Determine which pages need to be updated - * This is necessary to prevent the job queue from smashing the DB with - * large numbers of concurrent invalidations of the same page - */ - $now = $this->mDb->timestamp(); - $ids = array(); - $res = $this->mDb->select( 'page', array( 'page_id' ), - array( - 'page_namespace' => $namespace, - 'page_title' => $dbkeys, - 'page_touched < ' . $this->mDb->addQuotes( $now ) - ), __METHOD__ - ); - - foreach ( $res as $row ) { - $ids[] = $row->page_id; - } - - if ( $ids === array() ) { - return; - } - - /** - * Do the update - * We still need the page_touched condition, in case the row has changed since - * the non-locking select above. - */ - $this->mDb->update( 'page', array( 'page_touched' => $now ), - array( - 'page_id' => $ids, - 'page_touched < ' . $this->mDb->addQuotes( $now ) - ), __METHOD__ - ); + $dbw = $this->mDb; + $dbw->onTransactionPreCommitOrIdle( function() use ( $dbw, $namespace, $dbkeys ) { + /** + * Determine which pages need to be updated + * This is necessary to prevent the job queue from smashing the DB with + * large numbers of concurrent invalidations of the same page + */ + $now = $dbw->timestamp(); + $ids = $dbw->selectFieldValues( 'page', + 'page_id', + array( + 'page_namespace' => $namespace, + 'page_title' => $dbkeys, + 'page_touched < ' . $dbw->addQuotes( $now ) + ), + __METHOD__ + ); + + if ( $ids === array() ) { + return; + } + + /** + * Do the update + * We still need the page_touched condition, in case the row has changed since + * the non-locking select above. + */ + $dbw->update( 'page', + array( 'page_touched' => $now ), + array( + 'page_id' => $ids, + 'page_touched < ' . $dbw->addQuotes( $now ) + ), __METHOD__ + ); + } ); } } -- 2.20.1