mirror of https://github.com/citusdata/citus.git
736 lines
62 KiB
Plaintext
736 lines
62 KiB
Plaintext
-- Test for create/drop database propagation.
|
|
-- This test is only executes for Postgres versions < 15.
|
|
-- For versions >= 15, pg15_create_drop_database_propagation.sql is used.
|
|
-- For versions >= 16, pg16_create_drop_database_propagation.sql is used.
|
|
-- Test the UDF that we use to issue database command during metadata sync.
|
|
SELECT pg_catalog.citus_internal_database_command(null);
|
|
ERROR: This is an internal Citus function can only be used in a distributed transaction
|
|
CREATE ROLE test_db_commands WITH LOGIN;
|
|
ALTER SYSTEM SET citus.enable_manual_metadata_changes_for_user TO 'test_db_commands';
|
|
SELECT pg_reload_conf();
|
|
pg_reload_conf
|
|
---------------------------------------------------------------------
|
|
t
|
|
(1 row)
|
|
|
|
SELECT pg_sleep(0.1);
|
|
pg_sleep
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
SET ROLE test_db_commands;
|
|
-- fails on null input
|
|
SELECT pg_catalog.citus_internal_database_command(null);
|
|
ERROR: command cannot be NULL
|
|
-- fails on non create / drop db command
|
|
SELECT pg_catalog.citus_internal_database_command('CREATE TABLE foo_bar(a int)');
|
|
ERROR: citus_internal_database_command() can only be used for CREATE DATABASE command by Citus.
|
|
SELECT pg_catalog.citus_internal_database_command('SELECT 1');
|
|
ERROR: citus_internal_database_command() can only be used for CREATE DATABASE command by Citus.
|
|
SELECT pg_catalog.citus_internal_database_command('asfsfdsg');
|
|
ERROR: syntax error at or near "asfsfdsg"
|
|
SELECT pg_catalog.citus_internal_database_command('');
|
|
ERROR: cannot execute multiple utility events
|
|
RESET ROLE;
|
|
ALTER ROLE test_db_commands nocreatedb;
|
|
SET ROLE test_db_commands;
|
|
-- make sure that pg_catalog.citus_internal_database_command doesn't cause privilege escalation
|
|
SELECT pg_catalog.citus_internal_database_command('CREATE DATABASE no_permissions');
|
|
ERROR: permission denied to create database
|
|
RESET ROLE;
|
|
DROP USER test_db_commands;
|
|
ALTER SYSTEM RESET citus.enable_manual_metadata_changes_for_user;
|
|
SELECT pg_reload_conf();
|
|
pg_reload_conf
|
|
---------------------------------------------------------------------
|
|
t
|
|
(1 row)
|
|
|
|
SELECT pg_sleep(0.1);
|
|
pg_sleep
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts3'
|
|
CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace';
|
|
\c - - - :worker_1_port
|
|
\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts4'
|
|
CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace';
|
|
\c - - - :worker_2_port
|
|
\set create_drop_db_tablespace :abs_srcdir '/tmp_check/ts5'
|
|
CREATE TABLESPACE create_drop_db_tablespace LOCATION :'create_drop_db_tablespace';
|
|
\c - - - :master_port
|
|
CREATE DATABASE local_database;
|
|
NOTICE: Citus partially supports CREATE DATABASE for distributed databases
|
|
DETAIL: Citus does not propagate CREATE DATABASE command to workers
|
|
HINT: You can manually create a database and its extensions on workers.
|
|
-- check that it's only created for coordinator
|
|
SELECT * FROM public.check_database_on_all_nodes('local_database') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "local_database", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
DROP DATABASE local_database;
|
|
-- and is dropped
|
|
SELECT * FROM public.check_database_on_all_nodes('local_database') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
\c - - - :worker_1_port
|
|
CREATE DATABASE local_database;
|
|
NOTICE: Citus partially supports CREATE DATABASE for distributed databases
|
|
DETAIL: Citus does not propagate CREATE DATABASE command to workers
|
|
HINT: You can manually create a database and its extensions on workers.
|
|
-- check that it's only created for coordinator
|
|
SELECT * FROM public.check_database_on_all_nodes('local_database') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (local) | {"database_properties": {"datacl": null, "datname": "local_database", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
DROP DATABASE local_database;
|
|
-- and is dropped
|
|
SELECT * FROM public.check_database_on_all_nodes('local_database') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (local) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
\c - - - :master_port
|
|
create user create_drop_db_test_user;
|
|
set citus.enable_create_database_propagation=on;
|
|
-- Tests for create database propagation with template0 which should fail
|
|
CREATE DATABASE mydatabase
|
|
WITH OWNER = create_drop_db_test_user
|
|
TEMPLATE = 'template0'
|
|
ENCODING = 'UTF8'
|
|
CONNECTION LIMIT = 10
|
|
TABLESPACE = create_drop_db_tablespace
|
|
ALLOW_CONNECTIONS = true
|
|
IS_TEMPLATE = false;
|
|
ERROR: Only template1 is supported as template parameter for CREATE DATABASE
|
|
CREATE DATABASE mydatabase_1
|
|
WITH template=template1
|
|
OWNER = create_drop_db_test_user
|
|
ENCODING = 'UTF8'
|
|
CONNECTION LIMIT = 10
|
|
TABLESPACE = create_drop_db_tablespace
|
|
ALLOW_CONNECTIONS = true
|
|
IS_TEMPLATE = false;
|
|
SELECT * FROM public.check_database_on_all_nodes('mydatabase_1') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "mydatabase_1", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "create_drop_db_tablespace", "daticurules": null, "datallowconn": true, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "mydatabase_1", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "create_drop_db_tablespace", "daticurules": null, "datallowconn": true, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "mydatabase_1", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "create_drop_db_tablespace", "daticurules": null, "datallowconn": true, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
-- Test LC / LOCALE settings that don't match the ones provided in template db.
|
|
-- All should throw an error on the coordinator.
|
|
CREATE DATABASE lc_collate_test LC_COLLATE = 'C.UTF-8';
|
|
ERROR: new collation (C.UTF-8) is incompatible with the collation of the template database (C)
|
|
HINT: Use the same collation as in the template database, or use template0 as template.
|
|
CREATE DATABASE lc_ctype_test LC_CTYPE = 'C.UTF-8';
|
|
ERROR: new LC_CTYPE (C.UTF-8) is incompatible with the LC_CTYPE of the template database (C)
|
|
HINT: Use the same LC_CTYPE as in the template database, or use template0 as template.
|
|
CREATE DATABASE locale_test LOCALE = 'C.UTF-8';
|
|
ERROR: new collation (C.UTF-8) is incompatible with the collation of the template database (C)
|
|
HINT: Use the same collation as in the template database, or use template0 as template.
|
|
CREATE DATABASE lc_collate_lc_ctype_test LC_COLLATE = 'C.UTF-8' LC_CTYPE = 'C.UTF-8';
|
|
ERROR: new collation (C.UTF-8) is incompatible with the collation of the template database (C)
|
|
HINT: Use the same collation as in the template database, or use template0 as template.
|
|
-- Test LC / LOCALE settings that match the ones provided in template db.
|
|
CREATE DATABASE lc_collate_test LC_COLLATE = 'C';
|
|
CREATE DATABASE lc_ctype_test LC_CTYPE = 'C';
|
|
CREATE DATABASE locale_test LOCALE = 'C';
|
|
CREATE DATABASE lc_collate_lc_ctype_test LC_COLLATE = 'C' LC_CTYPE = 'C';
|
|
SELECT * FROM public.check_database_on_all_nodes('lc_collate_test') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "lc_collate_test", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "lc_collate_test", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "lc_collate_test", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
SELECT * FROM public.check_database_on_all_nodes('lc_ctype_test') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "lc_ctype_test", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "lc_ctype_test", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "lc_ctype_test", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
SELECT * FROM public.check_database_on_all_nodes('locale_test') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "locale_test", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "locale_test", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "locale_test", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
SELECT * FROM public.check_database_on_all_nodes('lc_collate_lc_ctype_test') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "lc_collate_lc_ctype_test", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "lc_collate_lc_ctype_test", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "lc_collate_lc_ctype_test", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
DROP DATABASE lc_collate_test;
|
|
DROP DATABASE lc_ctype_test;
|
|
DROP DATABASE locale_test;
|
|
DROP DATABASE lc_collate_lc_ctype_test;
|
|
-- ALTER TABLESPACE .. RENAME TO .. is not supported, so we need to rename it manually.
|
|
SELECT result FROM run_command_on_all_nodes(
|
|
$$
|
|
ALTER TABLESPACE create_drop_db_tablespace RENAME TO "ts-needs\!escape"
|
|
$$
|
|
);
|
|
result
|
|
---------------------------------------------------------------------
|
|
ALTER TABLESPACE
|
|
ALTER TABLESPACE
|
|
ALTER TABLESPACE
|
|
(3 rows)
|
|
|
|
CREATE USER "role-needs\!escape";
|
|
CREATE DATABASE "db-needs\!escape" owner "role-needs\!escape" tablespace "ts-needs\!escape";
|
|
-- Rename it to make check_database_on_all_nodes happy.
|
|
-- Today we don't support ALTER DATABASE .. RENAME TO .., so need to propagate it manually.
|
|
SELECT result FROM run_command_on_all_nodes(
|
|
$$
|
|
ALTER DATABASE "db-needs\!escape" RENAME TO db_needs_escape
|
|
$$
|
|
);
|
|
result
|
|
---------------------------------------------------------------------
|
|
ALTER DATABASE
|
|
ALTER DATABASE
|
|
ALTER DATABASE
|
|
(3 rows)
|
|
|
|
SELECT * FROM public.check_database_on_all_nodes('db_needs_escape') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "db_needs_escape", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "role-needs\\!escape", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "db_needs_escape", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "role-needs\\!escape", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "db_needs_escape", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "role-needs\\!escape", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
-- test database syncing after node addition
|
|
select 1 from citus_remove_node('localhost', :worker_2_port);
|
|
?column?
|
|
---------------------------------------------------------------------
|
|
1
|
|
(1 row)
|
|
|
|
--test with is_template true and allow connections false
|
|
CREATE DATABASE mydatabase
|
|
OWNER = create_drop_db_test_user
|
|
CONNECTION LIMIT = 10
|
|
ENCODING = 'UTF8'
|
|
TABLESPACE = "ts-needs\!escape"
|
|
ALLOW_CONNECTIONS = false
|
|
IS_TEMPLATE = false;
|
|
SELECT * FROM public.check_database_on_all_nodes('mydatabase') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "mydatabase", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": false, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "mydatabase", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": false, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(2 rows)
|
|
|
|
SET citus.metadata_sync_mode to 'transactional';
|
|
select 1 from citus_add_node('localhost', :worker_2_port);
|
|
?column?
|
|
---------------------------------------------------------------------
|
|
1
|
|
(1 row)
|
|
|
|
SELECT * FROM public.check_database_on_all_nodes('mydatabase') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "mydatabase", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": false, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "mydatabase", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": false, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "mydatabase", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": false, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
SELECT * FROM public.check_database_on_all_nodes('mydatabase_1') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "mydatabase_1", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "mydatabase_1", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "mydatabase_1", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
SELECT * FROM public.check_database_on_all_nodes('db_needs_escape') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "db_needs_escape", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "role-needs\\!escape", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "db_needs_escape", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "role-needs\\!escape", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "db_needs_escape", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "role-needs\\!escape", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
select 1 from citus_remove_node('localhost', :worker_2_port);
|
|
?column?
|
|
---------------------------------------------------------------------
|
|
1
|
|
(1 row)
|
|
|
|
SET citus.metadata_sync_mode to 'nontransactional';
|
|
select 1 from citus_add_node('localhost', :worker_2_port);
|
|
?column?
|
|
---------------------------------------------------------------------
|
|
1
|
|
(1 row)
|
|
|
|
RESET citus.metadata_sync_mode;
|
|
SELECT * FROM public.check_database_on_all_nodes('mydatabase') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "mydatabase", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": false, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "mydatabase", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": false, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "mydatabase", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": false, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
SELECT * FROM public.check_database_on_all_nodes('mydatabase_1') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "mydatabase_1", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "mydatabase_1", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "mydatabase_1", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
SELECT * FROM public.check_database_on_all_nodes('db_needs_escape') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "db_needs_escape", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "role-needs\\!escape", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "db_needs_escape", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "role-needs\\!escape", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "db_needs_escape", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "role-needs\\!escape", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
SELECT citus_disable_node_and_wait('localhost', :worker_1_port, true);
|
|
citus_disable_node_and_wait
|
|
---------------------------------------------------------------------
|
|
|
|
(1 row)
|
|
|
|
CREATE DATABASE test_node_activation;
|
|
SELECT 1 FROM citus_activate_node('localhost', :worker_1_port);
|
|
?column?
|
|
---------------------------------------------------------------------
|
|
1
|
|
(1 row)
|
|
|
|
SELECT * FROM public.check_database_on_all_nodes('mydatabase') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "mydatabase", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": false, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "mydatabase", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": false, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "mydatabase", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": false, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
SELECT * FROM public.check_database_on_all_nodes('mydatabase_1') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "mydatabase_1", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "mydatabase_1", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "mydatabase_1", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": 10, "daticulocale": null, "datistemplate": false, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
SELECT * FROM public.check_database_on_all_nodes('db_needs_escape') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "db_needs_escape", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "role-needs\\!escape", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "db_needs_escape", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "role-needs\\!escape", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "db_needs_escape", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "role-needs\\!escape", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
SELECT * FROM public.check_database_on_all_nodes('test_node_activation') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "test_node_activation", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "test_node_activation", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "test_node_activation", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
SET citus.log_remote_commands = true;
|
|
set citus.grep_remote_commands = '%DROP DATABASE%';
|
|
drop database mydatabase;
|
|
NOTICE: issuing DROP DATABASE mydatabase
|
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
|
NOTICE: issuing DROP DATABASE mydatabase
|
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
|
SET citus.log_remote_commands = false;
|
|
-- check that we actually drop the database
|
|
drop database mydatabase_1;
|
|
SELECT * FROM public.check_database_on_all_nodes('mydatabase_1') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
SELECT * FROM public.check_database_on_all_nodes('mydatabase') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
-- create a template database with all options set and allow connections false
|
|
CREATE DATABASE my_template_database
|
|
WITH OWNER = create_drop_db_test_user
|
|
ENCODING = 'UTF8'
|
|
TABLESPACE = "ts-needs\!escape"
|
|
ALLOW_CONNECTIONS = false
|
|
IS_TEMPLATE = true;
|
|
SELECT * FROM public.check_database_on_all_nodes('my_template_database') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "my_template_database", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": false, "datconnlimit": -1, "daticulocale": null, "datistemplate": true, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "my_template_database", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": false, "datconnlimit": -1, "daticulocale": null, "datistemplate": true, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "my_template_database", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "ts-needs\\!escape", "daticurules": null, "datallowconn": false, "datconnlimit": -1, "daticulocale": null, "datistemplate": true, "database_owner": "create_drop_db_test_user", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
--template databases could not be dropped so we need to change the template flag
|
|
SELECT result from run_command_on_all_nodes(
|
|
$$
|
|
UPDATE pg_database SET datistemplate = false WHERE datname = 'my_template_database'
|
|
$$
|
|
) ORDER BY result;
|
|
result
|
|
---------------------------------------------------------------------
|
|
UPDATE 1
|
|
UPDATE 1
|
|
UPDATE 1
|
|
(3 rows)
|
|
|
|
SET citus.log_remote_commands = true;
|
|
set citus.grep_remote_commands = '%DROP DATABASE%';
|
|
drop database my_template_database;
|
|
NOTICE: issuing DROP DATABASE my_template_database
|
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
|
NOTICE: issuing DROP DATABASE my_template_database
|
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
|
SET citus.log_remote_commands = false;
|
|
SELECT * FROM public.check_database_on_all_nodes('my_template_database') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
--tests for special characters in database name
|
|
set citus.enable_create_database_propagation=on;
|
|
SET citus.log_remote_commands = true;
|
|
set citus.grep_remote_commands = '%CREATE DATABASE%';
|
|
create database "mydatabase#1'2";
|
|
NOTICE: issuing CREATE DATABASE "mydatabase#1'2"
|
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
|
NOTICE: issuing CREATE DATABASE "mydatabase#1'2"
|
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
|
set citus.grep_remote_commands = '%DROP DATABASE%';
|
|
drop database if exists "mydatabase#1'2";
|
|
NOTICE: issuing DROP DATABASE IF EXISTS "mydatabase#1'2"
|
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
|
NOTICE: issuing DROP DATABASE IF EXISTS "mydatabase#1'2"
|
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
|
reset citus.grep_remote_commands;
|
|
reset citus.log_remote_commands;
|
|
-- it doesn't fail thanks to "if exists"
|
|
drop database if exists "mydatabase#1'2";
|
|
NOTICE: database "mydatabase#1'2" does not exist, skipping
|
|
-- recreate it to verify that it's actually dropped
|
|
create database "mydatabase#1'2";
|
|
drop database "mydatabase#1'2";
|
|
-- second time we try to drop it, it fails due to lack of "if exists"
|
|
drop database "mydatabase#1'2";
|
|
ERROR: database "mydatabase#1'2" does not exist
|
|
\c - - - :worker_1_port
|
|
SET citus.enable_create_database_propagation TO ON;
|
|
-- show that dropping the database from workers is not allowed when citus.enable_create_database_propagation is on
|
|
DROP DATABASE db_needs_escape;
|
|
ERROR: operation is not allowed on this node
|
|
HINT: Connect to the coordinator and run it again.
|
|
-- and the same applies to create database too
|
|
create database error_test;
|
|
ERROR: operation is not allowed on this node
|
|
HINT: Connect to the coordinator and run it again.
|
|
\c - - - :master_port
|
|
SET citus.enable_create_database_propagation TO ON;
|
|
DROP DATABASE test_node_activation;
|
|
DROP DATABASE db_needs_escape;
|
|
DROP USER "role-needs\!escape";
|
|
-- drop database with force options test
|
|
create database db_force_test;
|
|
SET citus.log_remote_commands = true;
|
|
set citus.grep_remote_commands = '%DROP DATABASE%';
|
|
drop database db_force_test with (force);
|
|
NOTICE: issuing DROP DATABASE db_force_test WITH ( FORCE )
|
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
|
NOTICE: issuing DROP DATABASE db_force_test WITH ( FORCE )
|
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
|
reset citus.log_remote_commands;
|
|
reset citus.grep_remote_commands;
|
|
SELECT * FROM public.check_database_on_all_nodes('db_force_test') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
-- test that we won't propagate non-distributed databases in citus_add_node
|
|
select 1 from citus_remove_node('localhost', :worker_2_port);
|
|
?column?
|
|
---------------------------------------------------------------------
|
|
1
|
|
(1 row)
|
|
|
|
SET citus.enable_create_database_propagation TO off;
|
|
CREATE DATABASE non_distributed_db;
|
|
NOTICE: Citus partially supports CREATE DATABASE for distributed databases
|
|
DETAIL: Citus does not propagate CREATE DATABASE command to workers
|
|
HINT: You can manually create a database and its extensions on workers.
|
|
SET citus.enable_create_database_propagation TO on;
|
|
create database distributed_db;
|
|
select 1 from citus_add_node('localhost', :worker_2_port);
|
|
?column?
|
|
---------------------------------------------------------------------
|
|
1
|
|
(1 row)
|
|
|
|
--non_distributed_db should not be propagated to worker_2
|
|
SELECT * FROM public.check_database_on_all_nodes('non_distributed_db') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "non_distributed_db", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": null, "pg_dist_object_record_for_db_exists": false, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
--distributed_db should be propagated to worker_2
|
|
SELECT * FROM public.check_database_on_all_nodes('distributed_db') ORDER BY node_type;
|
|
node_type | result
|
|
---------------------------------------------------------------------
|
|
coordinator (local) | {"database_properties": {"datacl": null, "datname": "distributed_db", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "distributed_db", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
worker node (remote) | {"database_properties": {"datacl": null, "datname": "distributed_db", "datctype": "C", "encoding": "UTF8", "datcollate": "C", "tablespace": "pg_default", "daticurules": null, "datallowconn": true, "datconnlimit": -1, "daticulocale": null, "datistemplate": false, "database_owner": "postgres", "datcollversion": null, "datlocprovider": "c"}, "pg_dist_object_record_for_db_exists": true, "stale_pg_dist_object_record_for_a_db_exists": false}
|
|
(3 rows)
|
|
|
|
--clean up resources created by this test
|
|
drop database distributed_db;
|
|
set citus.enable_create_database_propagation TO off;
|
|
drop database non_distributed_db;
|
|
-- test role grants on DATABASE in metadata sync
|
|
SET citus.enable_create_database_propagation TO on;
|
|
CREATE ROLE db_role_grants_test_role_exists_on_node_2;
|
|
select 1 from citus_remove_node('localhost', :worker_2_port);
|
|
?column?
|
|
---------------------------------------------------------------------
|
|
1
|
|
(1 row)
|
|
|
|
CREATE DATABASE db_role_grants_test;
|
|
revoke connect,temp,temporary on database db_role_grants_test from public;
|
|
SET citus.log_remote_commands = true;
|
|
set citus.grep_remote_commands = '%CREATE ROLE%';
|
|
CREATE ROLE db_role_grants_test_role_missing_on_node_2;
|
|
NOTICE: issuing SELECT worker_create_or_alter_role('db_role_grants_test_role_missing_on_node_2', 'CREATE ROLE db_role_grants_test_role_missing_on_node_2', 'ALTER ROLE db_role_grants_test_role_missing_on_node_2')
|
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
|
RESET citus.log_remote_commands ;
|
|
RESET citus.grep_remote_commands;
|
|
-- check the privileges before grant
|
|
SELECT result from run_command_on_all_nodes(
|
|
$$
|
|
select has_database_privilege('db_role_grants_test_role_exists_on_node_2','db_role_grants_test', 'CREATE')
|
|
$$
|
|
) ORDER BY result;
|
|
result
|
|
---------------------------------------------------------------------
|
|
f
|
|
f
|
|
(2 rows)
|
|
|
|
SELECT result from run_command_on_all_nodes(
|
|
$$
|
|
select has_database_privilege('db_role_grants_test_role_exists_on_node_2','db_role_grants_test', 'TEMPORARY')
|
|
$$
|
|
) ORDER BY result;
|
|
result
|
|
---------------------------------------------------------------------
|
|
f
|
|
f
|
|
(2 rows)
|
|
|
|
SELECT result from run_command_on_all_nodes(
|
|
$$
|
|
select has_database_privilege('db_role_grants_test_role_exists_on_node_2','db_role_grants_test', 'CONNECT')
|
|
$$
|
|
) ORDER BY result;
|
|
result
|
|
---------------------------------------------------------------------
|
|
f
|
|
f
|
|
(2 rows)
|
|
|
|
SELECT result from run_command_on_all_nodes(
|
|
$$
|
|
select has_database_privilege('db_role_grants_test_role_missing_on_node_2','db_role_grants_test', 'CREATE')
|
|
$$
|
|
) ORDER BY result;
|
|
result
|
|
---------------------------------------------------------------------
|
|
f
|
|
f
|
|
(2 rows)
|
|
|
|
SELECT result from run_command_on_all_nodes(
|
|
$$
|
|
select has_database_privilege('db_role_grants_test_role_missing_on_node_2','db_role_grants_test', 'TEMPORARY')
|
|
$$
|
|
) ORDER BY result;
|
|
result
|
|
---------------------------------------------------------------------
|
|
f
|
|
f
|
|
(2 rows)
|
|
|
|
SELECT result from run_command_on_all_nodes(
|
|
$$
|
|
select has_database_privilege('db_role_grants_test_role_missing_on_node_2','db_role_grants_test', 'CONNECT')
|
|
$$
|
|
) ORDER BY result;
|
|
result
|
|
---------------------------------------------------------------------
|
|
f
|
|
f
|
|
(2 rows)
|
|
|
|
SET citus.log_remote_commands = true;
|
|
set citus.grep_remote_commands = '%GRANT%';
|
|
grant CONNECT,TEMPORARY,CREATE on DATABASE db_role_grants_test to db_role_grants_test_role_exists_on_node_2;
|
|
NOTICE: issuing GRANT connect, temporary, create ON DATABASE db_role_grants_test TO db_role_grants_test_role_exists_on_node_2;
|
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
|
grant CONNECT,TEMPORARY,CREATE on DATABASE db_role_grants_test to db_role_grants_test_role_missing_on_node_2;
|
|
NOTICE: issuing GRANT connect, temporary, create ON DATABASE db_role_grants_test TO db_role_grants_test_role_missing_on_node_2;
|
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
|
select 1 from citus_add_node('localhost', :worker_2_port);
|
|
NOTICE: issuing CREATE SCHEMA IF NOT EXISTS public AUTHORIZATION pg_database_owner;SET ROLE pg_database_owner;GRANT USAGE ON SCHEMA public TO pg_database_owner;;GRANT CREATE ON SCHEMA public TO pg_database_owner;;RESET ROLE;SET ROLE pg_database_owner;GRANT USAGE ON SCHEMA public TO PUBLIC;;RESET ROLE
|
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
|
NOTICE: issuing CREATE SCHEMA IF NOT EXISTS information_schema AUTHORIZATION postgres;SET ROLE postgres;GRANT USAGE ON SCHEMA information_schema TO postgres;;GRANT CREATE ON SCHEMA information_schema TO postgres;;RESET ROLE;SET ROLE postgres;GRANT USAGE ON SCHEMA information_schema TO PUBLIC;;RESET ROLE
|
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
|
NOTICE: issuing SET citus.enable_ddl_propagation TO 'off';SET ROLE postgres;GRANT CONNECT ON DATABASE db_role_grants_test TO postgres;;GRANT CREATE ON DATABASE db_role_grants_test TO postgres;;GRANT TEMPORARY ON DATABASE db_role_grants_test TO postgres;;RESET ROLE;SET ROLE postgres;GRANT CONNECT ON DATABASE db_role_grants_test TO db_role_grants_test_role_exists_on_node_2;;GRANT CREATE ON DATABASE db_role_grants_test TO db_role_grants_test_role_exists_on_node_2;;GRANT TEMPORARY ON DATABASE db_role_grants_test TO db_role_grants_test_role_exists_on_node_2;;RESET ROLE;SET ROLE postgres;GRANT CONNECT ON DATABASE db_role_grants_test TO db_role_grants_test_role_missing_on_node_2;;GRANT CREATE ON DATABASE db_role_grants_test TO db_role_grants_test_role_missing_on_node_2;;GRANT TEMPORARY ON DATABASE db_role_grants_test TO db_role_grants_test_role_missing_on_node_2;;RESET ROLE;SET citus.enable_ddl_propagation TO 'on'
|
|
DETAIL: on server postgres@localhost:xxxxx connectionId: xxxxxxx
|
|
?column?
|
|
---------------------------------------------------------------------
|
|
1
|
|
(1 row)
|
|
|
|
SELECT result from run_command_on_all_nodes(
|
|
$$
|
|
select has_database_privilege('db_role_grants_test_role_exists_on_node_2','db_role_grants_test', 'CREATE')
|
|
$$
|
|
) ORDER BY result;
|
|
result
|
|
---------------------------------------------------------------------
|
|
t
|
|
t
|
|
t
|
|
(3 rows)
|
|
|
|
SELECT result from run_command_on_all_nodes(
|
|
$$
|
|
select has_database_privilege('db_role_grants_test_role_exists_on_node_2','db_role_grants_test', 'TEMPORARY')
|
|
$$
|
|
) ORDER BY result;
|
|
result
|
|
---------------------------------------------------------------------
|
|
t
|
|
t
|
|
t
|
|
(3 rows)
|
|
|
|
SELECT result from run_command_on_all_nodes(
|
|
$$
|
|
select has_database_privilege('db_role_grants_test_role_exists_on_node_2','db_role_grants_test', 'CONNECT')
|
|
$$
|
|
) ORDER BY result;
|
|
result
|
|
---------------------------------------------------------------------
|
|
t
|
|
t
|
|
t
|
|
(3 rows)
|
|
|
|
SELECT result from run_command_on_all_nodes(
|
|
$$
|
|
select has_database_privilege('db_role_grants_test_role_missing_on_node_2','db_role_grants_test', 'CREATE')
|
|
$$
|
|
) ORDER BY result;
|
|
result
|
|
---------------------------------------------------------------------
|
|
t
|
|
t
|
|
t
|
|
(3 rows)
|
|
|
|
SELECT result from run_command_on_all_nodes(
|
|
$$
|
|
select has_database_privilege('db_role_grants_test_role_missing_on_node_2','db_role_grants_test', 'TEMPORARY')
|
|
$$
|
|
) ORDER BY result;
|
|
result
|
|
---------------------------------------------------------------------
|
|
t
|
|
t
|
|
t
|
|
(3 rows)
|
|
|
|
SELECT result from run_command_on_all_nodes(
|
|
$$
|
|
select has_database_privilege('db_role_grants_test_role_missing_on_node_2','db_role_grants_test', 'CONNECT')
|
|
$$
|
|
) ORDER BY result;
|
|
result
|
|
---------------------------------------------------------------------
|
|
t
|
|
t
|
|
t
|
|
(3 rows)
|
|
|
|
DROP DATABASE db_role_grants_test;
|
|
DROP ROLE db_role_grants_test_role_exists_on_node_2;
|
|
DROP ROLE db_role_grants_test_role_missing_on_node_2;
|
|
--clean up resources created by this test
|
|
-- DROP TABLESPACE is not supported, so we need to drop it manually.
|
|
SELECT result FROM run_command_on_all_nodes(
|
|
$$
|
|
drop tablespace "ts-needs\!escape"
|
|
$$
|
|
);
|
|
result
|
|
---------------------------------------------------------------------
|
|
DROP TABLESPACE
|
|
DROP TABLESPACE
|
|
DROP TABLESPACE
|
|
(3 rows)
|
|
|
|
drop user create_drop_db_test_user;
|