mirror of https://github.com/citusdata/citus.git
Limit citus_drain_node to drain the specified node only (#6361)
DESCRIPTION: Fixes citus_drain_node to drain the specified worker only. Fixes #6267pull/6413/head
parent
86e186f671
commit
1776bdf654
|
@ -1386,6 +1386,21 @@ IsActiveShardPlacement(ShardPlacement *shardPlacement)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IsPlacementOnWorkerNode checks if the shard placement is for to the given
|
||||||
|
* workenode.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
IsPlacementOnWorkerNode(ShardPlacement *placement, WorkerNode *workerNode)
|
||||||
|
{
|
||||||
|
if (strncmp(workerNode->workerName, placement->nodeName, WORKER_LENGTH) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return workerNode->workerPort == placement->nodePort;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FilterShardPlacementList filters a list of shard placements based on a filter.
|
* FilterShardPlacementList filters a list of shard placements based on a filter.
|
||||||
* Keep only the shard for which the filter function returns true.
|
* Keep only the shard for which the filter function returns true.
|
||||||
|
@ -1409,6 +1424,30 @@ FilterShardPlacementList(List *shardPlacementList, bool (*filter)(ShardPlacement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FilterActiveShardPlacementListByNode filters a list of active shard placements based on given nodeName and nodePort.
|
||||||
|
*/
|
||||||
|
List *
|
||||||
|
FilterActiveShardPlacementListByNode(List *shardPlacementList, WorkerNode *workerNode)
|
||||||
|
{
|
||||||
|
List *activeShardPlacementList = FilterShardPlacementList(shardPlacementList,
|
||||||
|
IsActiveShardPlacement);
|
||||||
|
List *filteredShardPlacementList = NIL;
|
||||||
|
ShardPlacement *shardPlacement = NULL;
|
||||||
|
|
||||||
|
foreach_ptr(shardPlacement, activeShardPlacementList)
|
||||||
|
{
|
||||||
|
if (IsPlacementOnWorkerNode(shardPlacement, workerNode))
|
||||||
|
{
|
||||||
|
filteredShardPlacementList = lappend(filteredShardPlacementList,
|
||||||
|
shardPlacement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filteredShardPlacementList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ActiveShardPlacementListOnGroup returns a list of active shard placements
|
* ActiveShardPlacementListOnGroup returns a list of active shard placements
|
||||||
* that are sitting on group with groupId for given shardId.
|
* that are sitting on group with groupId for given shardId.
|
||||||
|
|
|
@ -77,6 +77,7 @@ typedef struct RebalanceOptions
|
||||||
float4 improvementThreshold;
|
float4 improvementThreshold;
|
||||||
Form_pg_dist_rebalance_strategy rebalanceStrategy;
|
Form_pg_dist_rebalance_strategy rebalanceStrategy;
|
||||||
const char *operationName;
|
const char *operationName;
|
||||||
|
WorkerNode *workerNode;
|
||||||
} RebalanceOptions;
|
} RebalanceOptions;
|
||||||
|
|
||||||
|
|
||||||
|
@ -209,7 +210,6 @@ static bool WorkerNodeListContains(List *workerNodeList, const char *workerName,
|
||||||
uint32 workerPort);
|
uint32 workerPort);
|
||||||
static void UpdateColocatedShardPlacementProgress(uint64 shardId, char *sourceName,
|
static void UpdateColocatedShardPlacementProgress(uint64 shardId, char *sourceName,
|
||||||
int sourcePort, uint64 progress);
|
int sourcePort, uint64 progress);
|
||||||
static bool IsPlacementOnWorkerNode(ShardPlacement *placement, WorkerNode *workerNode);
|
|
||||||
static NodeFillState * FindFillStateForPlacement(RebalanceState *state,
|
static NodeFillState * FindFillStateForPlacement(RebalanceState *state,
|
||||||
ShardPlacement *placement);
|
ShardPlacement *placement);
|
||||||
static RebalanceState * InitRebalanceState(List *workerNodeList, List *shardPlacementList,
|
static RebalanceState * InitRebalanceState(List *workerNodeList, List *shardPlacementList,
|
||||||
|
@ -469,6 +469,13 @@ GetRebalanceSteps(RebalanceOptions *options)
|
||||||
options->excludedShardArray);
|
options->excludedShardArray);
|
||||||
List *activeShardPlacementListForRelation =
|
List *activeShardPlacementListForRelation =
|
||||||
FilterShardPlacementList(shardPlacementList, IsActiveShardPlacement);
|
FilterShardPlacementList(shardPlacementList, IsActiveShardPlacement);
|
||||||
|
|
||||||
|
if (options->workerNode != NULL)
|
||||||
|
{
|
||||||
|
activeShardPlacementListForRelation = FilterActiveShardPlacementListByNode(
|
||||||
|
shardPlacementList, options->workerNode);
|
||||||
|
}
|
||||||
|
|
||||||
activeShardPlacementListList =
|
activeShardPlacementListList =
|
||||||
lappend(activeShardPlacementListList, activeShardPlacementListForRelation);
|
lappend(activeShardPlacementListList, activeShardPlacementListForRelation);
|
||||||
}
|
}
|
||||||
|
@ -1052,6 +1059,7 @@ citus_drain_node(PG_FUNCTION_ARGS)
|
||||||
};
|
};
|
||||||
|
|
||||||
char *nodeName = text_to_cstring(nodeNameText);
|
char *nodeName = text_to_cstring(nodeNameText);
|
||||||
|
options.workerNode = FindWorkerNodeOrError(nodeName, nodePort);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is done in a separate session. This way it's not undone if the
|
* This is done in a separate session. This way it's not undone if the
|
||||||
|
@ -2294,21 +2302,6 @@ FindFillStateForPlacement(RebalanceState *state, ShardPlacement *placement)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* IsPlacementOnWorkerNode checks if the shard placement is for to the given
|
|
||||||
* workenode.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
IsPlacementOnWorkerNode(ShardPlacement *placement, WorkerNode *workerNode)
|
|
||||||
{
|
|
||||||
if (strncmp(workerNode->workerName, placement->nodeName, WORKER_LENGTH) != 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return workerNode->workerPort == placement->nodePort;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CompareNodeFillStateAsc can be used to sort fill states from empty to full.
|
* CompareNodeFillStateAsc can be used to sort fill states from empty to full.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -289,8 +289,11 @@ extern uint64 ShardLength(uint64 shardId);
|
||||||
extern bool NodeGroupHasShardPlacements(int32 groupId,
|
extern bool NodeGroupHasShardPlacements(int32 groupId,
|
||||||
bool onlyConsiderActivePlacements);
|
bool onlyConsiderActivePlacements);
|
||||||
extern bool IsActiveShardPlacement(ShardPlacement *ShardPlacement);
|
extern bool IsActiveShardPlacement(ShardPlacement *ShardPlacement);
|
||||||
|
extern bool IsPlacementOnWorkerNode(ShardPlacement *placement, WorkerNode *workerNode);
|
||||||
extern List * FilterShardPlacementList(List *shardPlacementList, bool (*filter)(
|
extern List * FilterShardPlacementList(List *shardPlacementList, bool (*filter)(
|
||||||
ShardPlacement *));
|
ShardPlacement *));
|
||||||
|
extern List * FilterActiveShardPlacementListByNode(List *shardPlacementList,
|
||||||
|
WorkerNode *workerNode);
|
||||||
extern List * ActiveShardPlacementListOnGroup(uint64 shardId, int32 groupId);
|
extern List * ActiveShardPlacementListOnGroup(uint64 shardId, int32 groupId);
|
||||||
extern List * ActiveShardPlacementList(uint64 shardId);
|
extern List * ActiveShardPlacementList(uint64 shardId);
|
||||||
extern List * ShardPlacementListWithoutOrphanedPlacements(uint64 shardId);
|
extern List * ShardPlacementListWithoutOrphanedPlacements(uint64 shardId);
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
CREATE SCHEMA citus_drain_node;
|
||||||
|
SET search_path TO citus_drain_node;
|
||||||
|
SET citus.shard_count TO 4;
|
||||||
|
SET citus.shard_replication_factor TO 1;
|
||||||
|
SET citus.next_shard_id TO 974653;
|
||||||
|
SET client_min_messages TO ERROR;
|
||||||
|
SELECT * FROM citus_set_coordinator_host('localhost', :master_port);
|
||||||
|
citus_set_coordinator_host
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM master_set_node_property('localhost', :master_port, 'shouldhaveshards', true);
|
||||||
|
master_set_node_property
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CREATE TABLE test (x INT, y INT);
|
||||||
|
SELECT create_distributed_table('test','x');
|
||||||
|
create_distributed_table
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CALL citus_cleanup_orphaned_shards();
|
||||||
|
SELECT nodename, nodeport, COUNT(*)
|
||||||
|
FROM pg_dist_placement AS placement,
|
||||||
|
pg_dist_node AS node
|
||||||
|
WHERE placement.groupid = node.groupid
|
||||||
|
AND node.noderole = 'primary' GROUP BY nodename, nodeport ORDER BY 1,2;
|
||||||
|
nodename | nodeport | count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
localhost | 57636 | 2
|
||||||
|
localhost | 57637 | 1
|
||||||
|
localhost | 57638 | 1
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT * FROM citus_set_node_property('localhost', :worker_2_port, 'shouldhaveshards', false);
|
||||||
|
citus_set_node_property
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * from citus_drain_node('localhost', :worker_1_port, shard_transfer_mode :='force_logical');
|
||||||
|
citus_drain_node
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CALL citus_cleanup_orphaned_shards();
|
||||||
|
SELECT nodename, nodeport, COUNT(*)
|
||||||
|
FROM pg_dist_placement AS placement,
|
||||||
|
pg_dist_node AS node
|
||||||
|
WHERE placement.groupid = node.groupid
|
||||||
|
AND node.noderole = 'primary' GROUP BY nodename, nodeport ORDER BY 1,2;
|
||||||
|
nodename | nodeport | count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
localhost | 57636 | 3
|
||||||
|
localhost | 57638 | 1
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
SELECT * FROM citus_set_node_property('localhost', :worker_1_port, 'shouldhaveshards', true);
|
||||||
|
citus_set_node_property
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM citus_set_node_property('localhost', :worker_2_port, 'shouldhaveshards', true);
|
||||||
|
citus_set_node_property
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM rebalance_table_shards(shard_transfer_mode :='force_logical');
|
||||||
|
rebalance_table_shards
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CALL citus_cleanup_orphaned_shards();
|
||||||
|
SELECT nodename, nodeport, COUNT(*)
|
||||||
|
FROM pg_dist_placement AS placement,
|
||||||
|
pg_dist_node AS node
|
||||||
|
WHERE placement.groupid = node.groupid
|
||||||
|
AND node.noderole = 'primary' GROUP BY nodename, nodeport ORDER BY 1,2;
|
||||||
|
nodename | nodeport | count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
localhost | 57636 | 2
|
||||||
|
localhost | 57637 | 1
|
||||||
|
localhost | 57638 | 1
|
||||||
|
(3 rows)
|
||||||
|
|
||||||
|
SELECT * FROM citus_set_node_property('localhost', :master_port, 'shouldhaveshards', false);
|
||||||
|
citus_set_node_property
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
SELECT * FROM rebalance_table_shards(shard_transfer_mode :='force_logical');
|
||||||
|
rebalance_table_shards
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
CALL citus_cleanup_orphaned_shards();
|
||||||
|
SELECT nodename, nodeport, COUNT(*)
|
||||||
|
FROM pg_dist_placement AS placement,
|
||||||
|
pg_dist_node AS node
|
||||||
|
WHERE placement.groupid = node.groupid
|
||||||
|
AND node.noderole = 'primary' GROUP BY nodename, nodeport ORDER BY 1,2;
|
||||||
|
nodename | nodeport | count
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
localhost | 57637 | 2
|
||||||
|
localhost | 57638 | 2
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
RESET search_path;
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
DROP SCHEMA citus_drain_node CASCADE;
|
|
@ -12,3 +12,4 @@ test: multi_colocated_shard_rebalance
|
||||||
test: ignoring_orphaned_shards
|
test: ignoring_orphaned_shards
|
||||||
test: cpu_priority
|
test: cpu_priority
|
||||||
test: check_mx
|
test: check_mx
|
||||||
|
test: citus_drain_node
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
CREATE SCHEMA citus_drain_node;
|
||||||
|
SET search_path TO citus_drain_node;
|
||||||
|
SET citus.shard_count TO 4;
|
||||||
|
SET citus.shard_replication_factor TO 1;
|
||||||
|
SET citus.next_shard_id TO 974653;
|
||||||
|
|
||||||
|
SET client_min_messages TO ERROR;
|
||||||
|
|
||||||
|
SELECT * FROM citus_set_coordinator_host('localhost', :master_port);
|
||||||
|
SELECT * FROM master_set_node_property('localhost', :master_port, 'shouldhaveshards', true);
|
||||||
|
|
||||||
|
CREATE TABLE test (x INT, y INT);
|
||||||
|
SELECT create_distributed_table('test','x');
|
||||||
|
|
||||||
|
CALL citus_cleanup_orphaned_shards();
|
||||||
|
|
||||||
|
SELECT nodename, nodeport, COUNT(*)
|
||||||
|
FROM pg_dist_placement AS placement,
|
||||||
|
pg_dist_node AS node
|
||||||
|
WHERE placement.groupid = node.groupid
|
||||||
|
AND node.noderole = 'primary' GROUP BY nodename, nodeport ORDER BY 1,2;
|
||||||
|
|
||||||
|
SELECT * FROM citus_set_node_property('localhost', :worker_2_port, 'shouldhaveshards', false);
|
||||||
|
SELECT * from citus_drain_node('localhost', :worker_1_port, shard_transfer_mode :='force_logical');
|
||||||
|
|
||||||
|
CALL citus_cleanup_orphaned_shards();
|
||||||
|
|
||||||
|
SELECT nodename, nodeport, COUNT(*)
|
||||||
|
FROM pg_dist_placement AS placement,
|
||||||
|
pg_dist_node AS node
|
||||||
|
WHERE placement.groupid = node.groupid
|
||||||
|
AND node.noderole = 'primary' GROUP BY nodename, nodeport ORDER BY 1,2;
|
||||||
|
|
||||||
|
SELECT * FROM citus_set_node_property('localhost', :worker_1_port, 'shouldhaveshards', true);
|
||||||
|
SELECT * FROM citus_set_node_property('localhost', :worker_2_port, 'shouldhaveshards', true);
|
||||||
|
|
||||||
|
SELECT * FROM rebalance_table_shards(shard_transfer_mode :='force_logical');
|
||||||
|
|
||||||
|
CALL citus_cleanup_orphaned_shards();
|
||||||
|
|
||||||
|
SELECT nodename, nodeport, COUNT(*)
|
||||||
|
FROM pg_dist_placement AS placement,
|
||||||
|
pg_dist_node AS node
|
||||||
|
WHERE placement.groupid = node.groupid
|
||||||
|
AND node.noderole = 'primary' GROUP BY nodename, nodeport ORDER BY 1,2;
|
||||||
|
|
||||||
|
SELECT * FROM citus_set_node_property('localhost', :master_port, 'shouldhaveshards', false);
|
||||||
|
|
||||||
|
SELECT * FROM rebalance_table_shards(shard_transfer_mode :='force_logical');
|
||||||
|
|
||||||
|
CALL citus_cleanup_orphaned_shards();
|
||||||
|
|
||||||
|
SELECT nodename, nodeport, COUNT(*)
|
||||||
|
FROM pg_dist_placement AS placement,
|
||||||
|
pg_dist_node AS node
|
||||||
|
WHERE placement.groupid = node.groupid
|
||||||
|
AND node.noderole = 'primary' GROUP BY nodename, nodeport ORDER BY 1,2;
|
||||||
|
|
||||||
|
RESET search_path;
|
||||||
|
|
||||||
|
SET client_min_messages TO WARNING;
|
||||||
|
DROP SCHEMA citus_drain_node CASCADE;
|
Loading…
Reference in New Issue