From 3bccd8c8f3f6ee6a758e9881e19159fe8f599b12 Mon Sep 17 00:00:00 2001 From: Guo Xiang Tan Date: Fri, 9 Mar 2018 13:18:47 +0800 Subject: [PATCH] FIX: Restore process for dump taken with `pg_dump` 10.3+. * Since we can no longer restore into a different schema, we will move tables in the public schema into the backup schema first before restoring the dump file which goes into the public schema. The downside to this approach is that we will increase the downtime experienced during the restore process. Downtime would equal the duration of restoring the dump file. --- lib/backup_restore/restorer.rb | 52 ++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/lib/backup_restore/restorer.rb b/lib/backup_restore/restorer.rb index fcffe922816..5150c7fa9dc 100644 --- a/lib/backup_restore/restorer.rb +++ b/lib/backup_restore/restorer.rb @@ -39,23 +39,41 @@ module BackupRestore validate_metadata extract_dump - restore_dump + dumped_by_version = Gem::Version.new(get_dumped_by_version) - ### READ-ONLY / START ### - enable_readonly_mode + if dumped_by_version >= Gem::Version.new("10.3") || + dumped_by_version >= Gem::Version.new("9.5.12") - pause_sidekiq - wait_for_sidekiq + enable_readonly_mode - switch_schema! + pause_sidekiq + wait_for_sidekiq - migrate_database - reconnect_database - reload_site_settings - clear_emoji_cache + BackupRestore.move_tables_between_schemas("public", "backup") + restore_dump + migrate_database + reconnect_database - disable_readonly_mode - ### READ-ONLY / END ### + reload_site_settings + clear_emoji_cache + + disable_readonly_mode + else + restore_dump + enable_readonly_mode + + pause_sidekiq + wait_for_sidekiq + + switch_schema! + + migrate_database + reconnect_database + reload_site_settings + clear_emoji_cache + + disable_readonly_mode + end extract_uploads rescue SystemExit @@ -238,6 +256,16 @@ module BackupRestore end end + def get_dumped_by_version + output = Discourse::Utils.execute_command( + File.extname(@dump_filename) == '.gz' ? 'zgrep' : 'grep', + '-m1', @dump_filename, '-e', "pg_dump", + failure_message: "Failed to check version of pg_dump used to generate the dump file" + ) + + output.match(/version (\d+(\.\d+)?)/)[1] + end + def restore_dump_command if File.extname(@dump_filename) == '.gz' "gzip -d < #{@dump_filename} | #{sed_command} | #{psql_command} 2>&1"