gitlab-org--gitlab-foss/lib/backup/database.rb
Jacob Vosmaer 8fe10e642a Empty the database during Postgres backup restore
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.
2014-02-26 18:26:31 +01:00

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