diff options
Diffstat (limited to 'app/workers/database')
6 files changed, 95 insertions, 9 deletions
diff --git a/app/workers/database/batched_background_migration/ci_database_worker.rb b/app/workers/database/batched_background_migration/ci_database_worker.rb index b04db87631a..58b0f5496f4 100644 --- a/app/workers/database/batched_background_migration/ci_database_worker.rb +++ b/app/workers/database/batched_background_migration/ci_database_worker.rb @@ -7,6 +7,10 @@ module Database def self.tracking_database @tracking_database ||= Gitlab::Database::CI_DATABASE_NAME.to_sym end + + def execution_worker_class + @execution_worker_class ||= Database::BatchedBackgroundMigration::CiExecutionWorker + end end end end diff --git a/app/workers/database/batched_background_migration/ci_execution_worker.rb b/app/workers/database/batched_background_migration/ci_execution_worker.rb new file mode 100644 index 00000000000..89c70e29dda --- /dev/null +++ b/app/workers/database/batched_background_migration/ci_execution_worker.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module Database + module BatchedBackgroundMigration + class CiExecutionWorker # rubocop:disable Scalability/IdempotentWorker + include ExecutionWorker + end + end +end diff --git a/app/workers/database/batched_background_migration/execution_worker.rb b/app/workers/database/batched_background_migration/execution_worker.rb index 098153c742f..b59e4bd1f86 100644 --- a/app/workers/database/batched_background_migration/execution_worker.rb +++ b/app/workers/database/batched_background_migration/execution_worker.rb @@ -2,14 +2,47 @@ module Database module BatchedBackgroundMigration - class ExecutionWorker # rubocop:disable Scalability/IdempotentWorker + module ExecutionWorker + extend ActiveSupport::Concern include ExclusiveLeaseGuard include Gitlab::Utils::StrongMemoize + include ApplicationWorker + include LimitedCapacity::Worker INTERVAL_VARIANCE = 5.seconds.freeze LEASE_TIMEOUT_MULTIPLIER = 3 + MAX_RUNNING_MIGRATIONS = 2 - def perform(database_name, migration_id) + included do + data_consistency :always + feature_category :database + queue_namespace :batched_background_migrations + end + + class_methods do + def max_running_jobs + MAX_RUNNING_MIGRATIONS + end + + # We have to overirde this one, as we want + # arguments passed as is, and not duplicated + def perform_with_capacity(args) + worker = new + worker.remove_failed_jobs + + bulk_perform_async(args) # rubocop:disable Scalability/BulkPerformWithContext + end + end + + def remaining_work_count(*args) + 0 # the cron worker is the only source of new jobs + end + + def max_running_jobs + self.class.max_running_jobs + end + + def perform_work(database_name, migration_id) self.database_name = database_name return unless enabled? diff --git a/app/workers/database/batched_background_migration/main_execution_worker.rb b/app/workers/database/batched_background_migration/main_execution_worker.rb new file mode 100644 index 00000000000..661496a86a9 --- /dev/null +++ b/app/workers/database/batched_background_migration/main_execution_worker.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module Database + module BatchedBackgroundMigration + class MainExecutionWorker # rubocop:disable Scalability/IdempotentWorker + include ExecutionWorker + end + end +end diff --git a/app/workers/database/batched_background_migration/single_database_worker.rb b/app/workers/database/batched_background_migration/single_database_worker.rb index 0c7c51d5c0a..e772216e557 100644 --- a/app/workers/database/batched_background_migration/single_database_worker.rb +++ b/app/workers/database/batched_background_migration/single_database_worker.rb @@ -39,7 +39,7 @@ module Database unless base_model Sidekiq.logger.info( class: self.class.name, - database: self.class.tracking_database, + database: tracking_database, message: 'skipping migration execution for unconfigured database') return @@ -48,34 +48,61 @@ module Database if shares_db_config? Sidekiq.logger.info( class: self.class.name, - database: self.class.tracking_database, + database: tracking_database, message: 'skipping migration execution for database that shares database configuration with another database') return end Gitlab::Database::SharedModel.using_connection(base_model.connection) do - break unless self.class.enabled? && active_migration + break unless self.class.enabled? - with_exclusive_lease(active_migration.interval) do - run_active_migration + if parallel_execution_enabled? + migrations = Gitlab::Database::BackgroundMigration::BatchedMigration + .active_migrations_distinct_on_table(connection: base_model.connection, limit: max_running_migrations).to_a + + queue_migrations_for_execution(migrations) if migrations.any? + else + break unless active_migration + + with_exclusive_lease(active_migration.interval) do + run_active_migration + end end end end private + def parallel_execution_enabled? + Feature.enabled?(:batched_migrations_parallel_execution) + end + + def max_running_migrations + execution_worker_class.max_running_jobs + end + def active_migration @active_migration ||= Gitlab::Database::BackgroundMigration::BatchedMigration.active_migration(connection: base_model.connection) end def run_active_migration - Database::BatchedBackgroundMigration::ExecutionWorker.new.perform(self.class.tracking_database, active_migration.id) + execution_worker_class.new.perform_work(tracking_database, active_migration.id) + end + + def tracking_database + self.class.tracking_database + end + + def queue_migrations_for_execution(migrations) + jobs_arguments = migrations.map { |migration| [tracking_database.to_s, migration.id] } + + execution_worker_class.perform_with_capacity(jobs_arguments) end def base_model strong_memoize(:base_model) do - Gitlab::Database.database_base_models[self.class.tracking_database] + Gitlab::Database.database_base_models[tracking_database] end end diff --git a/app/workers/database/batched_background_migration_worker.rb b/app/workers/database/batched_background_migration_worker.rb index 29804be832d..1450613dd89 100644 --- a/app/workers/database/batched_background_migration_worker.rb +++ b/app/workers/database/batched_background_migration_worker.rb @@ -7,5 +7,9 @@ module Database def self.tracking_database @tracking_database ||= Gitlab::Database::MAIN_DATABASE_NAME.to_sym end + + def execution_worker_class + @execution_worker_class ||= Database::BatchedBackgroundMigration::MainExecutionWorker + end end end |