8fe10e642a
The expected behavior during a GitLab backup restore is to overwrite existing database data. This works for MySQL because the output of mysqldump contains 'DROP TABLE IF EXISTS' statements. pg_dump on the other hand assumes that one will restore into an empty database. When this is not the case, during the restore with psql some of the data will be skipped if existing data is 'in the way'. By first invoking `rake db:schema:load` during a Postgres GitLab backup restore, we make sure that all important data is correctly restored.
74 lines
2.2 KiB
Ruby
74 lines
2.2 KiB
Ruby
require 'yaml'
|
|
|
|
module Backup
|
|
class Database
|
|
attr_reader :config, :db_dir
|
|
|
|
def initialize
|
|
@config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env]
|
|
@db_dir = File.join(Gitlab.config.backup.path, 'db')
|
|
FileUtils.mkdir_p(@db_dir) unless Dir.exists?(@db_dir)
|
|
end
|
|
|
|
def dump
|
|
success = case config["adapter"]
|
|
when /^mysql/ then
|
|
print "Dumping MySQL database #{config['database']} ... "
|
|
system('mysqldump', *mysql_args, config['database'], out: db_file_name)
|
|
when "postgresql" then
|
|
print "Dumping PostgreSQL database #{config['database']} ... "
|
|
pg_env
|
|
system('pg_dump', config['database'], out: db_file_name)
|
|
end
|
|
report_success(success)
|
|
end
|
|
|
|
def restore
|
|
success = case config["adapter"]
|
|
when /^mysql/ then
|
|
print "Restoring MySQL database #{config['database']} ... "
|
|
system('mysql', *mysql_args, config['database'], in: db_file_name)
|
|
when "postgresql" then
|
|
puts "Destructively rebuilding database schema for RAILS_ENV #{Rails.env}"
|
|
Rake::Task["db:schema:load"].invoke
|
|
print "Restoring PostgreSQL database #{config['database']} ... "
|
|
pg_env
|
|
system('psql', config['database'], '-f', db_file_name)
|
|
end
|
|
report_success(success)
|
|
end
|
|
|
|
protected
|
|
|
|
def db_file_name
|
|
File.join(db_dir, 'database.sql')
|
|
end
|
|
|
|
def mysql_args
|
|
args = {
|
|
'host' => '--host',
|
|
'port' => '--port',
|
|
'socket' => '--socket',
|
|
'username' => '--user',
|
|
'encoding' => '--default-character-set',
|
|
'password' => '--password'
|
|
}
|
|
args.map { |opt, arg| "#{arg}=#{config[opt]}" if config[opt] }.compact
|
|
end
|
|
|
|
def pg_env
|
|
ENV['PGUSER'] = config["username"] if config["username"]
|
|
ENV['PGHOST'] = config["host"] if config["host"]
|
|
ENV['PGPORT'] = config["port"].to_s if config["port"]
|
|
ENV['PGPASSWORD'] = config["password"].to_s if config["password"]
|
|
end
|
|
|
|
def report_success(success)
|
|
if success
|
|
puts '[DONE]'.green
|
|
else
|
|
puts '[FAILED]'.red
|
|
end
|
|
end
|
|
end
|
|
end
|