diff options
Diffstat (limited to 'lib/gitlab/database/migration_helpers.rb')
-rw-r--r-- | lib/gitlab/database/migration_helpers.rb | 180 |
1 files changed, 0 insertions, 180 deletions
diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb index 4245dd80714..aa5ac1e3486 100644 --- a/lib/gitlab/database/migration_helpers.rb +++ b/lib/gitlab/database/migration_helpers.rb @@ -778,186 +778,6 @@ module Gitlab install_rename_triggers(table, old, new) end - # Changes the column type of a table using a background migration. - # - # Because this method uses a background migration it's more suitable for - # large tables. For small tables it's better to use - # `change_column_type_concurrently` since it can complete its work in a - # much shorter amount of time and doesn't rely on Sidekiq. - # - # Example usage: - # - # class Issue < ActiveRecord::Base - # self.table_name = 'issues' - # - # include EachBatch - # - # def self.to_migrate - # where('closed_at IS NOT NULL') - # end - # end - # - # change_column_type_using_background_migration( - # Issue.to_migrate, - # :closed_at, - # :datetime_with_timezone - # ) - # - # Reverting a migration like this is done exactly the same way, just with - # a different type to migrate to (e.g. `:datetime` in the above example). - # - # relation - An ActiveRecord relation to use for scheduling jobs and - # figuring out what table we're modifying. This relation _must_ - # have the EachBatch module included. - # - # column - The name of the column for which the type will be changed. - # - # new_type - The new type of the column. - # - # batch_size - The number of rows to schedule in a single background - # migration. - # - # interval - The time interval between every background migration. - def change_column_type_using_background_migration( - relation, - column, - new_type, - batch_size: 10_000, - interval: 10.minutes - ) - - unless relation.model < EachBatch - raise TypeError, 'The relation must include the EachBatch module' - end - - temp_column = "#{column}_for_type_change" - table = relation.table_name - max_index = 0 - - add_column(table, temp_column, new_type) - install_rename_triggers(table, column, temp_column) - - # Schedule the jobs that will copy the data from the old column to the - # new one. Rows with NULL values in our source column are skipped since - # the target column is already NULL at this point. - relation.where.not(column => nil).each_batch(of: batch_size) do |batch, index| - start_id, end_id = batch.pluck('MIN(id), MAX(id)').first - max_index = index - - migrate_in( - index * interval, - 'CopyColumn', - [table, column, temp_column, start_id, end_id] - ) - end - - # Schedule the renaming of the column to happen (initially) 1 hour after - # the last batch finished. - migrate_in( - (max_index * interval) + 1.hour, - 'CleanupConcurrentTypeChange', - [table, column, temp_column] - ) - - if perform_background_migration_inline? - # To ensure the schema is up to date immediately we perform the - # migration inline in dev / test environments. - Gitlab::BackgroundMigration.steal('CopyColumn') - Gitlab::BackgroundMigration.steal('CleanupConcurrentTypeChange') - end - end - - # Renames a column using a background migration. - # - # Because this method uses a background migration it's more suitable for - # large tables. For small tables it's better to use - # `rename_column_concurrently` since it can complete its work in a much - # shorter amount of time and doesn't rely on Sidekiq. - # - # Example usage: - # - # rename_column_using_background_migration( - # :users, - # :feed_token, - # :rss_token - # ) - # - # table - The name of the database table containing the column. - # - # old - The old column name. - # - # new - The new column name. - # - # type - The type of the new column. If no type is given the old column's - # type is used. - # - # batch_size - The number of rows to schedule in a single background - # migration. - # - # interval - The time interval between every background migration. - def rename_column_using_background_migration( - table, - old_column, - new_column, - type: nil, - batch_size: 10_000, - interval: 10.minutes - ) - - check_trigger_permissions!(table) - - old_col = column_for(table, old_column) - new_type = type || old_col.type - max_index = 0 - - add_column(table, new_column, new_type, - limit: old_col.limit, - precision: old_col.precision, - scale: old_col.scale) - - # We set the default value _after_ adding the column so we don't end up - # updating any existing data with the default value. This isn't - # necessary since we copy over old values further down. - change_column_default(table, new_column, old_col.default) if old_col.default - - install_rename_triggers(table, old_column, new_column) - - model = Class.new(ActiveRecord::Base) do - self.table_name = table - - include ::EachBatch - end - - # Schedule the jobs that will copy the data from the old column to the - # new one. Rows with NULL values in our source column are skipped since - # the target column is already NULL at this point. - model.where.not(old_column => nil).each_batch(of: batch_size) do |batch, index| - start_id, end_id = batch.pluck('MIN(id), MAX(id)').first - max_index = index - - migrate_in( - index * interval, - 'CopyColumn', - [table, old_column, new_column, start_id, end_id] - ) - end - - # Schedule the renaming of the column to happen (initially) 1 hour after - # the last batch finished. - migrate_in( - (max_index * interval) + 1.hour, - 'CleanupConcurrentRename', - [table, old_column, new_column] - ) - - if perform_background_migration_inline? - # To ensure the schema is up to date immediately we perform the - # migration inline in dev / test environments. - Gitlab::BackgroundMigration.steal('CopyColumn') - Gitlab::BackgroundMigration.steal('CleanupConcurrentRename') - end - end - def convert_to_bigint_column(column) "#{column}_convert_to_bigint" end |