Skip to content

Repeated SELECT query with ProtectedBranch.protected? in GitAccess

This relates to https://gitlab.com/gitlab-org/gitlab-ee/issues/6465, but for some reason doesn't seem to be causing as much of a performance issue as the LFS and path lock checks.

In git_access.rb, we call:

      changes_list = Gitlab::ChangesList.new(changes)

      # Iterate over all changes to find if user allowed all of them to be applied
      changes_list.each.with_index do |change, index|
        first_change = index == 0

        # If user does not have access to make at least one change, cancel all
        # push by allowing the exception to bubble up
        check_single_change_access(change, skip_lfs_integrity_check: !first_change)
      end

This calls ChangeAccess#protected_branch_checks:

      def protected_branch_checks
        return unless ProtectedBranch.protected?(project, branch_name)

As mentioned in https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/19978/diffs, there is an N query here:

  def self.protected?(project, ref_name)
    return true if project.empty_repo? && default_branch_protected?

    refs = project.protected_branches.select(:name)  # This calls a SELECT every time

You can uncomment the with_threshold(1) in the test case to see this.