FIX: Remove unsupported SQL from DB dump during restore

DB dumps might contain SQL that is unsupported in a usual Discourse DB. This removes those SQL statements during the restore of a backup to prevent errors.
This commit is contained in:
Gerhard Schlager
2025-11-03 11:15:00 +01:00
committed by Gerhard Schlager
parent 6629e73449
commit 3179f9c04d
3 changed files with 105 additions and 3 deletions
+16 -3
View File
@@ -104,15 +104,27 @@ module BackupRestore
"CREATE SCHEMA", # PostgreSQL 11+
"COMMENT ON SCHEMA", # PostgreSQL 11+
"SET default_table_access_method", # PostgreSQL 12
"CREATE EXTENSION",
"COMMENT ON EXTENSION",
"\\\\restrict",
"\\\\unrestrict",
].join("|")
command = "sed -E '/^(#{unwanted_sql})/d' #{@db_dump_path}"
commands = [
"/^(#{unwanted_sql})/d;",
"/^CREATE FUNCTION discourse_functions/,/^\\$\\$;$/d",
"/^CREATE (SERVER|USER MAPPING|FOREIGN TABLE)/,/^ *\\);/d",
]
if BackupRestore.postgresql_major_version < 11
command = "#{command} | sed -E 's/^(CREATE TRIGGER.+EXECUTE) FUNCTION/\\1 PROCEDURE/'"
commands << "s/^(CREATE TRIGGER.+EXECUTE) FUNCTION/\\1 PROCEDURE/"
end
command
<<~COMMAND
sed -E '
#{commands.join(";\n")}
' #{@db_dump_path}
COMMAND
end
def restore_dump_command
@@ -165,6 +177,7 @@ module BackupRestore
"SKIP_POST_DEPLOYMENT_MIGRATIONS" => "0",
"SKIP_OPTIMIZE_ICONS" => "1",
"DISABLE_TRANSLATION_OVERRIDES" => "1",
"SKIP_SEED_FU" => "1",
},
"rake",
"db:migrate",
+70
View File
@@ -0,0 +1,70 @@
--
-- PostgreSQL database dump
--
-- Dumped from database version 12.2 (Debian 12.2-2.pgdg100+1)
-- Dumped by pg_dump version 12.2 (Debian 12.2-2.pgdg100+1)
-- Started on 2020-06-15 08:06:34 UTC
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
--
-- TOC entry 198 (class 1259 OID 16585)
-- Name: foo; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.foo (
id integer NOT NULL,
topic_id integer,
user_id integer
);
CREATE EXTENSION IF NOT EXISTS hstore WITH SCHEMA public;
COMMENT ON EXTENSION hstore IS 'data type for storing sets of (key, value) pairs';
CREATE EXTENSION IF NOT EXISTS postgres_fdw WITH SCHEMA public;
COMMENT ON EXTENSION postgres_fdw IS 'foreign-data wrapper for remote PostgreSQL servers';
CREATE FUNCTION discourse_functions.raise_topic_status_updates_readonly() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
RAISE EXCEPTION 'Discourse: topic_status_updates is read only';
END
$$;
CREATE SERVER discourse_foo_fdw FOREIGN DATA WRAPPER postgres_fdw OPTIONS (
dbname 'discourse_foo',
host 'localhost',
port '5432'
);
CREATE USER MAPPING FOR discourse SERVER discourse_foo_fdw OPTIONS (
password '123',
"user" 'discourse'
);
CREATE FOREIGN TABLE public.foo_sso_records (
external_id character varying,
external_email character varying
)
SERVER discourse_foo_fdw
OPTIONS (
schema_name 'public',
table_name 'single_sign_on_records'
);
@@ -77,6 +77,10 @@ RSpec.describe BackupRestore::DatabaseRestorer do
expect_restore_to_work("postgresql_15.14.sql")
end
it "ignores unwanted SQL" do
expect_restore_to_work("unwanted.sql")
end
it "detects error during restore" do
expect { restore("error.sql", stub_migrate: false) }.to raise_error(
BackupRestore::DatabaseRestoreError,
@@ -137,6 +141,21 @@ RSpec.describe BackupRestore::DatabaseRestorer do
/^CREATE TRIGGER foo_user_id_readonly .+? EXECUTE FUNCTION discourse_functions.raise_foo_user_id_readonly/,
)
end
it "removes unwanted SQL" do
log = restore_and_log_output("unwanted.sql")
expect(log).to include("CREATE TABLE public.foo")
expect(log).not_to be_blank
expect(log).not_to include("CREATE EXTENSION")
expect(log).not_to include("COMMENT ON EXTENSION")
expect(log).not_to include(
"CREATE FUNCTION discourse_functions.raise_topic_status_updates_readonly",
)
expect(log).not_to include("CREATE SERVER")
expect(log).not_to include("CREATE USER")
expect(log).not_to include("CREATE FOREIGN TABLE")
end
end
describe "database connection" do