Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-04-22 00:09:40 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-04-22 00:09:40 +0300
commitdb115d5ac71e57b2dad327004de7660e353dcd1c (patch)
tree440519fe8dd6439577258fa671274d6b9a0d7813 /lib
parentaed8f5ecc5f9a09e3af9c32f7b02743d317a4116 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/background_migration/copy_column_using_background_migration_job.rb29
-rw-r--r--lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature.rb17
-rw-r--r--lib/gitlab/database/migration_helpers.rb65
3 files changed, 64 insertions, 47 deletions
diff --git a/lib/gitlab/background_migration/copy_column_using_background_migration_job.rb b/lib/gitlab/background_migration/copy_column_using_background_migration_job.rb
index b89ea7dc250..c7226b41bab 100644
--- a/lib/gitlab/background_migration/copy_column_using_background_migration_job.rb
+++ b/lib/gitlab/background_migration/copy_column_using_background_migration_job.rb
@@ -2,8 +2,8 @@
module Gitlab
module BackgroundMigration
- # Background migration that updates the value of a
- # column using the value of another column in the same table.
+ # Background migration that updates the value of one or more
+ # columns using the value of other columns in the same table.
#
# - The {start_id, end_id} arguments are at the start so that it can be used
# with `queue_batched_background_migration`
@@ -25,17 +25,21 @@ module Gitlab
# sub_batch_size - We don't want updates to take more than ~100ms
# This allows us to run multiple smaller batches during
# the minimum 2.minute interval that we can schedule jobs
- # copy_from - The column containing the data to copy.
- # copy_to - The column to copy the data to.
+ # copy_from - List of columns containing the data to copy.
+ # copy_to - List of columns to copy the data to. Order must match the order in `copy_from`.
def perform(start_id, end_id, batch_table, batch_column, sub_batch_size, copy_from, copy_to)
- quoted_copy_from = connection.quote_column_name(copy_from)
- quoted_copy_to = connection.quote_column_name(copy_to)
+ copy_from = Array.wrap(copy_from)
+ copy_to = Array.wrap(copy_to)
+
+ raise ArgumentError, 'number of source and destination columns must match' unless copy_from.count == copy_to.count
+
+ assignment_clauses = column_assignment_clauses(copy_from, copy_to)
parent_batch_relation = relation_scoped_to_range(batch_table, batch_column, start_id, end_id)
parent_batch_relation.each_batch(column: batch_column, of: sub_batch_size) do |sub_batch|
batch_metrics.time_operation(:update_all) do
- sub_batch.update_all("#{quoted_copy_to}=#{quoted_copy_from}")
+ sub_batch.update_all(assignment_clauses)
end
sleep(PAUSE_SECONDS)
@@ -55,6 +59,17 @@ module Gitlab
def relation_scoped_to_range(source_table, source_key_column, start_id, stop_id)
define_batchable_model(source_table).where(source_key_column => start_id..stop_id)
end
+
+ def column_assignment_clauses(copy_from, copy_to)
+ assignments = copy_from.zip(copy_to).map do |from_column, to_column|
+ from_column = connection.quote_column_name(from_column)
+ to_column = connection.quote_column_name(to_column)
+
+ "#{to_column} = #{from_column}"
+ end
+
+ assignments.join(', ')
+ end
end
end
end
diff --git a/lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature.rb b/lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature.rb
index 9ecf53317d0..c01545e5dca 100644
--- a/lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature.rb
+++ b/lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature.rb
@@ -8,18 +8,15 @@ module Gitlab
class MoveContainerRegistryEnabledToProjectFeature
MAX_BATCH_SIZE = 300
- module Migratable
- # Migration model namespace isolated from application code.
- class ProjectFeature < ActiveRecord::Base
- ENABLED = 20
- DISABLED = 0
- end
- end
+ ENABLED = 20
+ DISABLED = 0
def perform(from_id, to_id)
(from_id..to_id).each_slice(MAX_BATCH_SIZE) do |batch|
process_batch(batch.first, batch.last)
end
+
+ Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded('MoveContainerRegistryEnabledToProjectFeature', [from_id, to_id])
end
private
@@ -37,9 +34,9 @@ module Gitlab
<<~SQL
UPDATE project_features
SET container_registry_access_level = (CASE p.container_registry_enabled
- WHEN true THEN #{ProjectFeature::ENABLED}
- WHEN false THEN #{ProjectFeature::DISABLED}
- ELSE #{ProjectFeature::DISABLED}
+ WHEN true THEN #{ENABLED}
+ WHEN false THEN #{DISABLED}
+ ELSE #{DISABLED}
END)
FROM projects p
WHERE project_id = p.id AND
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb
index d06a73da8ac..25ae72370fe 100644
--- a/lib/gitlab/database/migration_helpers.rb
+++ b/lib/gitlab/database/migration_helpers.rb
@@ -905,7 +905,7 @@ module Gitlab
end
end
- # Initializes the conversion of an integer column to bigint
+ # Initializes the conversion of a set of integer columns to bigint
#
# It can be used for converting both a Primary Key and any Foreign Keys
# that may reference it or any other integer column that we may want to
@@ -923,14 +923,14 @@ module Gitlab
# Note: this helper is intended to be used in a regular (pre-deployment) migration.
#
# This helper is part 1 of a multi-step migration process:
- # 1. initialize_conversion_of_integer_to_bigint to create the new column and database triggers
+ # 1. initialize_conversion_of_integer_to_bigint to create the new columns and database trigger
# 2. backfill_conversion_of_integer_to_bigint to copy historic data using background migrations
# 3. remaining steps TBD, see #288005
#
# table - The name of the database table containing the column
- # column - The name of the column that we want to convert to bigint.
+ # columns - The name, or array of names, of the column(s) that we want to convert to bigint.
# primary_key - The name of the primary key column (most often :id)
- def initialize_conversion_of_integer_to_bigint(table, column, primary_key: :id)
+ def initialize_conversion_of_integer_to_bigint(table, columns, primary_key: :id)
unless table_exists?(table)
raise "Table #{table} does not exist"
end
@@ -939,34 +939,40 @@ module Gitlab
raise "Column #{primary_key} does not exist on #{table}"
end
- unless column_exists?(table, column)
- raise "Column #{column} does not exist on #{table}"
+ columns = Array.wrap(columns)
+ columns.each do |column|
+ next if column_exists?(table, column)
+
+ raise ArgumentError, "Column #{column} does not exist on #{table}"
end
check_trigger_permissions!(table)
- old_column = column_for(table, column)
- tmp_column = "#{column}_convert_to_bigint"
+ conversions = columns.to_h { |column| [column, "#{column}_convert_to_bigint"] }
with_lock_retries do
- if (column.to_s == primary_key.to_s) || !old_column.null
- # If the column to be converted is either a PK or is defined as NOT NULL,
- # set it to `NOT NULL DEFAULT 0` and we'll copy paste the correct values bellow
- # That way, we skip the expensive validation step required to add
- # a NOT NULL constraint at the end of the process
- add_column(table, tmp_column, :bigint, default: old_column.default || 0, null: false)
- else
- add_column(table, tmp_column, :bigint, default: old_column.default)
+ conversions.each do |(source_column, temporary_name)|
+ column = column_for(table, source_column)
+
+ if (column.name.to_s == primary_key.to_s) || !column.null
+ # If the column to be converted is either a PK or is defined as NOT NULL,
+ # set it to `NOT NULL DEFAULT 0` and we'll copy paste the correct values bellow
+ # That way, we skip the expensive validation step required to add
+ # a NOT NULL constraint at the end of the process
+ add_column(table, temporary_name, :bigint, default: column.default || 0, null: false)
+ else
+ add_column(table, temporary_name, :bigint, default: column.default)
+ end
end
- install_rename_triggers(table, column, tmp_column)
+ install_rename_triggers(table, conversions.keys, conversions.values)
end
end
- # Backfills the new column used in the conversion of an integer column to bigint using background migrations.
+ # Backfills the new columns used in an integer-to-bigint conversion using background migrations.
#
# - This helper should be called from a post-deployment migration.
- # - In order for this helper to work properly, the new column must be first initialized with
+ # - In order for this helper to work properly, the new columns must be first initialized with
# the `initialize_conversion_of_integer_to_bigint` helper.
# - It tracks the scheduled background jobs through Gitlab::Database::BackgroundMigration::BatchedMigration,
# which allows a more thorough check that all jobs succeeded in the
@@ -976,12 +982,12 @@ module Gitlab
# deployed (including background job changes) before we begin processing the background migration.
#
# This helper is part 2 of a multi-step migration process:
- # 1. initialize_conversion_of_integer_to_bigint to create the new column and database triggers
+ # 1. initialize_conversion_of_integer_to_bigint to create the new columns and database trigger
# 2. backfill_conversion_of_integer_to_bigint to copy historic data using background migrations
# 3. remaining steps TBD, see #288005
#
# table - The name of the database table containing the column
- # column - The name of the column that we want to convert to bigint.
+ # columns - The name, or an array of names, of the column(s) we want to convert to bigint.
# primary_key - The name of the primary key column (most often :id)
# batch_size - The number of rows to schedule in a single background migration
# sub_batch_size - The smaller batches that will be used by each scheduled job
@@ -1001,7 +1007,7 @@ module Gitlab
# between the scheduled jobs
def backfill_conversion_of_integer_to_bigint(
table,
- column,
+ columns,
primary_key: :id,
batch_size: 20_000,
sub_batch_size: 1000,
@@ -1016,22 +1022,21 @@ module Gitlab
raise "Column #{primary_key} does not exist on #{table}"
end
- unless column_exists?(table, column)
- raise "Column #{column} does not exist on #{table}"
- end
+ conversions = Array.wrap(columns).to_h do |column|
+ raise ArgumentError, "Column #{column} does not exist on #{table}" unless column_exists?(table, column)
- tmp_column = "#{column}_convert_to_bigint"
+ temporary_name = "#{column}_convert_to_bigint"
+ raise ArgumentError, "Column #{temporary_name} does not exist on #{table}" unless column_exists?(table, temporary_name)
- unless column_exists?(table, tmp_column)
- raise 'The temporary column does not exist, initialize it with `initialize_conversion_of_integer_to_bigint`'
+ [column, temporary_name]
end
batched_migration = queue_batched_background_migration(
'CopyColumnUsingBackgroundMigrationJob',
table,
primary_key,
- column,
- tmp_column,
+ conversions.keys,
+ conversions.values,
job_interval: interval,
batch_size: batch_size,
sub_batch_size: sub_batch_size)