files/gitlab-ctl-commands/lib/postgresql/decomposition_migration.rb (100 lines of code) (raw):
require 'io/console'
class PostgreSQL
class DecompositionMigration
def initialize(ctl)
@ctl = ctl
end
def migrate!
unless @ctl.service_enabled?('postgresql')
puts 'There is no PostgreSQL instance enabled in Omnibus, exiting...'
exit 1
end
puts <<~MSG
This script will migrate this GitLab instance to a two-database setup.
WARNING:
- This script is experimental. See https://docs.gitlab.com/ee/administration/postgresql/multiple_databases.html
- Once migrated to a two-database setup, you cannot migrate it back.
Ensure:
- The new database 'gitlabhq_production_ci' has been created, for example:
gitlab-psql -c "CREATE DATABASE gitlabhq_production_ci WITH OWNER 'gitlab'"
- The following changes are added to /etc/gitlab/gitlab.rb configuration file
but do **not** run 'gitlab-ctl reconfigure' yet:
gitlab_rails['env'] = { 'GITLAB_ALLOW_SEPARATE_CI_DATABASE' => 'true' }
gitlab_rails['databases']['ci']['enable'] = true
gitlab_rails['databases']['ci']['db_database'] = 'gitlabhq_production_ci'
This script will:
- Disable background migrations because they should not be active during this migration
See https://docs.gitlab.com/ee/development/database/batched_background_migrations.html#enable-or-disable-background-migrations
- Stop the Gitlab Instance
- Copy data in gitlabhq_production to gitlabhq_production_ci (by dumping, then restoring)
- Apply configuration changes in /etc/gitlab/gitlab.rb using 'gitlab-ctl reconfigure'
- Prevent errorneous database access
- Re-enable background migrations
- Restart GitLab
This script will not:
- Clean up data in the databases
Please confirm the upgrade by pressing 'y':
MSG
prompt = $stdin.gets.chomp
exit(1) unless prompt.casecmp('y').zero?
disable_background_migrations unless background_migrations_initally_disabled?
stop_gitlab_services
run_migration
post_migrate
puts <<~MSG
GitLab is now running on two databases. Data related to CI is now written to the ci
database.
You can also remove duplicated data by running:
'sudo gitlab-rake gitlab:db:truncate_legacy_tables:main'
'sudo gitlab-rake gitlab:db:truncate_legacy_tables:ci'
MSG
end
private
def background_migrations_initally_disabled?
@background_migrations_initally_disabled ||= GitlabCtl::Util.run_command(
'gitlab-rails runner "puts (Feature.disabled?(:execute_background_migrations, type: :ops) && Feature.disabled?(:execute_batched_migrations_on_schedule, type: :ops)).to_s"'
).stdout.chomp == "true"
end
def disable_background_migrations
puts "Disabling Background Migrations..."
run_command <<~CMD
gitlab-rails runner "Feature.disable(:execute_background_migrations) && Feature.disable(:execute_batched_migrations_on_schedule)"
CMD
end
def enable_background_migrations
puts "Enabling Background Migrations..."
run_command <<~CMD
gitlab-rails runner "Feature.enable(:execute_background_migrations) && Feature.enable(:execute_batched_migrations_on_schedule)"
CMD
end
def stop_gitlab_services
puts "Stopping GitLab..."
run_command("gitlab-ctl stop && gitlab-ctl start postgresql")
end
def run_migration
puts "Copying data to new database..."
run_command("gitlab-rake gitlab:db:decomposition:migrate", timeout: 84_600)
end
def post_migrate
puts "Reconfigure GitLab..."
run_command("gitlab-ctl reconfigure")
puts "Enable write locks..."
run_command("gitlab-rake gitlab:db:lock_writes")
enable_background_migrations unless background_migrations_initally_disabled?
puts "Restarting GitLab..."
run_command("gitlab-ctl restart")
end
def run_command(cmd, timeout: nil)
GitlabCtl::Util.run_command(cmd, timeout: timeout).tap do |status|
if status.error?
enable_background_migrations unless background_migrations_initally_disabled?
puts status.stdout
puts status.stderr
puts "[ERROR] Failed to execute: #{cmd}"
puts "This GitLab instance is still disabled."
exit 1
end
end
end
end
end