From: Brad Jorsch Date: Tue, 12 Jun 2018 15:28:25 +0000 (-0400) Subject: Category: Lock the category row before the categorylinks rows X-Git-Tag: 1.34.0-rc.0~5110 X-Git-Url: http://git.cyclocoop.org/data/%24oldEdit?a=commitdiff_plain;h=4aa09d47591337bf1da38fd3c8a11f58d872a33c;p=lhc%2Fweb%2Fwiklou.git Category: Lock the category row before the categorylinks rows We've noticed a large increase in deadlocks between LinksDeletionUpdate deleting categorylinks rows and Category::refreshCounts() trying to update the category table. My best guess as to what's going on there is that LinksDeletionUpdate locks the category row via the call to WikiPage::updateCategoryCounts() then the categorylinks rows via its own deletions, while Category first locks the categorylinks rows (in share mode) and then the category row when it tries to update or delete it. To break the deadlock, let's have Category do a SELECT FOR UPDATE on the category row first before it locks the categorylinks rows. Bug: T195397 Change-Id: Ie11baadf2ff0ba2afbc86b10bc523525c570a490 --- diff --git a/includes/Category.php b/includes/Category.php index 46b86d8cd8..2cf44b86f8 100644 --- a/includes/Category.php +++ b/includes/Category.php @@ -335,6 +335,16 @@ class Category { $dbw->startAtomic( __METHOD__ ); + // Lock the `category` row before locking `categorylinks` rows to try + // to avoid deadlocks with LinksDeletionUpdate (T195397) + $dbw->selectField( + 'category', + 1, + [ 'cat_title' => $this->mName ], + __METHOD__, + [ 'FOR UPDATE' ] + ); + // Lock all the `categorylinks` records and gaps for this category; // this is a separate query due to postgres/oracle limitations $dbw->selectRowCount(