Commit 7db9dce1 authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch '241980-uploads-count-as-used-storage' into 'master'

Account for uploaded files in storage statistics

See merge request gitlab-org/gitlab!46941
parents 8f7a2123 4cf3b6d1
...@@ -96,7 +96,8 @@ class Namespace < ApplicationRecord ...@@ -96,7 +96,8 @@ class Namespace < ApplicationRecord
'COALESCE(SUM(ps.snippets_size), 0) AS snippets_size', 'COALESCE(SUM(ps.snippets_size), 0) AS snippets_size',
'COALESCE(SUM(ps.lfs_objects_size), 0) AS lfs_objects_size', 'COALESCE(SUM(ps.lfs_objects_size), 0) AS lfs_objects_size',
'COALESCE(SUM(ps.build_artifacts_size), 0) AS build_artifacts_size', 'COALESCE(SUM(ps.build_artifacts_size), 0) AS build_artifacts_size',
'COALESCE(SUM(ps.packages_size), 0) AS packages_size' 'COALESCE(SUM(ps.packages_size), 0) AS packages_size',
'COALESCE(SUM(ps.uploads_size), 0) AS uploads_size'
) )
end end
......
...@@ -11,6 +11,7 @@ class Namespace::RootStorageStatistics < ApplicationRecord ...@@ -11,6 +11,7 @@ class Namespace::RootStorageStatistics < ApplicationRecord
packages_size packages_size
#{SNIPPETS_SIZE_STAT_NAME} #{SNIPPETS_SIZE_STAT_NAME}
pipeline_artifacts_size pipeline_artifacts_size
uploads_size
).freeze ).freeze
self.primary_key = :namespace_id self.primary_key = :namespace_id
...@@ -50,7 +51,8 @@ class Namespace::RootStorageStatistics < ApplicationRecord ...@@ -50,7 +51,8 @@ class Namespace::RootStorageStatistics < ApplicationRecord
'COALESCE(SUM(ps.build_artifacts_size), 0) AS build_artifacts_size', 'COALESCE(SUM(ps.build_artifacts_size), 0) AS build_artifacts_size',
'COALESCE(SUM(ps.packages_size), 0) AS packages_size', 'COALESCE(SUM(ps.packages_size), 0) AS packages_size',
"COALESCE(SUM(ps.snippets_size), 0) AS #{SNIPPETS_SIZE_STAT_NAME}", "COALESCE(SUM(ps.snippets_size), 0) AS #{SNIPPETS_SIZE_STAT_NAME}",
'COALESCE(SUM(ps.pipeline_artifacts_size), 0) AS pipeline_artifacts_size' 'COALESCE(SUM(ps.pipeline_artifacts_size), 0) AS pipeline_artifacts_size',
'COALESCE(SUM(ps.uploads_size), 0) AS uploads_size'
) )
end end
......
...@@ -19,14 +19,14 @@ class ProjectStatistics < ApplicationRecord ...@@ -19,14 +19,14 @@ class ProjectStatistics < ApplicationRecord
before_save :update_storage_size before_save :update_storage_size
COLUMNS_TO_REFRESH = [:repository_size, :wiki_size, :lfs_objects_size, :commit_count, :snippets_size].freeze COLUMNS_TO_REFRESH = [:repository_size, :wiki_size, :lfs_objects_size, :commit_count, :snippets_size, :uploads_size].freeze
INCREMENTABLE_COLUMNS = { INCREMENTABLE_COLUMNS = {
build_artifacts_size: %i[storage_size], build_artifacts_size: %i[storage_size],
packages_size: %i[storage_size], packages_size: %i[storage_size],
pipeline_artifacts_size: %i[storage_size], pipeline_artifacts_size: %i[storage_size],
snippets_size: %i[storage_size] snippets_size: %i[storage_size]
}.freeze }.freeze
NAMESPACE_RELATABLE_COLUMNS = [:repository_size, :wiki_size, :lfs_objects_size].freeze NAMESPACE_RELATABLE_COLUMNS = [:repository_size, :wiki_size, :lfs_objects_size, :uploads_size].freeze
scope :for_project_ids, ->(project_ids) { where(project_id: project_ids) } scope :for_project_ids, ->(project_ids) { where(project_id: project_ids) }
...@@ -72,6 +72,12 @@ class ProjectStatistics < ApplicationRecord ...@@ -72,6 +72,12 @@ class ProjectStatistics < ApplicationRecord
self.lfs_objects_size = project.lfs_objects.sum(:size) self.lfs_objects_size = project.lfs_objects.sum(:size)
end end
def update_uploads_size
return uploads_size unless Feature.enabled?(:count_uploads_size_in_storage_stats, project)
self.uploads_size = project.uploads.sum(:size)
end
# `wiki_size` and `snippets_size` have no default value in the database # `wiki_size` and `snippets_size` have no default value in the database
# and the column can be nil. # and the column can be nil.
# This means that, when the columns were added, all rows had nil # This means that, when the columns were added, all rows had nil
...@@ -98,6 +104,10 @@ class ProjectStatistics < ApplicationRecord ...@@ -98,6 +104,10 @@ class ProjectStatistics < ApplicationRecord
# might try to update project statistics before the `pipeline_artifacts_size` column has been created. # might try to update project statistics before the `pipeline_artifacts_size` column has been created.
storage_size += pipeline_artifacts_size if self.class.column_names.include?('pipeline_artifacts_size') storage_size += pipeline_artifacts_size if self.class.column_names.include?('pipeline_artifacts_size')
# The `uploads_size` column was added on 20201105021637 but db/post_migrate/20190527194900_schedule_calculate_wiki_sizes.rb
# might try to update project statistics before the `uploads_size` column has been created.
storage_size += uploads_size if self.class.column_names.include?('uploads_size')
self.storage_size = storage_size self.storage_size = storage_size
end end
......
---
title: Account for uploads as part of used repository storage
merge_request: 46941
author:
type: added
---
name: count_uploads_size_in_storage_stats
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46941
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/281950
milestone: '13.6'
type: development
group: group::project management
default_enabled: false
# frozen_string_literal: true
class AddUploadsSizeToProjectStatistics < ActiveRecord::Migration[6.0]
DOWNTIME = false
def up
add_column :project_statistics, :uploads_size, :bigint, default: 0, null: false
end
def down
remove_column :project_statistics, :uploads_size
end
end
# frozen_string_literal: true
class AddUploadsSizeToNamespaceRootStorageStatistics < ActiveRecord::Migration[6.0]
DOWNTIME = false
def up
add_column :namespace_root_storage_statistics, :uploads_size, :bigint, default: 0, null: false
end
def down
remove_column :namespace_root_storage_statistics, :uploads_size
end
end
b04e37c8713a333afbff4c7034d9f3ffca4a4490d0b563b73d9e6bffd45f3f6a
\ No newline at end of file
afeff8d6bf5ca14f955f5d387e8d219e852e9617b80fe07ed2e1b57af19fd4fa
\ No newline at end of file
...@@ -13876,7 +13876,8 @@ CREATE TABLE namespace_root_storage_statistics ( ...@@ -13876,7 +13876,8 @@ CREATE TABLE namespace_root_storage_statistics (
storage_size bigint DEFAULT 0 NOT NULL, storage_size bigint DEFAULT 0 NOT NULL,
packages_size bigint DEFAULT 0 NOT NULL, packages_size bigint DEFAULT 0 NOT NULL,
snippets_size bigint DEFAULT 0 NOT NULL, snippets_size bigint DEFAULT 0 NOT NULL,
pipeline_artifacts_size bigint DEFAULT 0 NOT NULL pipeline_artifacts_size bigint DEFAULT 0 NOT NULL,
uploads_size bigint DEFAULT 0 NOT NULL
); );
CREATE TABLE namespace_settings ( CREATE TABLE namespace_settings (
...@@ -15260,7 +15261,8 @@ CREATE TABLE project_statistics ( ...@@ -15260,7 +15261,8 @@ CREATE TABLE project_statistics (
packages_size bigint DEFAULT 0 NOT NULL, packages_size bigint DEFAULT 0 NOT NULL,
wiki_size bigint, wiki_size bigint,
snippets_size bigint, snippets_size bigint,
pipeline_artifacts_size bigint DEFAULT 0 NOT NULL pipeline_artifacts_size bigint DEFAULT 0 NOT NULL,
uploads_size bigint DEFAULT 0 NOT NULL
); );
CREATE SEQUENCE project_statistics_id_seq CREATE SEQUENCE project_statistics_id_seq
......
...@@ -23,6 +23,7 @@ FactoryBot.define do ...@@ -23,6 +23,7 @@ FactoryBot.define do
project_statistics.packages_size = evaluator.size_multiplier * 5 project_statistics.packages_size = evaluator.size_multiplier * 5
project_statistics.snippets_size = evaluator.size_multiplier * 6 project_statistics.snippets_size = evaluator.size_multiplier * 6
project_statistics.pipeline_artifacts_size = evaluator.size_multiplier * 7 project_statistics.pipeline_artifacts_size = evaluator.size_multiplier * 7
project_statistics.uploads_size = evaluator.size_multiplier * 8
end end
end end
end end
......
...@@ -45,6 +45,7 @@ RSpec.describe Namespace::RootStorageStatistics, type: :model do ...@@ -45,6 +45,7 @@ RSpec.describe Namespace::RootStorageStatistics, type: :model do
total_storage_size = stat1.storage_size + stat2.storage_size total_storage_size = stat1.storage_size + stat2.storage_size
total_snippets_size = stat1.snippets_size + stat2.snippets_size total_snippets_size = stat1.snippets_size + stat2.snippets_size
total_pipeline_artifacts_size = stat1.pipeline_artifacts_size + stat2.pipeline_artifacts_size total_pipeline_artifacts_size = stat1.pipeline_artifacts_size + stat2.pipeline_artifacts_size
total_uploads_size = stat1.uploads_size + stat2.uploads_size
expect(root_storage_statistics.repository_size).to eq(total_repository_size) expect(root_storage_statistics.repository_size).to eq(total_repository_size)
expect(root_storage_statistics.wiki_size).to eq(total_wiki_size) expect(root_storage_statistics.wiki_size).to eq(total_wiki_size)
...@@ -54,6 +55,7 @@ RSpec.describe Namespace::RootStorageStatistics, type: :model do ...@@ -54,6 +55,7 @@ RSpec.describe Namespace::RootStorageStatistics, type: :model do
expect(root_storage_statistics.storage_size).to eq(total_storage_size) expect(root_storage_statistics.storage_size).to eq(total_storage_size)
expect(root_storage_statistics.snippets_size).to eq(total_snippets_size) expect(root_storage_statistics.snippets_size).to eq(total_snippets_size)
expect(root_storage_statistics.pipeline_artifacts_size).to eq(total_pipeline_artifacts_size) expect(root_storage_statistics.pipeline_artifacts_size).to eq(total_pipeline_artifacts_size)
expect(root_storage_statistics.uploads_size).to eq(total_uploads_size)
end end
it 'works when there are no projects' do it 'works when there are no projects' do
......
...@@ -34,7 +34,8 @@ RSpec.describe ProjectStatistics do ...@@ -34,7 +34,8 @@ RSpec.describe ProjectStatistics do
lfs_objects_size: 2.exabytes, lfs_objects_size: 2.exabytes,
build_artifacts_size: 1.exabyte, build_artifacts_size: 1.exabyte,
snippets_size: 1.exabyte, snippets_size: 1.exabyte,
pipeline_artifacts_size: 1.exabyte - 1 pipeline_artifacts_size: 512.petabytes - 1,
uploads_size: 512.petabytes
) )
statistics.reload statistics.reload
...@@ -46,7 +47,8 @@ RSpec.describe ProjectStatistics do ...@@ -46,7 +47,8 @@ RSpec.describe ProjectStatistics do
expect(statistics.build_artifacts_size).to eq(1.exabyte) expect(statistics.build_artifacts_size).to eq(1.exabyte)
expect(statistics.storage_size).to eq(8.exabytes - 1) expect(statistics.storage_size).to eq(8.exabytes - 1)
expect(statistics.snippets_size).to eq(1.exabyte) expect(statistics.snippets_size).to eq(1.exabyte)
expect(statistics.pipeline_artifacts_size).to eq(1.exabyte - 1) expect(statistics.pipeline_artifacts_size).to eq(512.petabytes - 1)
expect(statistics.uploads_size).to eq(512.petabytes)
end end
end end
...@@ -57,6 +59,7 @@ RSpec.describe ProjectStatistics do ...@@ -57,6 +59,7 @@ RSpec.describe ProjectStatistics do
statistics.lfs_objects_size = 3 statistics.lfs_objects_size = 3
statistics.build_artifacts_size = 4 statistics.build_artifacts_size = 4
statistics.snippets_size = 5 statistics.snippets_size = 5
statistics.uploads_size = 3
expect(statistics.total_repository_size).to eq 5 expect(statistics.total_repository_size).to eq 5
end end
...@@ -98,6 +101,7 @@ RSpec.describe ProjectStatistics do ...@@ -98,6 +101,7 @@ RSpec.describe ProjectStatistics do
allow(statistics).to receive(:update_lfs_objects_size) allow(statistics).to receive(:update_lfs_objects_size)
allow(statistics).to receive(:update_snippets_size) allow(statistics).to receive(:update_snippets_size)
allow(statistics).to receive(:update_storage_size) allow(statistics).to receive(:update_storage_size)
allow(statistics).to receive(:update_uploads_size)
end end
context "without arguments" do context "without arguments" do
...@@ -111,6 +115,7 @@ RSpec.describe ProjectStatistics do ...@@ -111,6 +115,7 @@ RSpec.describe ProjectStatistics do
expect(statistics).to have_received(:update_wiki_size) expect(statistics).to have_received(:update_wiki_size)
expect(statistics).to have_received(:update_lfs_objects_size) expect(statistics).to have_received(:update_lfs_objects_size)
expect(statistics).to have_received(:update_snippets_size) expect(statistics).to have_received(:update_snippets_size)
expect(statistics).to have_received(:update_uploads_size)
end end
end end
...@@ -125,6 +130,7 @@ RSpec.describe ProjectStatistics do ...@@ -125,6 +130,7 @@ RSpec.describe ProjectStatistics do
expect(statistics).not_to have_received(:update_repository_size) expect(statistics).not_to have_received(:update_repository_size)
expect(statistics).not_to have_received(:update_wiki_size) expect(statistics).not_to have_received(:update_wiki_size)
expect(statistics).not_to have_received(:update_snippets_size) expect(statistics).not_to have_received(:update_snippets_size)
expect(statistics).not_to have_received(:update_uploads_size)
end end
end end
...@@ -139,10 +145,12 @@ RSpec.describe ProjectStatistics do ...@@ -139,10 +145,12 @@ RSpec.describe ProjectStatistics do
expect(statistics).to have_received(:update_repository_size) expect(statistics).to have_received(:update_repository_size)
expect(statistics).to have_received(:update_wiki_size) expect(statistics).to have_received(:update_wiki_size)
expect(statistics).to have_received(:update_snippets_size) expect(statistics).to have_received(:update_snippets_size)
expect(statistics).to have_received(:update_uploads_size)
expect(statistics.repository_size).to eq(0) expect(statistics.repository_size).to eq(0)
expect(statistics.commit_count).to eq(0) expect(statistics.commit_count).to eq(0)
expect(statistics.wiki_size).to eq(0) expect(statistics.wiki_size).to eq(0)
expect(statistics.snippets_size).to eq(0) expect(statistics.snippets_size).to eq(0)
expect(statistics.uploads_size).to eq(0)
end end
end end
...@@ -163,10 +171,12 @@ RSpec.describe ProjectStatistics do ...@@ -163,10 +171,12 @@ RSpec.describe ProjectStatistics do
expect(statistics).to have_received(:update_repository_size) expect(statistics).to have_received(:update_repository_size)
expect(statistics).to have_received(:update_wiki_size) expect(statistics).to have_received(:update_wiki_size)
expect(statistics).to have_received(:update_snippets_size) expect(statistics).to have_received(:update_snippets_size)
expect(statistics).to have_received(:update_uploads_size)
expect(statistics.repository_size).to eq(0) expect(statistics.repository_size).to eq(0)
expect(statistics.commit_count).to eq(0) expect(statistics.commit_count).to eq(0)
expect(statistics.wiki_size).to eq(0) expect(statistics.wiki_size).to eq(0)
expect(statistics.snippets_size).to eq(0) expect(statistics.snippets_size).to eq(0)
expect(statistics.uploads_size).to eq(0)
end end
end end
...@@ -211,6 +221,7 @@ RSpec.describe ProjectStatistics do ...@@ -211,6 +221,7 @@ RSpec.describe ProjectStatistics do
expect(statistics).not_to receive(:update_wiki_size) expect(statistics).not_to receive(:update_wiki_size)
expect(statistics).not_to receive(:update_lfs_objects_size) expect(statistics).not_to receive(:update_lfs_objects_size)
expect(statistics).not_to receive(:update_snippets_size) expect(statistics).not_to receive(:update_snippets_size)
expect(statistics).not_to receive(:update_uploads_size)
expect(statistics).not_to receive(:save!) expect(statistics).not_to receive(:save!)
expect(Namespaces::ScheduleAggregationWorker) expect(Namespaces::ScheduleAggregationWorker)
.not_to receive(:perform_async) .not_to receive(:perform_async)
...@@ -295,6 +306,26 @@ RSpec.describe ProjectStatistics do ...@@ -295,6 +306,26 @@ RSpec.describe ProjectStatistics do
end end
end end
describe '#update_uploads_size' do
let!(:upload1) { create(:upload, model: project, size: 1.megabyte) }
let!(:upload2) { create(:upload, model: project, size: 2.megabytes) }
it 'stores the size of related uploaded files' do
expect(statistics.update_uploads_size).to eq(3.megabytes)
end
context 'with feature flag disabled' do
before do
statistics.update_columns(uploads_size: 0)
stub_feature_flags(count_uploads_size_in_storage_stats: false)
end
it 'does not store the size of related uploaded files' do
expect(statistics.update_uploads_size).to eq(0)
end
end
end
describe '#update_storage_size' do describe '#update_storage_size' do
it "sums all storage counters" do it "sums all storage counters" do
statistics.update!( statistics.update!(
...@@ -302,12 +333,13 @@ RSpec.describe ProjectStatistics do ...@@ -302,12 +333,13 @@ RSpec.describe ProjectStatistics do
wiki_size: 4, wiki_size: 4,
lfs_objects_size: 3, lfs_objects_size: 3,
snippets_size: 2, snippets_size: 2,
pipeline_artifacts_size: 3 pipeline_artifacts_size: 3,
uploads_size: 5
) )
statistics.reload statistics.reload
expect(statistics.storage_size).to eq 14 expect(statistics.storage_size).to eq 19
end end
it 'works during wiki_size backfill' do it 'works during wiki_size backfill' 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