Commit f0527376 authored by Stan Hu's avatar Stan Hu Committed by Heinrich Lee Yu

Reduce idle in transaction time when updating MRs

`MergeRequestDiff#save_git_content` can take a while to compute and save
the diffs, and it can hold a transaction in idle for a long time when it
attempts to update the latest `latest_merge_request_diff_id`.

To prevent this, we first generate the diff and only after this
completes do we update the diff ID.

Closes https://gitlab.com/gitlab-org/gitlab/issues/33650
parent f0d315a8
...@@ -136,6 +136,7 @@ class MergeRequestDiff < ApplicationRecord ...@@ -136,6 +136,7 @@ class MergeRequestDiff < ApplicationRecord
# All diff information is collected from repository after object is created. # All diff information is collected from repository after object is created.
# It allows you to override variables like head_commit_sha before getting diff. # It allows you to override variables like head_commit_sha before getting diff.
after_create :save_git_content, unless: :importing? after_create :save_git_content, unless: :importing?
after_create_commit :set_as_latest_diff, unless: :importing?
after_save :update_external_diff_store, if: -> { !importing? && saved_change_to_external_diff? } after_save :update_external_diff_store, if: -> { !importing? && saved_change_to_external_diff? }
...@@ -150,10 +151,6 @@ class MergeRequestDiff < ApplicationRecord ...@@ -150,10 +151,6 @@ class MergeRequestDiff < ApplicationRecord
# Collect information about commits and diff from repository # Collect information about commits and diff from repository
# and save it to the database as serialized data # and save it to the database as serialized data
def save_git_content def save_git_content
MergeRequest
.where('id = ? AND COALESCE(latest_merge_request_diff_id, 0) < ?', self.merge_request_id, self.id)
.update_all(latest_merge_request_diff_id: self.id)
ensure_commit_shas ensure_commit_shas
save_commits save_commits
save_diffs save_diffs
...@@ -168,6 +165,12 @@ class MergeRequestDiff < ApplicationRecord ...@@ -168,6 +165,12 @@ class MergeRequestDiff < ApplicationRecord
keep_around_commits keep_around_commits
end end
def set_as_latest_diff
MergeRequest
.where('id = ? AND COALESCE(latest_merge_request_diff_id, 0) < ?', self.merge_request_id, self.id)
.update_all(latest_merge_request_diff_id: self.id)
end
def ensure_commit_shas def ensure_commit_shas
self.start_commit_sha ||= merge_request.target_branch_sha self.start_commit_sha ||= merge_request.target_branch_sha
self.head_commit_sha ||= merge_request.source_branch_sha self.head_commit_sha ||= merge_request.source_branch_sha
......
---
title: Reduce idle in transaction time when updating a merge request
merge_request: 18493
author:
type: performance
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment