Add force option to master_remove_node

We can now remove nodes from cluster regardless of them
having an active shard placement.
pull/1092/head
Murat Tuncer 2017-01-04 12:28:53 +03:00
parent 350b1e6431
commit 205f6563fa
8 changed files with 82 additions and 17 deletions

View File

@ -9,7 +9,7 @@ EXTVERSIONS = 5.0 5.0-1 5.0-2 \
5.1-1 5.1-2 5.1-3 5.1-4 5.1-5 5.1-6 5.1-7 5.1-8 \
5.2-1 5.2-2 5.2-3 5.2-4 \
6.0-1 6.0-2 6.0-3 6.0-4 6.0-5 6.0-6 6.0-7 6.0-8 6.0-9 6.0-10 6.0-11 6.0-12 6.0-13 6.0-14 6.0-15 6.0-16 6.0-17 6.0-18 \
6.1-1 6.1-2 6.1-3 6.1-4 6.1-5 6.1-6 6.1-7 6.1-8 6.1-9 6.1-10 6.1-11 6.1-12
6.1-1 6.1-2 6.1-3 6.1-4 6.1-5 6.1-6 6.1-7 6.1-8 6.1-9 6.1-10 6.1-11 6.1-12 6.1-13
# All citus--*.sql files in the source directory
DATA = $(patsubst $(citus_abs_srcdir)/%.sql,%.sql,$(wildcard $(citus_abs_srcdir)/$(EXTENSION)--*--*.sql))
@ -119,6 +119,8 @@ $(EXTENSION)--6.1-11.sql: $(EXTENSION)--6.1-10.sql $(EXTENSION)--6.1-10--6.1-11.
cat $^ > $@
$(EXTENSION)--6.1-12.sql: $(EXTENSION)--6.1-11.sql $(EXTENSION)--6.1-11--6.1-12.sql
cat $^ > $@
$(EXTENSION)--6.1-13.sql: $(EXTENSION)--6.1-12.sql $(EXTENSION)--6.1-12--6.1-13.sql
cat $^ > $@
NO_PGXS = 1

View File

@ -0,0 +1,15 @@
/* citus--6.1-12--6.1-13.sql */
SET search_path = 'pg_catalog';
DROP FUNCTION IF EXISTS master_remove_node(nodename text, nodeport integer);
CREATE FUNCTION master_remove_node(nodename text, nodeport integer,
force bool DEFAULT false)
RETURNS void
LANGUAGE C STRICT
AS 'MODULE_PATHNAME', $$master_remove_node$$;
COMMENT ON FUNCTION master_remove_node(nodename text, nodeport integer, force bool)
IS 'remove node from the cluster';
RESET search_path;

View File

@ -1,6 +1,6 @@
# Citus extension
comment = 'Citus distributed database'
default_version = '6.1-12'
default_version = '6.1-13'
module_pathname = '$libdir/citus'
relocatable = false
schema = pg_catalog

View File

@ -111,6 +111,7 @@ master_remove_node(PG_FUNCTION_ARGS)
{
text *nodeName = PG_GETARG_TEXT_P(0);
int32 nodePort = PG_GETARG_INT32(1);
bool force = PG_GETARG_BOOL(2);
char *nodeNameString = text_to_cstring(nodeName);
char *nodeDeleteCommand = NULL;
bool hasShardPlacements = false;
@ -120,7 +121,16 @@ master_remove_node(PG_FUNCTION_ARGS)
EnsureSuperUser();
hasShardPlacements = NodeHasActiveShardPlacements(nodeNameString, nodePort);
if (hasShardPlacements)
if (hasShardPlacements && force)
{
ereport(NOTICE, (errmsg("Node %s:%d has active shard placements. Some "
"queries may fail after this operation. Use "
"select master_add_node('%s', %d) to add this "
"node back.",
nodeNameString, nodePort, nodeNameString,
nodePort)));
}
else if (hasShardPlacements)
{
ereport(ERROR, (errmsg("you cannot remove a node which has active "
"shard placements")));

View File

@ -101,6 +101,31 @@ SELECT master_get_active_worker_nodes();
(localhost,57637)
(2 rows)
-- try to remove a node with active placements with force = true and see that node is removed
SELECT master_remove_node('localhost', :worker_2_port, true);
NOTICE: Node localhost:57638 has active shard placements. Some queries may fail after this operation. Use select master_add_node('localhost', 57638) to add this node back.
master_remove_node
--------------------
(1 row)
SELECT master_get_active_worker_nodes();
master_get_active_worker_nodes
--------------------------------
(localhost,57637)
(1 row)
-- restore the node for next tests
SELECT master_add_node('localhost', :worker_2_port);
master_add_node
---------------------------------
(4,4,localhost,57638,default,f)
(1 row)
-- try to remove a node with active placements with force = false and see that node
-- removal is failed
SELECT master_remove_node('localhost', :worker_2_port, false);
ERROR: you cannot remove a node which has active shard placements
-- mark all placements in the candidate node as inactive
UPDATE pg_dist_shard_placement SET shardstate=3 WHERE nodeport=:worker_2_port;
SELECT shardid, shardstate, nodename, nodeport FROM pg_dist_shard_placement WHERE nodeport=:worker_2_port;
@ -133,7 +158,7 @@ SELECT master_get_active_worker_nodes();
SELECT master_add_node('localhost', :worker_2_port);
master_add_node
---------------------------------
(4,4,localhost,57638,default,f)
(5,5,localhost,57638,default,f)
(1 row)
UPDATE pg_dist_shard_placement SET shardstate=1 WHERE nodeport=:worker_2_port;
@ -149,7 +174,7 @@ UPDATE pg_dist_node SET hasmetadata=true WHERE nodeport=:worker_1_port;
SELECT master_add_node('localhost', :worker_2_port);
master_add_node
---------------------------------
(5,5,localhost,57638,default,f)
(6,6,localhost,57638,default,f)
(1 row)
\c - - - :worker_1_port
@ -178,7 +203,7 @@ UPDATE pg_dist_node SET hasmetadata=false WHERE nodeport=:worker_1_port;
SELECT master_add_node('localhost', :worker_2_port);
master_add_node
---------------------------------
(6,6,localhost,57638,default,f)
(7,7,localhost,57638,default,f)
(1 row)
\c - - - :worker_1_port
@ -208,14 +233,14 @@ SELECT
master_add_node('localhost', :worker_2_port);
master_add_node | master_add_node
---------------------------------+---------------------------------
(7,7,localhost,57637,default,f) | (8,8,localhost,57638,default,f)
(8,8,localhost,57637,default,f) | (9,9,localhost,57638,default,f)
(1 row)
SELECT * FROM pg_dist_node ORDER BY nodeid;
nodeid | groupid | nodename | nodeport | noderack | hasmetadata
--------+---------+-----------+----------+----------+-------------
7 | 7 | localhost | 57637 | default | f
8 | 8 | localhost | 57638 | default | f
8 | 8 | localhost | 57637 | default | f
9 | 9 | localhost | 57638 | default | f
(2 rows)
-- check that mixed add/remove node commands work fine inside transaction
@ -227,9 +252,9 @@ SELECT master_remove_node('localhost', :worker_2_port);
(1 row)
SELECT master_add_node('localhost', :worker_2_port);
master_add_node
---------------------------------
(9,9,localhost,57638,default,f)
master_add_node
-----------------------------------
(10,10,localhost,57638,default,f)
(1 row)
SELECT master_remove_node('localhost', :worker_2_port);
@ -249,7 +274,7 @@ BEGIN;
SELECT master_add_node('localhost', :worker_2_port);
master_add_node
-----------------------------------
(10,10,localhost,57638,default,f)
(11,11,localhost,57638,default,f)
(1 row)
SELECT master_remove_node('localhost', :worker_2_port);
@ -261,7 +286,7 @@ SELECT master_remove_node('localhost', :worker_2_port);
SELECT master_add_node('localhost', :worker_2_port);
master_add_node
-----------------------------------
(11,11,localhost,57638,default,f)
(12,12,localhost,57638,default,f)
(1 row)
COMMIT;
@ -289,13 +314,13 @@ SELECT master_remove_node(nodename, nodeport) FROM pg_dist_node;
SELECT master_add_node('localhost', :worker_1_port);
master_add_node
-----------------------------------
(12,12,localhost,57637,default,f)
(13,13,localhost,57637,default,f)
(1 row)
SELECT master_add_node('localhost', :worker_2_port);
master_add_node
-----------------------------------
(13,13,localhost,57638,default,f)
(14,14,localhost,57638,default,f)
(1 row)
-- check that a distributed table can be created after adding a node in a transaction
@ -309,7 +334,7 @@ BEGIN;
SELECT master_add_node('localhost', :worker_2_port);
master_add_node
-----------------------------------
(14,14,localhost,57638,default,f)
(15,15,localhost,57638,default,f)
(1 row)
CREATE TABLE temp(col1 text, col2 int);

View File

@ -70,6 +70,7 @@ ALTER EXTENSION citus UPDATE TO '6.1-9';
ALTER EXTENSION citus UPDATE TO '6.1-10';
ALTER EXTENSION citus UPDATE TO '6.1-11';
ALTER EXTENSION citus UPDATE TO '6.1-12';
ALTER EXTENSION citus UPDATE TO '6.1-13';
-- ensure no objects were created outside pg_catalog
SELECT COUNT(*)
FROM pg_depend AS pgd,

View File

@ -40,6 +40,17 @@ SELECT shardid, shardstate, nodename, nodeport FROM pg_dist_shard_placement WHER
SELECT master_remove_node('localhost', :worker_2_port);
SELECT master_get_active_worker_nodes();
-- try to remove a node with active placements with force = true and see that node is removed
SELECT master_remove_node('localhost', :worker_2_port, true);
SELECT master_get_active_worker_nodes();
-- restore the node for next tests
SELECT master_add_node('localhost', :worker_2_port);
-- try to remove a node with active placements with force = false and see that node
-- removal is failed
SELECT master_remove_node('localhost', :worker_2_port, false);
-- mark all placements in the candidate node as inactive
UPDATE pg_dist_shard_placement SET shardstate=3 WHERE nodeport=:worker_2_port;
SELECT shardid, shardstate, nodename, nodeport FROM pg_dist_shard_placement WHERE nodeport=:worker_2_port;

View File

@ -70,6 +70,7 @@ ALTER EXTENSION citus UPDATE TO '6.1-9';
ALTER EXTENSION citus UPDATE TO '6.1-10';
ALTER EXTENSION citus UPDATE TO '6.1-11';
ALTER EXTENSION citus UPDATE TO '6.1-12';
ALTER EXTENSION citus UPDATE TO '6.1-13';
-- ensure no objects were created outside pg_catalog
SELECT COUNT(*)