2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2025-09-09 22:22:54 +08:00

FEATURE: Work with compressed version of pg_dump during backup and restore.

This commit is contained in:
Guo Xiang Tan 2016-07-22 10:45:39 +08:00
parent b5fbff947b
commit 03aa13b2bb
4 changed files with 82 additions and 51 deletions

View file

@ -1,6 +1,7 @@
module BackupRestore
class Backuper
include BackupRestore::Utils
attr_reader :success
@ -42,8 +43,6 @@ module BackupRestore
log "Finalizing backup..."
update_dump
create_archive
after_create_hook
@ -84,7 +83,7 @@ module BackupRestore
@current_db = RailsMultisite::ConnectionManagement.current_db
@timestamp = Time.now.strftime("%Y-%m-%d-%H%M%S")
@tmp_directory = File.join(Rails.root, "tmp", "backups", @current_db, @timestamp)
@dump_filename = File.join(@tmp_directory, BackupRestore::DUMP_FILE)
@dump_filename = "#{File.join(@tmp_directory, BackupRestore::DUMP_FILE)}.gz"
@meta_filename = File.join(@tmp_directory, BackupRestore::METADATA_FILE)
@archive_directory = File.join(Rails.root, "public", "backups", @current_db)
@archive_basename = File.join(@archive_directory, "#{SiteSetting.title.parameterize}-#{@timestamp}")
@ -192,6 +191,7 @@ module BackupRestore
"--no-owner", # do not output commands to set ownership of objects
"--no-privileges", # prevent dumping of access privileges
"--verbose", # specifies verbose mode
"--compress=4", # Compression level of 4
host_argument, # the hostname to connect to (if any)
port_argument, # the port to connect to (if any)
username_argument, # the username to connect as (if any)
@ -199,59 +199,32 @@ module BackupRestore
].join(" ")
end
def update_dump
log "Updating dump for more awesomeness..."
`#{sed_command}`
end
def sed_command
# in order to limit the downtime when restoring as much as possible
# we force the restoration to happen in the "restore" schema
# during the restoration, this make sure we
# - drop the "restore" schema if it exists
# - create the "restore" schema
# - prepend the "restore" schema into the search_path
regexp = "SET search_path = public, pg_catalog;"
replacement = [ "DROP SCHEMA IF EXISTS restore CASCADE;",
"CREATE SCHEMA restore;",
"SET search_path = restore, public, pg_catalog;",
].join(" ")
# we only want to replace the VERY first occurence of the search_path command
expression = "1,/^#{regexp}$/s/#{regexp}/#{replacement}/"
# I tried to use the --in-place argument but it was SLOOOWWWWwwwwww
# so I output the result into another file and rename it back afterwards
[ "sed -e '#{expression}' < #{@dump_filename} > #{@dump_filename}.tmp",
"&&",
"mv #{@dump_filename}.tmp #{@dump_filename}",
].join(" ")
end
def create_archive
log "Creating archive: #{File.basename(@archive_basename)}.tar.gz"
tar_filename = "#{@archive_basename}.tar"
log "Making sure archive does not already exist..."
`rm -f #{tar_filename}`
`rm -f #{tar_filename}.gz`
execute_command("rm -f #{tar_filename}")
execute_command("rm -f #{tar_filename}.gz")
log "Creating empty archive..."
`tar --create --file #{tar_filename} --files-from /dev/null`
execute_command("tar --create --file #{tar_filename} --files-from /dev/null")
log "Archiving data dump..."
FileUtils.cd(File.dirname(@dump_filename)) do
`tar --append --dereference --file #{tar_filename} #{File.basename(@dump_filename)}`
FileUtils.cd(File.dirname("#{@dump_filename}")) do
execute_command(
"tar --append --dereference --file #{tar_filename} #{File.basename(@dump_filename)}",
"Failed to archive data dump."
)
end
log "Archiving metadata..."
FileUtils.cd(File.dirname(@meta_filename)) do
`tar --append --dereference --file #{tar_filename} #{File.basename(@meta_filename)}`
execute_command(
"tar --append --dereference --file #{tar_filename} #{File.basename(@meta_filename)}",
"Failed to archive metadata."
)
end
if @with_uploads
@ -259,14 +232,17 @@ module BackupRestore
log "Archiving uploads..."
FileUtils.cd(File.join(Rails.root, "public")) do
`tar --append --dereference --file #{tar_filename} #{upload_directory}`
execute_command(
"tar --append --dereference --file #{tar_filename} #{upload_directory}",
"Failed to archive uploads."
)
end
end
remove_tmp_directory
log "Gzipping archive, this may take a while..."
`gzip -5 #{tar_filename}`
execute_command("gzip -5 #{tar_filename}", "Failed to gzip archive.")
end
def after_create_hook