Commit ad04490c authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch '213382-use-not-valid-to-immediately-enforce-a-not-null-constraint' into 'master'

Use NOT VALID to enforce a not null constraint on file store columns

See merge request gitlab-org/gitlab!31261
parents 3734e1e7 f57a706c
---
title: Use NOT VALID to enforce a not null constraint on file store columns
merge_request: 31261
author:
type: performance
# frozen_string_literal: true
class FillFileStoreLfsObjects < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
update_column_in_batches(:lfs_objects, :file_store, 1) do |table, query|
query.where(table[:file_store].eq(nil))
end
end
def down
# no-op
end
end
# frozen_string_literal: true
class FillStoreUploads < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
update_column_in_batches(:uploads, :store, 1) do |table, query|
query.where(table[:store].eq(nil))
end
end
def down
# no-op
end
end
# frozen_string_literal: true
class FillFileStoreCiJobArtifacts < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
# rubocop:disable Migration/UpdateLargeTable
update_column_in_batches(:ci_job_artifacts, :file_store, 1) do |table, query|
query.where(table[:file_store].eq(nil))
end
# rubocop:enable Migration/UpdateLargeTable
end
def down
# no-op
end
end
# frozen_string_literal: true
class AddNotNullConstraintOnFileStoreToLfsObjects < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_not_null_constraint(:lfs_objects, :file_store, validate: false)
end
def down
remove_not_null_constraint(:lfs_objects, :file_store)
end
end
# frozen_string_literal: true
class AddNotNullConstraintOnStoreToUploads < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_not_null_constraint(:uploads, :store, validate: false)
end
def down
remove_not_null_constraint(:uploads, :store)
end
end
# frozen_string_literal: true
class AddNotNullConstraintOnFileStoreToCiJobsArtifacts < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_not_null_constraint(:ci_job_artifacts, :file_store, validate: false)
end
def down
remove_not_null_constraint(:ci_job_artifacts, :file_store)
end
end
......@@ -7995,6 +7995,15 @@ ALTER TABLE ONLY public.chat_names
ALTER TABLE ONLY public.chat_teams
ADD CONSTRAINT chat_teams_pkey PRIMARY KEY (id);
ALTER TABLE public.ci_job_artifacts
ADD CONSTRAINT check_27f0f6dbab CHECK ((file_store IS NOT NULL)) NOT VALID;
ALTER TABLE public.uploads
ADD CONSTRAINT check_5e9547379c CHECK ((store IS NOT NULL)) NOT VALID;
ALTER TABLE public.lfs_objects
ADD CONSTRAINT check_eecfc5717d CHECK ((file_store IS NOT NULL)) NOT VALID;
ALTER TABLE ONLY public.ci_build_needs
ADD CONSTRAINT ci_build_needs_pkey PRIMARY KEY (id);
......@@ -13795,5 +13804,11 @@ COPY "schema_migrations" (version) FROM STDIN;
20200511162057
20200511162115
20200512085150
20200513234502
20200513235347
20200513235532
20200514000009
20200514000132
20200514000340
\.
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'migrate', '20200513235532_fill_file_store_ci_job_artifacts.rb')
describe FillFileStoreCiJobArtifacts do
let(:namespaces) { table(:namespaces) }
let(:projects) { table(:projects) }
let(:builds) { table(:ci_builds) }
let(:job_artifacts) { table(:ci_job_artifacts) }
before do
namespaces.create!(id: 123, name: 'sample', path: 'sample')
projects.create!(id: 123, name: 'sample', path: 'sample', namespace_id: 123)
builds.create!(id: 1)
end
context 'when file_store is nil' do
it 'updates file_store to local' do
job_artifacts.create!(project_id: 123, job_id: 1, file_type: 1, file_store: nil)
job_artifact = job_artifacts.find_by(project_id: 123, job_id: 1)
expect { migrate! }.to change { job_artifact.reload.file_store }.from(nil).to(1)
end
end
context 'when file_store is set to local' do
it 'does not update file_store' do
job_artifacts.create!(project_id: 123, job_id: 1, file_type: 1, file_store: 1)
job_artifact = job_artifacts.find_by(project_id: 123, job_id: 1)
expect { migrate! }.not_to change { job_artifact.reload.file_store }
end
end
context 'when file_store is set to object storage' do
it 'does not update file_store' do
job_artifacts.create!(project_id: 123, job_id: 1, file_type: 1, file_store: 2)
job_artifact = job_artifacts.find_by(project_id: 123, job_id: 1)
expect { migrate! }.not_to change { job_artifact.reload.file_store }
end
end
end
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'migrate', '20200513234502_fill_file_store_lfs_objects.rb')
describe FillFileStoreLfsObjects do
let(:lfs_objects) { table(:lfs_objects) }
let(:oid) { 'b804383982bb89b00e828e3f44c038cc991d3d1768009fc39ba8e2c081b9fb75' }
context 'when file_store is nil' do
it 'updates file_store to local' do
lfs_objects.create(oid: oid, size: 1062, file_store: nil)
lfs_object = lfs_objects.find_by(oid: oid)
expect { migrate! }.to change { lfs_object.reload.file_store }.from(nil).to(1)
end
end
context 'when file_store is set to local' do
it 'does not update file_store' do
lfs_objects.create(oid: oid, size: 1062, file_store: 1)
lfs_object = lfs_objects.find_by(oid: oid)
expect { migrate! }.not_to change { lfs_object.reload.file_store }
end
end
context 'when file_store is set to object storage' do
it 'does not update file_store' do
lfs_objects.create(oid: oid, size: 1062, file_store: 2)
lfs_object = lfs_objects.find_by(oid: oid)
expect { migrate! }.not_to change { lfs_object.reload.file_store }
end
end
end
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'migrate', '20200513235347_fill_store_uploads.rb')
describe FillStoreUploads do
let(:uploads) { table(:uploads) }
let(:path) { 'uploads/-/system/avatar.jpg' }
context 'when store is nil' do
it 'updates store to local' do
uploads.create(size: 100.kilobytes,
uploader: 'AvatarUploader',
path: path,
store: nil)
upload = uploads.find_by(path: path)
expect { migrate! }.to change { upload.reload.store }.from(nil).to(1)
end
end
context 'when store is set to local' do
it 'does not update store' do
uploads.create(size: 100.kilobytes,
uploader: 'AvatarUploader',
path: path,
store: 1)
upload = uploads.find_by(path: path)
expect { migrate! }.not_to change { upload.reload.store }
end
end
context 'when store is set to object storage' do
it 'does not update store' do
uploads.create(size: 100.kilobytes,
uploader: 'AvatarUploader',
path: path,
store: 2)
upload = uploads.find_by(path: path)
expect { migrate! }.not_to change { upload.reload.store }
end
end
end
......@@ -378,19 +378,6 @@ describe Ci::JobArtifact do
describe 'file is being stored' do
subject { create(:ci_job_artifact, :archive) }
context 'when object has nil store' do
before do
subject.update_column(:file_store, nil)
subject.reload
end
it 'is stored locally' do
expect(subject.file_store).to be(nil)
expect(subject.file).to be_file_storage
expect(subject.file.object_store).to eq(ObjectStorage::Store::LOCAL)
end
end
context 'when existing object has local store' do
it 'is stored locally' do
expect(subject.file_store).to be(ObjectStorage::Store::LOCAL)
......
......@@ -22,18 +22,6 @@ describe 'gitlab:artifacts namespace rake task' do
context 'when local storage is used' do
let(:store) { ObjectStorage::Store::LOCAL }
context 'and job does not have file store defined' do
let(:object_storage_enabled) { true }
let(:store) { nil }
it "migrates file to remote storage" do
subject
expect(artifact.reload.file_store).to eq(ObjectStorage::Store::REMOTE)
expect(job_trace.reload.file_store).to eq(ObjectStorage::Store::REMOTE)
end
end
context 'and remote storage is defined' do
let(:object_storage_enabled) { true }
......
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