From fbecf48a0324a12a500a22c04beaa03256174414 Mon Sep 17 00:00:00 2001 From: Brian Cloutier Date: Thu, 3 Aug 2017 14:03:55 +0300 Subject: [PATCH] Disallow adding primary nodes to non-default clusters --- .../distributed/citus--7.0-8--7.0-9.sql | 3 +++ src/backend/distributed/utils/node_metadata.c | 21 ++++++++++++------- src/include/distributed/worker_manager.h | 2 ++ .../expected/multi_cluster_management.out | 12 +++++++++++ .../regress/sql/multi_cluster_management.sql | 9 ++++++++ 5 files changed, 39 insertions(+), 8 deletions(-) diff --git a/src/backend/distributed/citus--7.0-8--7.0-9.sql b/src/backend/distributed/citus--7.0-8--7.0-9.sql index e74b966d8..8422a90dd 100644 --- a/src/backend/distributed/citus--7.0-8--7.0-9.sql +++ b/src/backend/distributed/citus--7.0-8--7.0-9.sql @@ -3,6 +3,9 @@ SET search_path = 'pg_catalog'; ALTER TABLE pg_dist_node ADD COLUMN nodecluster name NOT NULL DEFAULT 'default'; +ALTER TABLE pg_dist_node + ADD CONSTRAINT primaries_are_only_allowed_in_the_default_cluster + CHECK (NOT (nodecluster <> 'default' AND noderole = 'primary')); DROP FUNCTION master_add_node(text, integer, integer, noderole); CREATE FUNCTION master_add_node(nodename text, diff --git a/src/backend/distributed/utils/node_metadata.c b/src/backend/distributed/utils/node_metadata.c index ca04bc7d4..3627a3c85 100644 --- a/src/backend/distributed/utils/node_metadata.c +++ b/src/backend/distributed/utils/node_metadata.c @@ -726,16 +726,21 @@ AddNodeMetadata(char *nodeName, int32 nodePort, int32 groupId, char *nodeRack, } /* if nodeRole hasn't been added yet there's a constraint for one-node-per-group */ - if (nodeRole != InvalidOid) + if (nodeRole != InvalidOid && nodeRole == PrimaryNodeRoleId()) { - if (nodeRole == PrimaryNodeRoleId()) - { - WorkerNode *existingPrimaryNode = PrimaryNodeForGroup(groupId, NULL); + WorkerNode *existingPrimaryNode = PrimaryNodeForGroup(groupId, NULL); - if (existingPrimaryNode != NULL) - { - ereport(ERROR, (errmsg("group %d already has a primary node", groupId))); - } + if (existingPrimaryNode != NULL) + { + ereport(ERROR, (errmsg("group %d already has a primary node", groupId))); + } + } + + if (nodeRole == PrimaryNodeRoleId()) + { + if (strncmp(nodeCluster, WORKER_DEFAULT_CLUSTER, WORKER_LENGTH) != 0) + { + ereport(ERROR, (errmsg("primaries must be added to the default cluster"))); } } diff --git a/src/include/distributed/worker_manager.h b/src/include/distributed/worker_manager.h index 3b5fd7c22..7e2fb5da5 100644 --- a/src/include/distributed/worker_manager.h +++ b/src/include/distributed/worker_manager.h @@ -30,6 +30,8 @@ #define WORKER_RACK_TRIES 5 #define WORKER_DEFAULT_RACK "default" +#define WORKER_DEFAULT_CLUSTER "default" + /* * In memory representation of pg_dist_node table elements. The elements are hold in * WorkerNodeHash table. diff --git a/src/test/regress/expected/multi_cluster_management.out b/src/test/regress/expected/multi_cluster_management.out index 7e6c7d621..44730f82b 100644 --- a/src/test/regress/expected/multi_cluster_management.out +++ b/src/test/regress/expected/multi_cluster_management.out @@ -437,6 +437,9 @@ SELECT stop_metadata_sync_to_node('localhost', :worker_2_port); (1 row) +-- check that you can't add a primary to a non-default cluster +SELECT master_add_node('localhost', 9999, nodecluster => 'olap'); +ERROR: primaries must be added to the default cluster -- check that you can't add more than one primary to a group SELECT groupid AS worker_1_group FROM pg_dist_node WHERE nodeport = :worker_1_port \gset SELECT master_add_node('localhost', 9999, groupid => :worker_1_group, noderole => 'primary'); @@ -471,5 +474,14 @@ UPDATE pg_dist_node SET noderole = 'primary' WHERE groupid = :worker_1_group AND nodeport = 9998; ERROR: there cannot be two primary nodes in a group CONTEXT: PL/pgSQL function citus.pg_dist_node_trigger_func() line 18 at RAISE +-- check that you can't manually add a primary to a non-default cluster +INSERT INTO pg_dist_node (nodename, nodeport, groupid, noderole, nodecluster) + VALUES ('localhost', 5000, 1000, 'primary', 'olap'); +ERROR: new row for relation "pg_dist_node" violates check constraint "primaries_are_only_allowed_in_the_default_cluster" +DETAIL: Failing row contains (17, 1000, localhost, 5000, default, f, t, primary, olap). +UPDATE pg_dist_node SET nodecluster = 'olap' + WHERE nodeport = :worker_1_port; +ERROR: new row for relation "pg_dist_node" violates check constraint "primaries_are_only_allowed_in_the_default_cluster" +DETAIL: Failing row contains (13, 12, localhost, 57637, default, f, t, primary, olap). -- don't remove the secondary and unavailable nodes, check that no commands are sent to -- them in any of the remaining tests diff --git a/src/test/regress/sql/multi_cluster_management.sql b/src/test/regress/sql/multi_cluster_management.sql index 432d873ae..3651dbb85 100644 --- a/src/test/regress/sql/multi_cluster_management.sql +++ b/src/test/regress/sql/multi_cluster_management.sql @@ -184,6 +184,9 @@ DELETE FROM pg_dist_node; SELECT stop_metadata_sync_to_node('localhost', :worker_1_port); SELECT stop_metadata_sync_to_node('localhost', :worker_2_port); +-- check that you can't add a primary to a non-default cluster +SELECT master_add_node('localhost', 9999, nodecluster => 'olap'); + -- check that you can't add more than one primary to a group SELECT groupid AS worker_1_group FROM pg_dist_node WHERE nodeport = :worker_1_port \gset SELECT master_add_node('localhost', 9999, groupid => :worker_1_group, noderole => 'primary'); @@ -201,5 +204,11 @@ INSERT INTO pg_dist_node (nodename, nodeport, groupid, noderole) UPDATE pg_dist_node SET noderole = 'primary' WHERE groupid = :worker_1_group AND nodeport = 9998; +-- check that you can't manually add a primary to a non-default cluster +INSERT INTO pg_dist_node (nodename, nodeport, groupid, noderole, nodecluster) + VALUES ('localhost', 5000, 1000, 'primary', 'olap'); +UPDATE pg_dist_node SET nodecluster = 'olap' + WHERE nodeport = :worker_1_port; + -- don't remove the secondary and unavailable nodes, check that no commands are sent to -- them in any of the remaining tests