Commit 2771c6ec authored by Andreas Brandl's avatar Andreas Brandl

Merge branch 'tc-index-uploads-file-store-ee' into 'master'

EE port: Enhance performance of counting local Uploads

Closes #6070

See merge request gitlab-org/gitlab-ee!8144
parents a939dd1c 4d1dac8f
......@@ -13,7 +13,7 @@ class Upload < ActiveRecord::Base
validates :model, presence: true
validates :uploader, presence: true
scope :with_files_stored_locally, -> { where(store: [nil, ObjectStorage::Store::LOCAL]) }
scope :with_files_stored_locally, -> { where(store: ObjectStorage::Store::LOCAL) }
scope :with_files_stored_remotely, -> { where(store: ObjectStorage::Store::REMOTE) }
before_save :calculate_checksum!, if: :foreground_checksummable?
......@@ -71,8 +71,6 @@ class Upload < ActiveRecord::Base
end
def local?
return true if store.nil?
store == ObjectStorage::Store::LOCAL
end
......
---
title: Enhance performance of counting local Uploads
merge_request: 22522
author:
type: performance
# frozen_string_literal: true
class AddIndexToUploadsStore < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_concurrent_index :uploads, :store
end
def down
remove_concurrent_index :uploads, :store
end
end
# frozen_string_literal: true
class StealFillStoreUpload < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
BATCH_SIZE = 10_000
disable_ddl_transaction!
class Upload < ActiveRecord::Base
include EachBatch
self.table_name = 'uploads'
self.inheritance_column = :_type_disabled # Disable STI
end
def up
Gitlab::BackgroundMigration.steal('FillStoreUpload')
Upload.where(store: nil).each_batch(of: BATCH_SIZE) do |batch|
range = batch.pluck('MIN(id)', 'MAX(id)').first
Gitlab::BackgroundMigration::FillStoreUpload.new.perform(*range)
end
end
def down
# noop
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20181101144347) do
ActiveRecord::Schema.define(version: 20181105201455) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -2870,6 +2870,7 @@ ActiveRecord::Schema.define(version: 20181101144347) do
add_index "uploads", ["checksum"], name: "index_uploads_on_checksum", using: :btree
add_index "uploads", ["model_id", "model_type"], name: "index_uploads_on_model_id_and_model_type", using: :btree
add_index "uploads", ["store"], name: "index_uploads_on_store", using: :btree
add_index "uploads", ["uploader", "path"], name: "index_uploads_on_uploader_and_path", using: :btree
create_table "user_agent_details", force: :cascade do |t|
......
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20181105201455_steal_fill_store_upload.rb')
describe StealFillStoreUpload, :migration do
let(:uploads) { table(:uploads) }
describe '#up' do
it 'steals the FillStoreUpload background migration' do
expect(Gitlab::BackgroundMigration).to receive(:steal).with('FillStoreUpload').and_call_original
migrate!
end
it 'does not run migration if not needed' do
uploads.create(size: 100.kilobytes,
uploader: 'AvatarUploader',
path: 'uploads/-/system/avatar.jpg',
store: 1)
expect_any_instance_of(Gitlab::BackgroundMigration::FillStoreUpload).not_to receive(:perform)
migrate!
end
it 'ensures all rows are migrated' do
uploads.create(size: 100.kilobytes,
uploader: 'AvatarUploader',
path: 'uploads/-/system/avatar.jpg',
store: nil)
expect_any_instance_of(Gitlab::BackgroundMigration::FillStoreUpload).to receive(:perform).and_call_original
expect do
migrate!
end.to change { uploads.where(store: nil).count }.from(1).to(0)
end
end
end
......@@ -21,7 +21,8 @@ describe Upload do
path: __FILE__,
size: described_class::CHECKSUM_THRESHOLD + 1.kilobyte,
model: build_stubbed(:user),
uploader: double('ExampleUploader')
uploader: double('ExampleUploader'),
store: ObjectStorage::Store::LOCAL
)
expect(UploadChecksumWorker)
......@@ -35,7 +36,8 @@ describe Upload do
path: __FILE__,
size: described_class::CHECKSUM_THRESHOLD,
model: build_stubbed(:user),
uploader: double('ExampleUploader')
uploader: double('ExampleUploader'),
store: ObjectStorage::Store::LOCAL
)
expect { upload.save }
......@@ -60,7 +62,7 @@ describe Upload do
describe '#absolute_path' do
it 'returns the path directly when already absolute' do
path = '/path/to/namespace/project/secret/file.jpg'
upload = described_class.new(path: path)
upload = described_class.new(path: path, store: ObjectStorage::Store::LOCAL)
expect(upload).not_to receive(:uploader_class)
......@@ -69,7 +71,7 @@ describe Upload do
it "delegates to the uploader's absolute_path method" do
uploader = spy('FakeUploader')
upload = described_class.new(path: 'secret/file.jpg')
upload = described_class.new(path: 'secret/file.jpg', store: ObjectStorage::Store::LOCAL)
expect(upload).to receive(:uploader_class).and_return(uploader)
upload.absolute_path
......@@ -81,7 +83,8 @@ describe Upload do
describe '#calculate_checksum!' do
let(:upload) do
described_class.new(path: __FILE__,
size: described_class::CHECKSUM_THRESHOLD - 1.megabyte)
size: described_class::CHECKSUM_THRESHOLD - 1.megabyte,
store: ObjectStorage::Store::LOCAL)
end
it 'sets `checksum` to SHA256 sum of the file' do
......@@ -104,14 +107,14 @@ describe Upload do
describe '#exist?' do
it 'returns true when the file exists' do
upload = described_class.new(path: __FILE__)
upload = described_class.new(path: __FILE__, store: ObjectStorage::Store::LOCAL)
expect(upload).to exist
end
context 'when the file does not exist' do
it 'returns false' do
upload = described_class.new(path: "#{__FILE__}-nope")
upload = described_class.new(path: "#{__FILE__}-nope", store: ObjectStorage::Store::LOCAL)
expect(upload).not_to exist
end
......@@ -139,7 +142,7 @@ describe Upload do
context 'when the record is not persisted' do
it 'does not send a message to Sentry' do
upload = described_class.new(path: "#{__FILE__}-nope")
upload = described_class.new(path: "#{__FILE__}-nope", store: ObjectStorage::Store::LOCAL)
expect(Raven).not_to receive(:capture_message)
......@@ -147,7 +150,7 @@ describe Upload do
end
it 'does not increment a metric counter' do
upload = described_class.new(path: "#{__FILE__}-nope")
upload = described_class.new(path: "#{__FILE__}-nope", store: ObjectStorage::Store::LOCAL)
expect(Gitlab::Metrics).not_to receive(:counter)
......
......@@ -38,14 +38,6 @@ describe 'gitlab:uploads:migrate rake tasks' do
let!(:projects) { create_list(:project, 10, :with_avatar) }
it_behaves_like 'enqueue jobs in batch', batch: 4
context 'Upload has store = nil' do
before do
Upload.where(model: projects).update_all(store: nil)
end
it_behaves_like 'enqueue jobs in batch', batch: 4
end
end
context "for Group" do
......
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