-- This file and its contents are licensed under the Timescale License. -- Please see the included NOTICE for copyright information and -- LICENSE-TIMESCALE for a copy of the license. -- Need to be super user to create extension and add data nodes \c :TEST_DBNAME :ROLE_SUPERUSER; ALTER ROLE :ROLE_DEFAULT_CLUSTER_USER CREATEDB PASSWORD 'pass'; GRANT USAGE ON FOREIGN DATA WRAPPER timescaledb_fdw TO :ROLE_DEFAULT_CLUSTER_USER; -- This test sets explicit UUIDs on the frontends to guarantee stable test output GRANT ALL ON _timescaledb_catalog.metadata TO :ROLE_DEFAULT_CLUSTER_USER; SET ROLE :ROLE_DEFAULT_CLUSTER_USER; -- Cleanup from other potential tests that created these databases SET client_min_messages TO ERROR; DROP DATABASE IF EXISTS backend_1; DROP DATABASE IF EXISTS backend_2; DROP DATABASE IF EXISTS frontend_b; DROP DATABASE IF EXISTS backend_3; SET client_min_messages TO NOTICE; CREATE DATABASE backend_1; CREATE DATABASE backend_2; CREATE DATABASE backend_3; CREATE DATABASE frontend_b; \c backend_1 SET client_min_messages TO ERROR; CREATE EXTENSION timescaledb; GRANT ALL ON _timescaledb_catalog.metadata TO :ROLE_DEFAULT_CLUSTER_USER; SET client_min_messages TO NOTICE; \c backend_2 SET client_min_messages TO ERROR; CREATE EXTENSION timescaledb; GRANT ALL ON _timescaledb_catalog.metadata TO :ROLE_DEFAULT_CLUSTER_USER; SET client_min_messages TO NOTICE; \c backend_3 SET client_min_messages TO ERROR; CREATE EXTENSION timescaledb; GRANT ALL ON _timescaledb_catalog.metadata TO :ROLE_DEFAULT_CLUSTER_USER; SET client_min_messages TO NOTICE; -- Create a second frontend database and add a backend to it \c frontend_b SET client_min_messages TO ERROR; CREATE EXTENSION timescaledb; SET client_min_messages TO NOTICE; ALTER ROLE :ROLE_DEFAULT_CLUSTER_USER CREATEDB PASSWORD 'pass'; GRANT USAGE ON FOREIGN DATA WRAPPER timescaledb_fdw TO :ROLE_DEFAULT_CLUSTER_USER; GRANT ALL ON _timescaledb_catalog.metadata TO :ROLE_DEFAULT_CLUSTER_USER; SET ROLE :ROLE_DEFAULT_CLUSTER_USER; INSERT INTO _timescaledb_catalog.metadata VALUES ('uuid', '87c235e9-d857-4f16-b59f-7fbac9b87664', true) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value; SELECT * FROM _timescaledb_catalog.metadata WHERE key LIKE 'uuid' OR key LIKE 'dist_uuid'; SELECT * FROM add_data_node('data_node_1', database => 'backend_3', password => 'pass', if_not_exists => true); SELECT * FROM _timescaledb_catalog.metadata WHERE key LIKE 'uuid' OR key LIKE 'dist_uuid'; -- Connect back to our original database and add a backend to it \c :TEST_DBNAME :ROLE_SUPERUSER; SET ROLE :ROLE_DEFAULT_CLUSTER_USER; INSERT INTO _timescaledb_catalog.metadata VALUES ('uuid', '77348176-09da-4a80-bc78-e31bdf5e63ec', true) ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value; SELECT * FROM _timescaledb_catalog.metadata WHERE key LIKE 'uuid' OR key LIKE 'dist_uuid'; SELECT * FROM add_data_node('data_node_1', database => 'backend_1', password => 'pass', if_not_exists => true); SELECT * FROM _timescaledb_catalog.metadata WHERE key LIKE 'uuid' OR key LIKE 'dist_uuid'; -- We now have two frontends with one backend each and one undistributed database -- Let's try some invalid configurations \set ON_ERROR_STOP 0 -- Adding frontend as backend to a different frontend SELECT * FROM add_data_node('frontend_b', database => 'frontend_b', password => 'pass', if_not_exists => true); -- Adding backend from a different group as a backend SELECT * FROM add_data_node('server_b', database => 'backend_3', password => 'pass', if_not_exists => true); -- Adding a valid backend target but to an existing backend \c backend_1 SET ROLE :ROLE_DEFAULT_CLUSTER_USER; SELECT * FROM add_data_node('data_node_2', database => 'backend_2', password => 'pass', if_not_exists => true); \c backend_2 GRANT USAGE ON FOREIGN DATA WRAPPER timescaledb_fdw TO :ROLE_DEFAULT_CLUSTER_USER; SET ROLE :ROLE_DEFAULT_CLUSTER_USER; SELECT * FROM _timescaledb_catalog.metadata WHERE key LIKE 'dist_uuid'; -- Adding a frontend as a backend to a nondistributed node SELECT * FROM add_data_node('frontend_b', database => 'frontend_b', password => 'pass', if_not_exists => true); SELECT * FROM _timescaledb_catalog.metadata WHERE key LIKE 'dist_uuid'; \set ON_ERROR_STOP 1 -- Add a second backend to TEST_DB \c :TEST_DBNAME :ROLE_SUPERUSER; SET ROLE :ROLE_DEFAULT_CLUSTER_USER; SELECT * FROM add_data_node('data_node_2', database => 'backend_2', password => 'pass', if_not_exists => true); \c backend_2 SET ROLE :ROLE_DEFAULT_CLUSTER_USER; SELECT * FROM _timescaledb_catalog.metadata WHERE key LIKE 'dist_uuid'; \c :TEST_DBNAME :ROLE_SUPERUSER; SET ROLE :ROLE_DEFAULT_CLUSTER_USER; -- Now remove a backend from this distributed database and then add it to the other cluster \c backend_1 SET ROLE :ROLE_DEFAULT_CLUSTER_USER; SELECT * FROM _timescaledb_catalog.metadata WHERE key LIKE 'dist_uuid'; \c :TEST_DBNAME :ROLE_SUPERUSER; SET ROLE :ROLE_DEFAULT_CLUSTER_USER; SELECT * FROM delete_data_node('data_node_1', cascade => true); \c backend_1 SET ROLE :ROLE_DEFAULT_CLUSTER_USER; SELECT * FROM _timescaledb_catalog.metadata WHERE key LIKE 'dist_uuid'; \c frontend_b SET ROLE :ROLE_DEFAULT_CLUSTER_USER; SELECT * FROM _timescaledb_catalog.metadata WHERE key LIKE 'uuid' OR key LIKE 'dist_uuid'; SELECT * FROM add_data_node('data_node_2', database => 'backend_1', password => 'pass', if_not_exists => true); \c backend_1 SET ROLE :ROLE_DEFAULT_CLUSTER_USER; SELECT * FROM _timescaledb_catalog.metadata WHERE key LIKE 'dist_uuid'; -- Now remove both backends from frontend_b, then verify that they and frontend_b are now valid backends for TEST_DB \c frontend_b SET ROLE :ROLE_DEFAULT_CLUSTER_USER; SELECT * FROM delete_data_node('data_node_1', cascade => true); SELECT * FROM delete_data_node('data_node_2', cascade => true); SELECT * FROM _timescaledb_catalog.metadata WHERE key LIKE 'uuid' OR key LIKE 'dist_uuid'; \c :TEST_DBNAME :ROLE_SUPERUSER; SET ROLE :ROLE_DEFAULT_CLUSTER_USER; SELECT * FROM add_data_node('data_node_1', database => 'backend_1', password => 'pass', if_not_exists => true); SELECT * FROM add_data_node('data_node_3', database => 'backend_3', password => 'pass', if_not_exists => true); SELECT * FROM add_data_node('data_node_4', database => 'frontend_b', password => 'pass', if_not_exists => true); \c frontend_b SET ROLE :ROLE_DEFAULT_CLUSTER_USER; SELECT * FROM _timescaledb_catalog.metadata WHERE key LIKE 'uuid' OR key LIKE 'dist_uuid'; \c :TEST_DBNAME :ROLE_SUPERUSER; SET ROLE :ROLE_DEFAULT_CLUSTER_USER; -- Test space reporting functions for distributed and non-distributed tables CREATE TABLE nondisttable(time timestamptz PRIMARY KEY, device int CHECK (device > 0), temp float); CREATE TABLE disttable(time timestamptz PRIMARY KEY, device int CHECK (device > 0), temp float); SELECT * FROM create_hypertable('nondisttable', 'time'); SELECT * FROM create_distributed_hypertable('disttable', 'time'); INSERT INTO nondisttable VALUES ('2017-01-01 06:01', 1, 1.1), ('2017-01-01 08:01', 1, 1.2), ('2018-01-02 08:01', 2, 1.3), ('2019-01-01 09:11', 3, 2.1), ('2017-01-01 06:05', 1, 1.4); INSERT INTO disttable VALUES ('2017-01-01 06:01', 1, 1.1), ('2017-01-01 08:01', 1, 1.2), ('2018-01-02 08:01', 2, 1.3), ('2019-01-01 09:11', 3, 2.1), ('2017-01-01 06:05', 1, 1.4); SELECT * FROM timescaledb_information.data_node; SELECT * FROM timescaledb_information.hypertable; SELECT * FROM hypertable_relation_size('disttable'); SELECT * FROM hypertable_relation_size('nondisttable'); SELECT * FROM hypertable_data_node_relation_size('disttable'); SELECT * FROM hypertable_data_node_relation_size('nondisttable'); -- Clean up for future tests DROP TABLE disttable; SELECT * FROM delete_data_node('data_node_1', cascade => true); SELECT * FROM delete_data_node('data_node_2', cascade => true); SELECT * FROM delete_data_node('data_node_3', cascade => true); SELECT * FROM delete_data_node('data_node_4', cascade => true); DROP DATABASE frontend_b; DROP DATABASE backend_1; DROP DATABASE backend_2; DROP DATABASE backend_3;