From b3f258c360a35ef0697cf7a5d8bdc3c0ef99c48d Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Tue, 10 Apr 2018 10:39:22 -0400 Subject: [PATCH] WikiPage: Avoid locking comment and actor tables in doDeleteArticleReal The existing code was using FOR UPDATE when selecting the revision table rows to be added to the archive table, which meant it was locking not only `revision`, `revision_comment_temp`, and `revision_actor_temp` that are being updated but also `comment` and `actor` that we have no intention of touching. And since those both are intended to be widely shared, that's likely to lead to unnecessary lock contention. To avoid that, we make two queries: one against only the rows we want to lock with FOR UPDATE, and the second to actually fetch the data without FOR UPDATE. Bug: T191892 Change-Id: I40ecf1786249c886a5ff25f29ec01edee3ff205d --- includes/page/WikiPage.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/includes/page/WikiPage.php b/includes/page/WikiPage.php index f45036c1db..f3860c63f5 100644 --- a/includes/page/WikiPage.php +++ b/includes/page/WikiPage.php @@ -2871,13 +2871,32 @@ class WikiPage implements Page, IDBAccessObject { // In the future, we may keep revisions and mark them with // the rev_deleted field, which is reserved for this purpose. + // Lock rows in `revision` and its temp tables, but not any others. + // Note array_intersect() preserves keys from the first arg, and we're + // assuming $revQuery has `revision` primary and isn't using subtables + // for anything we care about. + $res = $dbw->select( + array_intersect( + $revQuery['tables'], + [ 'revision', 'revision_comment_temp', 'revision_actor_temp' ] + ), + '1', + [ 'rev_page' => $id ], + __METHOD__, + 'FOR UPDATE', + $revQuery['joins'] + ); + foreach ( $res as $row ) { + // Fetch all rows in case the DB needs that to properly lock them. + } + // Get all of the page revisions $res = $dbw->select( $revQuery['tables'], $revQuery['fields'], [ 'rev_page' => $id ], __METHOD__, - 'FOR UPDATE', + [], $revQuery['joins'] ); -- 2.20.1