gitlab-org--gitlab-foss/db/post_migrate/20190715193142_migrate_disc...

63 lines
2.2 KiB
Ruby

# frozen_string_literal: true
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class MigrateDiscussionIdOnPromotedEpics < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
# We have ~5000 unique discussion_ids -> this migration will take about 102 minutes
# (5000/100 * 2 minutes + 2 minutes initial delay) on gitlab.com.
DOWNTIME = false
BATCH_SIZE = 100
DELAY_INTERVAL = 2.minutes
MIGRATION = 'FixPromotedEpicsDiscussionIds'
disable_ddl_transaction!
class SystemNoteMetadata < ActiveRecord::Base
self.table_name = 'system_note_metadata'
self.inheritance_column = :_type_disabled
end
class Note < ActiveRecord::Base
include EachBatch
has_one :system_note_metadata, class_name: 'MigrateDiscussionIdOnPromotedEpics::SystemNoteMetadata'
self.table_name = 'notes'
self.inheritance_column = :_type_disabled
def self.fetch_discussion_ids_query
promoted_epics_query = Note
.joins(:system_note_metadata)
.where(system: true)
.where(noteable_type: 'Epic')
.where(system_note_metadata: { action: 'moved' })
.select("DISTINCT noteable_id")
Note.where(noteable_type: 'Epic')
.where(noteable_id: promoted_epics_query)
.distinct.pluck(:discussion_id)
end
end
def up
add_concurrent_index(:system_note_metadata, :note_id, where: "action='moved'", name: 'temp_index_system_note_metadata_on_moved_note_id')
add_concurrent_index(:notes, [:id, :noteable_id], where: "noteable_type='Epic' AND system", name: 'temp_index_notes_on_id_and_noteable_id' )
all_discussion_ids = Note.fetch_discussion_ids_query
all_discussion_ids.in_groups_of(BATCH_SIZE, false).each_with_index do |ids, index|
delay = DELAY_INTERVAL * (index + 1)
BackgroundMigrationWorker.perform_in(delay, MIGRATION, [ids])
end
remove_concurrent_index(:system_note_metadata, :note_id, where: "action='moved'", name: 'temp_index_system_note_metadata_on_moved_note_id')
remove_concurrent_index(:notes, [:id, :noteable_id], where: "noteable_type='Epic' AND system", name: 'temp_index_notes_on_id_and_noteable_id')
end
def down
# no-op
end
end