mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-16 18:43:18 +08:00
Add repartition option on detach/delete_data_node
This change adds a new parameter to the detach_data_node and delete_data_node functions that will allow the user to automatically shrink their space dimension to match the number of nodes.
This commit is contained in:
parent
32f3d17cde
commit
d49e9a5739
@ -173,7 +173,8 @@ AS '@MODULE_PATHNAME@', 'ts_data_node_add' LANGUAGE C VOLATILE;
|
||||
CREATE OR REPLACE FUNCTION delete_data_node(
|
||||
node_name NAME,
|
||||
if_exists BOOLEAN = FALSE,
|
||||
force BOOLEAN = FALSE
|
||||
force BOOLEAN = FALSE,
|
||||
repartition BOOLEAN = TRUE
|
||||
) RETURNS BOOLEAN AS '@MODULE_PATHNAME@', 'ts_data_node_delete' LANGUAGE C VOLATILE;
|
||||
|
||||
-- Attach a data node to a distributed hypertable
|
||||
@ -186,7 +187,12 @@ CREATE OR REPLACE FUNCTION attach_data_node(
|
||||
AS '@MODULE_PATHNAME@', 'ts_data_node_attach' LANGUAGE C VOLATILE;
|
||||
|
||||
-- Detach a data node from a distributed hypertable. NULL hypertable means it will detach from all distributed hypertables
|
||||
CREATE OR REPLACE FUNCTION detach_data_node(node_name NAME, hypertable REGCLASS = NULL, force BOOLEAN = FALSE) RETURNS INTEGER
|
||||
CREATE OR REPLACE FUNCTION detach_data_node(
|
||||
node_name NAME,
|
||||
hypertable REGCLASS = NULL,
|
||||
force BOOLEAN = FALSE,
|
||||
repartition BOOLEAN = TRUE
|
||||
) RETURNS INTEGER
|
||||
AS '@MODULE_PATHNAME@', 'ts_data_node_detach' LANGUAGE C VOLATILE;
|
||||
|
||||
-- Block new chunk creation on a data node for a distributed hypertable. NULL hypertable means it will block
|
||||
|
@ -809,18 +809,18 @@ data_node_attach(PG_FUNCTION_ARGS)
|
||||
|
||||
num_nodes = list_length(ht->data_nodes) + 1;
|
||||
|
||||
if (num_nodes > MAX_NUM_HYPERTABLE_DATA_NODES)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("max number of data nodes already attached"),
|
||||
errdetail("The number of data nodes in a hypertable cannot exceed %d",
|
||||
MAX_NUM_HYPERTABLE_DATA_NODES)));
|
||||
|
||||
/* If there are less slices (partitions) in the space dimension than there
|
||||
* are data nodesx, we'd like to expand the number of slices to be able to
|
||||
* are data nodes, we'd like to expand the number of slices to be able to
|
||||
* make use of the new data node. */
|
||||
if (NULL != dim && num_nodes > dim->fd.num_slices)
|
||||
{
|
||||
if (num_nodes > MAX_NUM_HYPERTABLE_DATA_NODES)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("max number of data nodes already attached"),
|
||||
errdetail("The number of data nodes in a hypertable cannot exceed %d",
|
||||
MAX_NUM_HYPERTABLE_DATA_NODES)));
|
||||
|
||||
if (repartition)
|
||||
{
|
||||
ts_dimension_set_number_of_slices(dim, num_nodes & 0xFFFF);
|
||||
@ -975,7 +975,7 @@ data_node_detach_validate(const char *node_name, Hypertable *ht, bool force, Ope
|
||||
static int
|
||||
data_node_modify_hypertable_data_nodes(const char *node_name, List *hypertable_data_nodes,
|
||||
bool all_hypertables, OperationType op_type,
|
||||
bool block_chunks, bool force)
|
||||
bool block_chunks, bool force, bool repartition)
|
||||
{
|
||||
Cache *hcache = ts_hypertable_cache_pin();
|
||||
ListCell *lc;
|
||||
@ -1028,6 +1028,26 @@ data_node_modify_hypertable_data_nodes(const char *node_name, List *hypertable_d
|
||||
/* delete hypertable mapping */
|
||||
removed +=
|
||||
ts_hypertable_data_node_delete_by_node_name_and_hypertable_id(node_name, ht->fd.id);
|
||||
|
||||
if (repartition)
|
||||
{
|
||||
Dimension *dim = hyperspace_get_closed_dimension(ht->space, 0);
|
||||
int num_nodes = list_length(ht->data_nodes) - 1;
|
||||
|
||||
if (dim != NULL && num_nodes < dim->fd.num_slices && num_nodes > 0)
|
||||
{
|
||||
ts_dimension_set_number_of_slices(dim, num_nodes & 0xFFFF);
|
||||
|
||||
ereport(NOTICE,
|
||||
(errmsg("the number of partitions in dimension \"%s\" was decreased to "
|
||||
"%u",
|
||||
NameStr(dim->fd.column_name),
|
||||
num_nodes),
|
||||
errdetail(
|
||||
"To make efficient use of all attached data nodes, the number of "
|
||||
"space partitions was set to match the number of data nodes.")));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1065,19 +1085,22 @@ data_node_block_hypertable_data_nodes(const char *node_name, List *hypertable_da
|
||||
all_hypertables,
|
||||
OP_BLOCK,
|
||||
block_chunks,
|
||||
force);
|
||||
force,
|
||||
false);
|
||||
}
|
||||
|
||||
static int
|
||||
data_node_detach_hypertable_data_nodes(const char *node_name, List *hypertable_data_nodes,
|
||||
bool all_hypertables, bool force, OperationType op_type)
|
||||
bool all_hypertables, bool force, bool repartition,
|
||||
OperationType op_type)
|
||||
{
|
||||
return data_node_modify_hypertable_data_nodes(node_name,
|
||||
hypertable_data_nodes,
|
||||
all_hypertables,
|
||||
op_type,
|
||||
false,
|
||||
force);
|
||||
force,
|
||||
repartition);
|
||||
}
|
||||
|
||||
static HypertableDataNode *
|
||||
@ -1171,6 +1194,7 @@ data_node_detach(PG_FUNCTION_ARGS)
|
||||
Oid table_id = PG_ARGISNULL(1) ? InvalidOid : PG_GETARG_OID(1);
|
||||
bool all_hypertables = PG_ARGISNULL(1);
|
||||
bool force = PG_ARGISNULL(2) ? InvalidOid : PG_GETARG_OID(2);
|
||||
bool repartition = PG_ARGISNULL(3) ? false : PG_GETARG_BOOL(3);
|
||||
int removed = 0;
|
||||
List *hypertable_data_nodes = NIL;
|
||||
ForeignServer *server = data_node_get_foreign_server(node_name, ACL_USAGE, true, false);
|
||||
@ -1197,6 +1221,7 @@ data_node_detach(PG_FUNCTION_ARGS)
|
||||
hypertable_data_nodes,
|
||||
all_hypertables,
|
||||
force,
|
||||
repartition,
|
||||
OP_DETACH);
|
||||
|
||||
PG_RETURN_INT32(removed);
|
||||
@ -1208,6 +1233,7 @@ data_node_delete(PG_FUNCTION_ARGS)
|
||||
const char *node_name = PG_ARGISNULL(0) ? NULL : PG_GETARG_CSTRING(0);
|
||||
bool if_exists = PG_ARGISNULL(1) ? false : PG_GETARG_BOOL(1);
|
||||
bool force = PG_ARGISNULL(2) ? false : PG_GETARG_BOOL(2);
|
||||
bool repartition = PG_ARGISNULL(3) ? false : PG_GETARG_BOOL(3);
|
||||
List *hypertable_data_nodes = NIL;
|
||||
DropStmt stmt;
|
||||
ObjectAddress address;
|
||||
@ -1247,6 +1273,7 @@ data_node_delete(PG_FUNCTION_ARGS)
|
||||
hypertable_data_nodes,
|
||||
true,
|
||||
force,
|
||||
repartition,
|
||||
OP_DELETE);
|
||||
|
||||
stmt = (DropStmt){
|
||||
|
@ -458,6 +458,7 @@ RESET ROLE;
|
||||
TRUNCATE disttable;
|
||||
TRUNCATE costtable;
|
||||
SELECT * FROM delete_data_node('data_node_1', force => true);
|
||||
NOTICE: the number of partitions in dimension "device" was decreased to 1
|
||||
delete_data_node
|
||||
------------------
|
||||
t
|
||||
|
@ -1016,6 +1016,7 @@ ERROR: table "devices" is not a hypertable
|
||||
-- force detach data node to become under-replicated for new data
|
||||
SELECT * FROM detach_data_node('data_node_3', 'disttable_2', force => true);
|
||||
WARNING: new data for hypertable "disttable_2" will be under-replicated due to detaching data node "data_node_3"
|
||||
NOTICE: the number of partitions in dimension "device" was decreased to 1
|
||||
detach_data_node
|
||||
------------------
|
||||
1
|
||||
@ -1108,6 +1109,7 @@ ORDER BY foreign_table_name;
|
||||
|
||||
SELECT * FROM detach_data_node('data_node_2', 'disttable', true);
|
||||
WARNING: new data for hypertable "disttable" will be under-replicated due to detaching data node "data_node_2"
|
||||
NOTICE: the number of partitions in dimension "device" was decreased to 1
|
||||
detach_data_node
|
||||
------------------
|
||||
1
|
||||
|
@ -1909,6 +1909,41 @@ ts_insert_blocker| 7|_timescaledb_internal.insert_blocker
|
||||
|
||||
(1 row)
|
||||
|
||||
-- Verify that repartitioning works as expected on detach_data_node
|
||||
SELECT * FROM detach_data_node('data_node_1', '"Table\\Schema"."Param_Table"', repartition => true);
|
||||
NOTICE: the number of partitions in dimension "__region" was decreased to 2
|
||||
detach_data_node
|
||||
------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT h.table_name, d.column_name, d.num_slices
|
||||
FROM _timescaledb_catalog.hypertable h, _timescaledb_catalog.dimension d
|
||||
WHERE h.id = d.hypertable_id
|
||||
AND h.table_name = 'Param_Table';
|
||||
table_name | column_name | num_slices
|
||||
-------------+------------------+------------
|
||||
Param_Table | __region | 2
|
||||
Param_Table | time Col %#^#@$# |
|
||||
(2 rows)
|
||||
|
||||
SELECT * FROM detach_data_node('data_node_2', '"Table\\Schema"."Param_Table"', force => true, repartition => false);
|
||||
WARNING: new data for hypertable "Param_Table" will be under-replicated due to detaching data node "data_node_2"
|
||||
detach_data_node
|
||||
------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT h.table_name, d.column_name, d.num_slices
|
||||
FROM _timescaledb_catalog.hypertable h, _timescaledb_catalog.dimension d
|
||||
WHERE h.id = d.hypertable_id
|
||||
AND h.table_name = 'Param_Table';
|
||||
table_name | column_name | num_slices
|
||||
-------------+------------------+------------
|
||||
Param_Table | __region | 2
|
||||
Param_Table | time Col %#^#@$# |
|
||||
(2 rows)
|
||||
|
||||
-- Test multi-dimensional hypertable. The add_dimension() command
|
||||
-- should be propagated to backends.
|
||||
CREATE TABLE dimented_table (time timestamptz, column1 int, column2 timestamptz, column3 int);
|
||||
@ -1950,7 +1985,7 @@ SELECT * FROM _timescaledb_catalog.dimension;
|
||||
2 | 1 | device | integer | f | 3 | _timescaledb_internal | get_partition_hash | | |
|
||||
3 | 2 | time | timestamp with time zone | t | | | | 604800000000 | |
|
||||
5 | 4 | time Col %#^#@$# | timestamp with time zone | t | | | | 604800000000 | |
|
||||
6 | 4 | __region | text | f | 4 | _timescaledb_internal | get_partition_hash | | |
|
||||
6 | 4 | __region | text | f | 2 | _timescaledb_internal | get_partition_hash | | |
|
||||
7 | 5 | time | timestamp with time zone | t | | | | 604800000000 | |
|
||||
8 | 5 | column1 | integer | f | 4 | _timescaledb_internal | get_partition_hash | | |
|
||||
9 | 5 | column2 | timestamp with time zone | t | | | | 604800000000 | |
|
||||
@ -1970,7 +2005,7 @@ SELECT * FROM _timescaledb_catalog.dimension;
|
||||
2 | 1 | device | integer | f | 3 | _timescaledb_internal | get_partition_hash | | |
|
||||
3 | 2 | time | timestamp with time zone | t | | | | 604800000000 | |
|
||||
5 | 4 | time Col %#^#@$# | timestamp with time zone | t | | | | 604800000000 | |
|
||||
6 | 4 | __region | text | f | 4 | _timescaledb_internal | get_partition_hash | | |
|
||||
6 | 4 | __region | text | f | 2 | _timescaledb_internal | get_partition_hash | | |
|
||||
7 | 5 | time | timestamp with time zone | t | | | | 604800000000 | |
|
||||
8 | 5 | column1 | integer | f | 4 | _timescaledb_internal | get_partition_hash | | |
|
||||
9 | 5 | column2 | timestamp with time zone | t | | | | 604800000000 | |
|
||||
|
@ -1909,6 +1909,41 @@ ts_insert_blocker| 7|_timescaledb_internal.insert_blocker
|
||||
|
||||
(1 row)
|
||||
|
||||
-- Verify that repartitioning works as expected on detach_data_node
|
||||
SELECT * FROM detach_data_node('data_node_1', '"Table\\Schema"."Param_Table"', repartition => true);
|
||||
NOTICE: the number of partitions in dimension "__region" was decreased to 2
|
||||
detach_data_node
|
||||
------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT h.table_name, d.column_name, d.num_slices
|
||||
FROM _timescaledb_catalog.hypertable h, _timescaledb_catalog.dimension d
|
||||
WHERE h.id = d.hypertable_id
|
||||
AND h.table_name = 'Param_Table';
|
||||
table_name | column_name | num_slices
|
||||
-------------+------------------+------------
|
||||
Param_Table | __region | 2
|
||||
Param_Table | time Col %#^#@$# |
|
||||
(2 rows)
|
||||
|
||||
SELECT * FROM detach_data_node('data_node_2', '"Table\\Schema"."Param_Table"', force => true, repartition => false);
|
||||
WARNING: new data for hypertable "Param_Table" will be under-replicated due to detaching data node "data_node_2"
|
||||
detach_data_node
|
||||
------------------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
SELECT h.table_name, d.column_name, d.num_slices
|
||||
FROM _timescaledb_catalog.hypertable h, _timescaledb_catalog.dimension d
|
||||
WHERE h.id = d.hypertable_id
|
||||
AND h.table_name = 'Param_Table';
|
||||
table_name | column_name | num_slices
|
||||
-------------+------------------+------------
|
||||
Param_Table | __region | 2
|
||||
Param_Table | time Col %#^#@$# |
|
||||
(2 rows)
|
||||
|
||||
-- Test multi-dimensional hypertable. The add_dimension() command
|
||||
-- should be propagated to backends.
|
||||
CREATE TABLE dimented_table (time timestamptz, column1 int, column2 timestamptz, column3 int);
|
||||
@ -1950,7 +1985,7 @@ SELECT * FROM _timescaledb_catalog.dimension;
|
||||
2 | 1 | device | integer | f | 3 | _timescaledb_internal | get_partition_hash | | |
|
||||
3 | 2 | time | timestamp with time zone | t | | | | 604800000000 | |
|
||||
5 | 4 | time Col %#^#@$# | timestamp with time zone | t | | | | 604800000000 | |
|
||||
6 | 4 | __region | text | f | 4 | _timescaledb_internal | get_partition_hash | | |
|
||||
6 | 4 | __region | text | f | 2 | _timescaledb_internal | get_partition_hash | | |
|
||||
7 | 5 | time | timestamp with time zone | t | | | | 604800000000 | |
|
||||
8 | 5 | column1 | integer | f | 4 | _timescaledb_internal | get_partition_hash | | |
|
||||
9 | 5 | column2 | timestamp with time zone | t | | | | 604800000000 | |
|
||||
@ -1970,7 +2005,7 @@ SELECT * FROM _timescaledb_catalog.dimension;
|
||||
2 | 1 | device | integer | f | 3 | _timescaledb_internal | get_partition_hash | | |
|
||||
3 | 2 | time | timestamp with time zone | t | | | | 604800000000 | |
|
||||
5 | 4 | time Col %#^#@$# | timestamp with time zone | t | | | | 604800000000 | |
|
||||
6 | 4 | __region | text | f | 4 | _timescaledb_internal | get_partition_hash | | |
|
||||
6 | 4 | __region | text | f | 2 | _timescaledb_internal | get_partition_hash | | |
|
||||
7 | 5 | time | timestamp with time zone | t | | | | 604800000000 | |
|
||||
8 | 5 | column1 | integer | f | 4 | _timescaledb_internal | get_partition_hash | | |
|
||||
9 | 5 | column2 | timestamp with time zone | t | | | | 604800000000 | |
|
||||
|
@ -571,6 +571,18 @@ SELECT t.tgname, t.tgtype, t.tgfoid::regproc
|
||||
FROM pg_trigger t, pg_class c WHERE c.relname = 'Param_Table' AND t.tgrelid = c.oid;
|
||||
$$);
|
||||
|
||||
-- Verify that repartitioning works as expected on detach_data_node
|
||||
SELECT * FROM detach_data_node('data_node_1', '"Table\\Schema"."Param_Table"', repartition => true);
|
||||
SELECT h.table_name, d.column_name, d.num_slices
|
||||
FROM _timescaledb_catalog.hypertable h, _timescaledb_catalog.dimension d
|
||||
WHERE h.id = d.hypertable_id
|
||||
AND h.table_name = 'Param_Table';
|
||||
SELECT * FROM detach_data_node('data_node_2', '"Table\\Schema"."Param_Table"', force => true, repartition => false);
|
||||
SELECT h.table_name, d.column_name, d.num_slices
|
||||
FROM _timescaledb_catalog.hypertable h, _timescaledb_catalog.dimension d
|
||||
WHERE h.id = d.hypertable_id
|
||||
AND h.table_name = 'Param_Table';
|
||||
|
||||
-- Test multi-dimensional hypertable. The add_dimension() command
|
||||
-- should be propagated to backends.
|
||||
CREATE TABLE dimented_table (time timestamptz, column1 int, column2 timestamptz, column3 int);
|
||||
|
Loading…
x
Reference in New Issue
Block a user