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
$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(