timescaledb/sql/restoring.sql
David Kohn ad97d266c0 Fix restoring/scheduler entrypoint to avoid BGW death
There was a race condition between the post_restore function
restarting the background worker and the setting of the
restoring flag to "off". If the worker started before the
change to the restoring flag had been committed, it would not
see the change and then die because the worker should exit
when the db is in a restoring state. This modifies the
post_restore function to use a restart instead of a start
so that it waits on the commit to start up. It also adds
logic to the entrypoint to reload config changes caused
by an `ALTER DATABASE SET` command. These changes are
normally only seen at connection startup but we have to
wait until after our lock on the modifying transaction is
released to know whether we should adopt them.
2020-03-10 11:02:18 -04:00

42 lines
1.4 KiB
PL/PgSQL

-- This file and its contents are licensed under the Apache License 2.0.
-- Please see the included NOTICE for copyright information and
-- LICENSE-APACHE for a copy of the license.
CREATE OR REPLACE FUNCTION timescaledb_pre_restore() RETURNS BOOL AS
$BODY$
DECLARE
db text;
BEGIN
SELECT current_database() INTO db;
EXECUTE format($$ALTER DATABASE %I SET timescaledb.restoring ='on'$$, db);
SET SESSION timescaledb.restoring = 'on';
PERFORM _timescaledb_internal.stop_background_workers();
--exported uuid may be included in the dump so backup the version
UPDATE _timescaledb_catalog.metadata SET key='exported_uuid_bak' WHERE key='exported_uuid';
RETURN true;
END
$BODY$
LANGUAGE PLPGSQL;
CREATE OR REPLACE FUNCTION timescaledb_post_restore() RETURNS BOOL AS
$BODY$
DECLARE
db text;
BEGIN
SELECT current_database() INTO db;
EXECUTE format($$ALTER DATABASE %I SET timescaledb.restoring ='off'$$, db);
SET SESSION timescaledb.restoring='off';
PERFORM _timescaledb_internal.restart_background_workers();
--try to restore the backed up uuid, if the restore did not set one
INSERT INTO _timescaledb_catalog.metadata
SELECT 'exported_uuid', value, include_in_telemetry FROM _timescaledb_catalog.metadata WHERE key='exported_uuid_bak'
ON CONFLICT DO NOTHING;
DELETE FROM _timescaledb_catalog.metadata WHERE key='exported_uuid_bak';
RETURN true;
END
$BODY$
LANGUAGE PLPGSQL;