From c09d46494989ff8e699c5e273ec920f1feb7ce68 Mon Sep 17 00:00:00 2001 From: liyuheng Date: Mon, 11 Nov 2024 14:28:36 +0800 Subject: [PATCH 01/13] =?UTF-8?q?=E8=B5=B0=E8=B5=B0=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 | 7 ++- .../org/apache/iotdb/db/qp/sql/SqlLexer.g4 | 4 ++ .../confignode/manager/ConfigManager.java | 9 +++ .../iotdb/confignode/manager/IManager.java | 3 + .../confignode/manager/ProcedureManager.java | 5 ++ .../thrift/ConfigNodeRPCServiceProcessor.java | 6 ++ .../db/protocol/client/ConfigNodeClient.java | 7 +++ .../config/TreeConfigTaskVisitor.java | 8 +++ .../executor/ClusterConfigTaskExecutor.java | 25 ++++++++ .../config/executor/IConfigTaskExecutor.java | 4 ++ .../metadata/ReconstructRegionTask.java | 42 +++++++++++++ .../queryengine/plan/parser/ASTVisitor.java | 13 ++++ .../plan/statement/StatementVisitor.java | 6 ++ .../metadata/ReconstructRegionStatement.java | 62 +++++++++++++++++++ .../src/main/thrift/confignode.thrift | 7 +++ 15 files changed, 207 insertions(+), 1 deletion(-) create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ReconstructRegionTask.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ReconstructRegionStatement.java diff --git a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 index 57d686de88e6..ea8e09561d09 100644 --- a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 +++ b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 @@ -64,7 +64,8 @@ ddlStatement | createContinuousQuery | dropContinuousQuery | showContinuousQueries // Cluster | showVariables | showCluster | showRegions | showDataNodes | showConfigNodes | showClusterId - | getRegionId | getTimeSlotList | countTimeSlotList | getSeriesSlotList | migrateRegion | verifyConnection + | getRegionId | getTimeSlotList | countTimeSlotList | getSeriesSlotList | migrateRegion | reconstructRegion + | verifyConnection // AINode | showAINodes | createModel | dropModel | showModels | callInference // Quota @@ -536,6 +537,10 @@ migrateRegion : MIGRATE REGION regionId=INTEGER_LITERAL FROM fromId=INTEGER_LITERAL TO toId=INTEGER_LITERAL ; +reconstructRegion + : RECONSTRUCT REGION regionId=INTEGER_LITERAL (COMMA regionId=INTEGER_LITERAL)* ON targetDataNodeId=INTEGER_LITERAL + ; + verifyConnection : VERIFY CONNECTION (DETAILS)? ; diff --git a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4 b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4 index a2803be52a41..26cfe650492d 100644 --- a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4 +++ b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4 @@ -642,6 +642,10 @@ READONLY : R E A D O N L Y ; +RECONSTRUCT + : R E C O N S T R U C T + ; + REGEXP : R E G E X P ; diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java index 29884cdd93de..c7667ee1f1a9 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java @@ -198,6 +198,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TPermissionInfoResp; import org.apache.iotdb.confignode.rpc.thrift.TPipeConfigTransferReq; import org.apache.iotdb.confignode.rpc.thrift.TPipeConfigTransferResp; +import org.apache.iotdb.confignode.rpc.thrift.TReconstructRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TRegionRouteMapResp; import org.apache.iotdb.confignode.rpc.thrift.TSchemaNodeManagementResp; import org.apache.iotdb.confignode.rpc.thrift.TSchemaPartitionTableResp; @@ -2357,6 +2358,14 @@ public TSStatus migrateRegion(TMigrateRegionReq req) { : status; } + @Override + public TSStatus reconstructRegion(TReconstructRegionReq req) { + TSStatus status = confirmLeader(); + return status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode() + ? procedureManager.reconstructRegion(req) + : status; + } + @Override public TSStatus createCQ(TCreateCQReq req) { TSStatus status = confirmLeader(); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java index 954946f229ea..27f52254622f 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java @@ -122,6 +122,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TPermissionInfoResp; import org.apache.iotdb.confignode.rpc.thrift.TPipeConfigTransferReq; import org.apache.iotdb.confignode.rpc.thrift.TPipeConfigTransferResp; +import org.apache.iotdb.confignode.rpc.thrift.TReconstructRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TRegionRouteMapResp; import org.apache.iotdb.confignode.rpc.thrift.TSchemaNodeManagementResp; import org.apache.iotdb.confignode.rpc.thrift.TSchemaPartitionTableResp; @@ -810,6 +811,8 @@ TDataPartitionTableResp getOrCreateDataPartition( TSStatus migrateRegion(TMigrateRegionReq req); + TSStatus reconstructRegion(TReconstructRegionReq req); + TSStatus createCQ(TCreateCQReq req); TSStatus dropCQ(TDropCQReq req); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java index 9ccf4eb41544..edc8046c4978 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java @@ -127,6 +127,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TDeleteTableDeviceResp; import org.apache.iotdb.confignode.rpc.thrift.TDropPipePluginReq; import org.apache.iotdb.confignode.rpc.thrift.TMigrateRegionReq; +import org.apache.iotdb.confignode.rpc.thrift.TReconstructRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TSubscribeReq; import org.apache.iotdb.confignode.rpc.thrift.TUnsubscribeReq; import org.apache.iotdb.consensus.ConsensusFactory; @@ -926,6 +927,10 @@ public TSStatus migrateRegion(TMigrateRegionReq migrateRegionReq) { } } + public TSStatus reconstructRegion(TReconstructRegionReq reconstructRegionReq) { + return null; + } + // endregion /** diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java index 36a7349e486b..a0470920121a 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java @@ -166,6 +166,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TPermissionInfoResp; import org.apache.iotdb.confignode.rpc.thrift.TPipeConfigTransferReq; import org.apache.iotdb.confignode.rpc.thrift.TPipeConfigTransferResp; +import org.apache.iotdb.confignode.rpc.thrift.TReconstructRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TRegionRouteMapResp; import org.apache.iotdb.confignode.rpc.thrift.TSchemaNodeManagementReq; import org.apache.iotdb.confignode.rpc.thrift.TSchemaNodeManagementResp; @@ -1233,6 +1234,11 @@ public TSStatus migrateRegion(TMigrateRegionReq req) { return configManager.migrateRegion(req); } + @Override + public TSStatus reconstructRegion(TReconstructRegionReq req) { + return configManager.reconstructRegion(req); + } + @Override public TSStatus createCQ(TCreateCQReq req) { return configManager.createCQ(req); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java index b0379a3d9c4b..5a7fcb909b7d 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java @@ -129,6 +129,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TPermissionInfoResp; import org.apache.iotdb.confignode.rpc.thrift.TPipeConfigTransferReq; import org.apache.iotdb.confignode.rpc.thrift.TPipeConfigTransferResp; +import org.apache.iotdb.confignode.rpc.thrift.TReconstructRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TRegionRouteMapResp; import org.apache.iotdb.confignode.rpc.thrift.TSchemaNodeManagementReq; import org.apache.iotdb.confignode.rpc.thrift.TSchemaNodeManagementResp; @@ -1190,6 +1191,12 @@ public TSStatus migrateRegion(TMigrateRegionReq req) throws TException { () -> client.migrateRegion(req), status -> !updateConfigNodeLeader(status)); } + @Override + public TSStatus reconstructRegion(TReconstructRegionReq req) throws TException { + return executeRemoteCallWithRetry( + () -> client.reconstructRegion(req), status -> !updateConfigNodeLeader(status)); + } + @Override public TSStatus createCQ(TCreateCQReq req) throws TException { return executeRemoteCallWithRetry( diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TreeConfigTaskVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TreeConfigTaskVisitor.java index 80677d5adece..855cdec714e6 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TreeConfigTaskVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TreeConfigTaskVisitor.java @@ -38,6 +38,7 @@ import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.GetSeriesSlotListTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.GetTimeSlotListTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.MigrateRegionTask; +import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.ReconstructRegionTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.SetTTLTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.ShowAINodesTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.ShowClusterDetailsTask; @@ -112,6 +113,7 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetSeriesSlotListStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetTimeSlotListStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.MigrateRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.ReconstructRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.SetTTLStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowClusterIdStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowClusterStatement; @@ -564,6 +566,12 @@ public IConfigTask visitMigrateRegion( return new MigrateRegionTask(migrateRegionStatement); } + @Override + public IConfigTask visitReconstructRegion( + ReconstructRegionStatement reconstructRegionStatement, MPPQueryContext context) { + return new ReconstructRegionTask(reconstructRegionStatement); + } + @Override public IConfigTask visitCreateContinuousQuery( CreateContinuousQueryStatement createContinuousQueryStatement, MPPQueryContext context) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java index 9c89fade5779..ae3da4d7a3b8 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java @@ -107,6 +107,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TMigrateRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TPipeConfigTransferReq; import org.apache.iotdb.confignode.rpc.thrift.TPipeConfigTransferResp; +import org.apache.iotdb.confignode.rpc.thrift.TReconstructRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TRegionInfo; import org.apache.iotdb.confignode.rpc.thrift.TShowAINodesResp; import org.apache.iotdb.confignode.rpc.thrift.TShowCQResp; @@ -215,6 +216,7 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetSeriesSlotListStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetTimeSlotListStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.MigrateRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.ReconstructRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.SetTTLStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowClusterStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowDatabaseStatement; @@ -2768,6 +2770,29 @@ public SettableFuture migrateRegion( return future; } + @Override + public SettableFuture reconstructRegion( + ReconstructRegionStatement reconstructRegionStatement) { + final SettableFuture future = SettableFuture.create(); + try (ConfigNodeClient configNodeClient = + CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) { + final TReconstructRegionReq req = + new TReconstructRegionReq( + reconstructRegionStatement.getDataNodeId(), + reconstructRegionStatement.getRegionIds()); + final TSStatus status = configNodeClient.reconstructRegion(req); + if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { + future.setException(new IoTDBException(status.message, status.code)); + return future; + } else { + future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS)); + } + } catch (Exception e) { + future.setException(e); + } + return future; + } + @Override public SettableFuture createContinuousQuery( CreateContinuousQueryStatement createContinuousQueryStatement, MPPQueryContext context) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/IConfigTaskExecutor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/IConfigTaskExecutor.java index 1bc3a8d4354f..285cf619ebef 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/IConfigTaskExecutor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/IConfigTaskExecutor.java @@ -52,6 +52,7 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetSeriesSlotListStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetTimeSlotListStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.MigrateRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.ReconstructRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.SetTTLStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowClusterStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowDatabaseStatement; @@ -242,6 +243,9 @@ SettableFuture countTimeSlotList( SettableFuture migrateRegion(MigrateRegionStatement migrateRegionStatement); + SettableFuture reconstructRegion( + ReconstructRegionStatement reconstructRegionStatement); + SettableFuture createContinuousQuery( CreateContinuousQueryStatement createContinuousQueryStatement, MPPQueryContext context); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ReconstructRegionTask.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ReconstructRegionTask.java new file mode 100644 index 000000000000..c89a0f38cd53 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ReconstructRegionTask.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.iotdb.db.queryengine.plan.execution.config.metadata; + +import org.apache.iotdb.db.queryengine.plan.execution.config.ConfigTaskResult; +import org.apache.iotdb.db.queryengine.plan.execution.config.IConfigTask; +import org.apache.iotdb.db.queryengine.plan.execution.config.executor.IConfigTaskExecutor; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.ReconstructRegionStatement; + +import com.google.common.util.concurrent.ListenableFuture; + +public class ReconstructRegionTask implements IConfigTask { + + protected final ReconstructRegionStatement reconstructRegionStatement; + + public ReconstructRegionTask(ReconstructRegionStatement reconstructRegionStatement) { + this.reconstructRegionStatement = reconstructRegionStatement; + } + + @Override + public ListenableFuture execute(IConfigTaskExecutor configTaskExecutor) + throws InterruptedException { + return null; + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java index 6c0ee3db2542..f74ad159630d 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java @@ -149,6 +149,7 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetSeriesSlotListStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetTimeSlotListStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.MigrateRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.ReconstructRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.SetTTLStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowChildNodesStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowChildPathsStatement; @@ -227,6 +228,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.io.BaseEncoding; +import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.TerminalNode; import org.apache.tsfile.common.conf.TSFileDescriptor; import org.apache.tsfile.common.constant.TsFileConstant; @@ -4178,6 +4180,17 @@ public Statement visitMigrateRegion(IoTDBSqlParser.MigrateRegionContext ctx) { Integer.parseInt(ctx.toId.getText())); } + @Override + public Statement visitReconstructRegion(IoTDBSqlParser.ReconstructRegionContext ctx) { + int dataNodeId = Integer.parseInt(ctx.targetDataNodeId.getText()); + List regionIds = + ctx.INTEGER_LITERAL().stream() + .map(ParseTree::getText) + .map(Integer::parseInt) + .collect(Collectors.toList()); + return new ReconstructRegionStatement(dataNodeId, regionIds); + } + @Override public Statement visitVerifyConnection(IoTDBSqlParser.VerifyConnectionContext ctx) { return new TestConnectionStatement(ctx.DETAILS() != null); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/StatementVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/StatementVisitor.java index d15677de60b7..eec93cb7a7e4 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/StatementVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/StatementVisitor.java @@ -56,6 +56,7 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetSeriesSlotListStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetTimeSlotListStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.MigrateRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.ReconstructRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.SetTTLStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowChildNodesStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowChildPathsStatement; @@ -577,6 +578,11 @@ public R visitMigrateRegion(MigrateRegionStatement migrateRegionStatement, C con return visitStatement(migrateRegionStatement, context); } + public R visitReconstructRegion( + ReconstructRegionStatement reconstructRegionStatement, C context) { + return visitStatement(reconstructRegionStatement, context); + } + public R visitDeactivateTemplate( DeactivateTemplateStatement deactivateTemplateStatement, C context) { return visitStatement(deactivateTemplateStatement, context); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ReconstructRegionStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ReconstructRegionStatement.java new file mode 100644 index 000000000000..f231f7359733 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ReconstructRegionStatement.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.iotdb.db.queryengine.plan.statement.metadata; + +import org.apache.iotdb.commons.path.PartialPath; +import org.apache.iotdb.db.queryengine.plan.analyze.QueryType; +import org.apache.iotdb.db.queryengine.plan.statement.IConfigStatement; +import org.apache.iotdb.db.queryengine.plan.statement.Statement; +import org.apache.iotdb.db.queryengine.plan.statement.StatementVisitor; + +import java.util.Collections; +import java.util.List; + +public class ReconstructRegionStatement extends Statement implements IConfigStatement { + final int dataNodeId; + final List regionIds; + + public ReconstructRegionStatement(int dataNodeId, List regionIds) { + this.dataNodeId = dataNodeId; + this.regionIds = regionIds; + } + + public int getDataNodeId() { + return dataNodeId; + } + + public List getRegionIds() { + return regionIds; + } + + @Override + public R accept(StatementVisitor visitor, C context) { + return visitor.visitReconstructRegion(this, context); + } + + @Override + public QueryType getQueryType() { + return QueryType.WRITE; + } + + @Override + public List getPaths() { + return Collections.emptyList(); + } +} diff --git a/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift b/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift index f4ae17689894..2a7cfb163740 100644 --- a/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift +++ b/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift @@ -312,6 +312,11 @@ struct TMigrateRegionReq { 3: required i32 toId } +struct TReconstructRegionReq { + 1: required i32 dataNodeId + 2: required list regionIds +} + // Authorize struct TAuthorizerReq { 1: required i32 authorType @@ -1536,6 +1541,8 @@ service IConfigNodeRPCService { /** Migrate a region replica from one dataNode to another */ common.TSStatus migrateRegion(TMigrateRegionReq req) + common.TSStatus reconstructRegion(TReconstructRegionReq req) + /** Kill query */ common.TSStatus killQuery(string queryId, i32 dataNodeId) From ceba31602e44630138f3d3118c53df1f041b1521 Mon Sep 17 00:00:00 2001 From: liyuheng Date: Tue, 12 Nov 2024 09:55:20 +0800 Subject: [PATCH 02/13] save --- .../confignode/manager/ProcedureManager.java | 24 ++- .../region/ReconstructRegionProcedure.java | 154 ++++++++++++++++++ .../impl/region/RegionMigrateProcedure.java | 8 +- .../state/ReconstructRegionState.java | 28 ++++ 4 files changed, 209 insertions(+), 5 deletions(-) create mode 100644 iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/ReconstructRegionProcedure.java create mode 100644 iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/ReconstructRegionState.java diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java index edc8046c4978..072fa9c151e7 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java @@ -927,8 +927,28 @@ public TSStatus migrateRegion(TMigrateRegionReq migrateRegionReq) { } } - public TSStatus reconstructRegion(TReconstructRegionReq reconstructRegionReq) { - return null; + public TSStatus reconstructRegion(TReconstructRegionReq req) { + final TDataNodeLocation targetDataNode = configManager + .getNodeManager() + .getRegisteredDataNode(req.getDataNodeId()) + .getLocation(); + for (int x : req.getRegionIds()) { + TConsensusGroupId regionId = configManager + .getPartitionManager() + .generateTConsensusGroupIdByRegionId(x).orElseThrow(() -> new IllegalArgumentException("Region id " + x + " is invalid")); + + + } + RegionMaintainHandler handler = env.getRegionMaintainHandler(); + final TDataNodeLocation coordinator = + handler.filterDataNodeWithOtherRegionReplica( + regionId, + destDataNode, + NodeStatus.Running, + NodeStatus.Removing, + NodeStatus.ReadOnly) + .orElse(null); + this.executor.submitProcedure() } // endregion diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/ReconstructRegionProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/ReconstructRegionProcedure.java new file mode 100644 index 000000000000..a07dd3d09158 --- /dev/null +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/ReconstructRegionProcedure.java @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.iotdb.confignode.procedure.impl.region; + +import org.apache.iotdb.common.rpc.thrift.TConsensusGroupId; +import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation; +import org.apache.iotdb.commons.utils.CommonDateTimeUtils; +import org.apache.iotdb.confignode.procedure.env.ConfigNodeProcedureEnv; +import org.apache.iotdb.confignode.procedure.exception.ProcedureException; +import org.apache.iotdb.confignode.procedure.exception.ProcedureSuspendedException; +import org.apache.iotdb.confignode.procedure.exception.ProcedureYieldException; +import org.apache.iotdb.confignode.procedure.impl.StateMachineProcedure; +import org.apache.iotdb.confignode.procedure.state.ProcedureLockState; +import org.apache.iotdb.confignode.procedure.state.ReconstructRegionState; +import org.apache.iotdb.db.utils.DateTimeUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +public class ReconstructRegionProcedure + extends StateMachineProcedure { + private static final Logger LOGGER = LoggerFactory.getLogger(ReconstructRegionProcedure.class); + + private final TConsensusGroupId regionId; + private final TDataNodeLocation targetDataNode; + private final TDataNodeLocation coordinator; + + public ReconstructRegionProcedure( + TConsensusGroupId regionId, TDataNodeLocation targetDataNode, TDataNodeLocation coordinator) { + this.regionId = regionId; + this.targetDataNode = targetDataNode; + this.coordinator = coordinator; + } + + @Override + protected Flow executeFromState(ConfigNodeProcedureEnv env, ReconstructRegionState state) + throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException { + try { + switch (state) { + case RECONSTRUCT_REGION_PREPARE: + LOGGER.info( + "[pid{}][ReconstructRegion] started, region {} on DataNode {}({}) will be reconstructed.", + getProcId(), + regionId.getId(), + targetDataNode.getDataNodeId(), + targetDataNode.getInternalEndPoint()); + setNextState(ReconstructRegionState.REMOVE_REGION_PEER); + break; + case REMOVE_REGION_PEER: + addChildProcedure(new RemoveRegionPeerProcedure(regionId, coordinator, targetDataNode)); + setNextState(ReconstructRegionState.REMOVE_REGION_PEER); + break; + case CHECK_REMOVE_REGION_PEER: + if (env.getConfigManager() + .getPartitionManager() + .isDataNodeContainsRegion(targetDataNode.getDataNodeId(), regionId)) { + LOGGER.warn( + "[pid{}][ReconstructRegion] sub-procedure RemoveRegionPeerProcedure failed, ReconstructRegionProcedure will not continue", + getProcId()); + return Flow.NO_MORE_STATE; + } + setNextState(ReconstructRegionState.ADD_REGION_PEER); + break; + case ADD_REGION_PEER: + addChildProcedure(new AddRegionPeerProcedure(regionId, coordinator, targetDataNode)); + setNextState(ReconstructRegionState.CHECK_ADD_REGION_PEER); + break; + case CHECK_ADD_REGION_PEER: + if (!env.getConfigManager() + .getPartitionManager() + .isDataNodeContainsRegion(targetDataNode.getDataNodeId(), regionId)) { + LOGGER.warn( + "[pid{}][ReconstructRegion] failed, but the region {} has been removed from DataNode {}. Use 'extend region' to fix this.", + getProcId(), + regionId.getId(), + targetDataNode.getDataNodeId()); + } else { + LOGGER.info( + "[pid{}][ReconstructRegion] success, region {} has been reconstructed on DataNode {}. Procedure took {} (started at {})", + getProcId(), + regionId.getId(), + targetDataNode.getDataNodeId(), + CommonDateTimeUtils.convertMillisecondToDurationStr( + System.currentTimeMillis() - getSubmittedTime()), + DateTimeUtils.convertLongToDate(getSubmittedTime(), "ms")); + } + return Flow.NO_MORE_STATE; + default: + throw new ProcedureException("Unsupported state: " + state.name()); + } + } catch (Exception e) { + LOGGER.error("[pid{}][ReconstructRegion] state {} fail", getProcId(), state, e); + return Flow.NO_MORE_STATE; + } + LOGGER.info("[pid{}][ReconstructRegion] state {} complete", getProcId(), state); + return Flow.HAS_MORE_STATE; + } + + @Override + protected void rollbackState( + ConfigNodeProcedureEnv configNodeProcedureEnv, ReconstructRegionState reconstructRegionState) + throws IOException, InterruptedException, ProcedureException {} + + @Override + protected ProcedureLockState acquireLock(ConfigNodeProcedureEnv configNodeProcedureEnv) { + configNodeProcedureEnv.getSchedulerLock().lock(); + try { + if (configNodeProcedureEnv.getRegionMigrateLock().tryLock(this)) { + LOGGER.info("procedureId {} acquire lock.", getProcId()); + return ProcedureLockState.LOCK_ACQUIRED; + } + configNodeProcedureEnv.getRegionMigrateLock().waitProcedure(this); + + LOGGER.info("procedureId {} wait for lock.", getProcId()); + return ProcedureLockState.LOCK_EVENT_WAIT; + } finally { + configNodeProcedureEnv.getSchedulerLock().unlock(); + } + } + + @Override + protected ReconstructRegionState getState(int stateId) { + return ReconstructRegionState.values()[stateId]; + } + + @Override + protected int getStateId(ReconstructRegionState reconstructRegionState) { + return reconstructRegionState.ordinal(); + } + + @Override + protected ReconstructRegionState getInitialState() { + return ReconstructRegionState.RECONSTRUCT_REGION_PREPARE; + } +} diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMigrateProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMigrateProcedure.java index 21904a576f33..3c03cf49b7b2 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMigrateProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMigrateProcedure.java @@ -83,11 +83,13 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, RegionTransitionStat switch (state) { case REGION_MIGRATE_PREPARE: LOGGER.info( - "[pid{}][MigrateRegion] started, region {} will be migrated from DataNode {} to {}.", + "[pid{}][MigrateRegion] started, region {} will be migrated from DataNode {}({}) to {}({}).", getProcId(), consensusGroupId.getId(), originalDataNode.getDataNodeId(), - destDataNode.getDataNodeId()); + originalDataNode.getInternalEndPoint(), + destDataNode.getDataNodeId(), + destDataNode.getInternalEndPoint()); setNextState(RegionTransitionState.ADD_REGION_PEER); break; case ADD_REGION_PEER: @@ -100,7 +102,7 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, RegionTransitionStat .getPartitionManager() .isDataNodeContainsRegion(destDataNode.getDataNodeId(), consensusGroupId)) { LOGGER.warn( - "[pid{}][MigrateRegion] sub-procedure AddRegionPeerProcedure fail, RegionMigrateProcedure will not continue", + "[pid{}][MigrateRegion] sub-procedure AddRegionPeerProcedure failed, RegionMigrateProcedure will not continue", getProcId()); return Flow.NO_MORE_STATE; } diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/ReconstructRegionState.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/ReconstructRegionState.java new file mode 100644 index 000000000000..ef7abc5329cc --- /dev/null +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/ReconstructRegionState.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.iotdb.confignode.procedure.state; + +public enum ReconstructRegionState { + RECONSTRUCT_REGION_PREPARE, + REMOVE_REGION_PEER, + CHECK_REMOVE_REGION_PEER, + ADD_REGION_PEER, + CHECK_ADD_REGION_PEER, +} From 89840175b6668c1839c0fd47629411248c1cf3cc Mon Sep 17 00:00:00 2001 From: liyuheng Date: Tue, 12 Nov 2024 15:54:44 +0800 Subject: [PATCH 03/13] it works --- .../confignode/manager/ProcedureManager.java | 197 +++++++++++++++--- .../impl/region/AddRegionPeerProcedure.java | 51 ++--- .../region/ReconstructRegionProcedure.java | 70 ++++++- .../region/RegionMemberChangeProcedure.java | 48 +++++ .../impl/region/RegionMigrateProcedure.java | 37 ++-- .../region/RemoveRegionPeerProcedure.java | 40 ++-- .../procedure/store/ProcedureFactory.java | 5 + .../procedure/store/ProcedureType.java | 7 +- .../metadata/ReconstructRegionTask.java | 2 +- .../queryengine/plan/parser/ASTVisitor.java | 1 + 10 files changed, 345 insertions(+), 113 deletions(-) create mode 100644 iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMemberChangeProcedure.java diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java index 072fa9c151e7..4b13fa9dc7b7 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java @@ -75,6 +75,8 @@ import org.apache.iotdb.confignode.procedure.impl.pipe.task.StartPipeProcedureV2; import org.apache.iotdb.confignode.procedure.impl.pipe.task.StopPipeProcedureV2; import org.apache.iotdb.confignode.procedure.impl.region.CreateRegionGroupsProcedure; +import org.apache.iotdb.confignode.procedure.impl.region.ReconstructRegionProcedure; +import org.apache.iotdb.confignode.procedure.impl.region.RegionMemberChangeProcedure; import org.apache.iotdb.confignode.procedure.impl.region.RegionMigrateProcedure; import org.apache.iotdb.confignode.procedure.impl.region.RegionMigrationPlan; import org.apache.iotdb.confignode.procedure.impl.schema.AlterLogicalViewProcedure; @@ -136,6 +138,7 @@ import org.apache.iotdb.rpc.RpcUtils; import org.apache.iotdb.rpc.TSStatusCode; +import org.apache.ratis.util.AutoCloseableLock; import org.apache.tsfile.utils.Binary; import org.apache.tsfile.utils.Pair; import org.apache.tsfile.utils.ReadWriteIOUtils; @@ -656,8 +659,7 @@ public TSStatus checkRemoveDataNodes(List dataNodeLocations) if (regionMigrateProcedure.isFinished()) { return false; } - return removedDataNodesRegionSet.contains( - regionMigrateProcedure.getConsensusGroupId()) + return removedDataNodesRegionSet.contains(regionMigrateProcedure.getRegionId()) || dataNodeLocations.contains(regionMigrateProcedure.getDestDataNode()); } return false; @@ -671,7 +673,7 @@ public TSStatus checkRemoveDataNodes(List dataNodeLocations) + "The RegionMigrateProcedure is migrating the region %s to the DataNode %s. " + "For further information, please search [pid%d] in log. ", conflictRegionMigrateProcedure.get().getProcId(), - ((RegionMigrateProcedure) conflictRegionMigrateProcedure.get()).getConsensusGroupId(), + ((RegionMigrateProcedure) conflictRegionMigrateProcedure.get()).getRegionId(), ((RegionMigrateProcedure) conflictRegionMigrateProcedure.get()).getDestDataNode(), conflictRegionMigrateProcedure.get().getProcId()); } @@ -726,9 +728,7 @@ private TSStatus checkRegionMigrate( procedure -> { if (procedure instanceof RegionMigrateProcedure) { return !procedure.isFinished() - && ((RegionMigrateProcedure) procedure) - .getConsensusGroupId() - .equals(regionGroupId); + && ((RegionMigrateProcedure) procedure).getRegionId().equals(regionGroupId); } return false; }) @@ -914,7 +914,7 @@ public TSStatus migrateRegion(TMigrateRegionReq migrateRegionReq) { coordinatorForAddPeer, coordinatorForRemovePeer)); LOGGER.info( - "Submit RegionMigrateProcedure successfully, Region: {}, Origin DataNode: {}, Dest DataNode: {}, Add Coordinator: {}, Remove Coordinator: {}", + "[MigrateRegion] Submit RegionMigrateProcedure successfully, Region: {}, Origin DataNode: {}, Dest DataNode: {}, Add Coordinator: {}, Remove Coordinator: {}", regionGroupId, originalDataNode, destDataNode, @@ -928,27 +928,174 @@ public TSStatus migrateRegion(TMigrateRegionReq migrateRegionReq) { } public TSStatus reconstructRegion(TReconstructRegionReq req) { - final TDataNodeLocation targetDataNode = configManager - .getNodeManager() - .getRegisteredDataNode(req.getDataNodeId()) - .getLocation(); - for (int x : req.getRegionIds()) { - TConsensusGroupId regionId = configManager - .getPartitionManager() - .generateTConsensusGroupIdByRegionId(x).orElseThrow(() -> new IllegalArgumentException("Region id " + x + " is invalid")); + RegionMaintainHandler handler = env.getRegionMaintainHandler(); + final TDataNodeLocation targetDataNode = + configManager.getNodeManager().getRegisteredDataNode(req.getDataNodeId()).getLocation(); + try (AutoCloseableLock autoCloseableLock = + AutoCloseableLock.acquire(env.getSubmitRegionMigrateLock())) { + List procedures = new ArrayList<>(); + for (int x : req.getRegionIds()) { + TConsensusGroupId regionId = + configManager + .getPartitionManager() + .generateTConsensusGroupIdByRegionId(x) + .orElseThrow(() -> new IllegalArgumentException("Region id " + x + " is invalid")); + final TDataNodeLocation coordinator = + handler + .filterDataNodeWithOtherRegionReplica( + regionId, + targetDataNode, + NodeStatus.Running, + NodeStatus.Removing, + NodeStatus.ReadOnly) + .orElse(null); + TSStatus status = checkReconstructRegion(req, regionId, targetDataNode, coordinator); + if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { + return status; + } + procedures.add(new ReconstructRegionProcedure(regionId, targetDataNode, coordinator)); + } + // all checks pass, submit all procedures + procedures.forEach( + reconstructRegionProcedure -> { + this.executor.submitProcedure(reconstructRegionProcedure); + LOGGER.info( + "[ReconstructRegion] Submit ReconstructRegionProcedure successfully, {}", + reconstructRegionProcedure); + }); + } + return RpcUtils.SUCCESS_STATUS; + } + private TSStatus checkReconstructRegion( + TReconstructRegionReq req, + TConsensusGroupId regionId, + TDataNodeLocation targetDataNode, + TDataNodeLocation coordinator) { + String failMessage = null; + ConfigNodeConfig conf = ConfigNodeDescriptor.getInstance().getConf(); + if (TConsensusGroupType.DataRegion == regionId.getType() + && conf.getDataReplicationFactor() == 1) { + failMessage = + String.format( + "You are trying to reconstruct data region %s. This region is a single replica and does not support region reconstruction.", + regionId.getId()); + } else if (TConsensusGroupType.SchemaRegion == regionId.getType() + && conf.getSchemaReplicationFactor() == 1) { + failMessage = + String.format( + "You are trying to reconstruct schema region %s. This region is a single replica and does not support region reconstruction.", + regionId.getId()); + } else if ((failMessage = + checkRegionMemberChangeProcedureDuplication( + regionId, "Submit reconstruct region procedure failed")) + != null) { + // need to do nothing more + } else if (targetDataNode == null) { + failMessage = + String.format( + "Submit ReconstructRegionProcedure failed, because cannot find target DataNode %d", + req.getDataNodeId()); + } else if (coordinator == null) { + failMessage = + String.format( + "Submit ReconstructRegionProcedure failed, because there are no other DataNodes could be selected to perform the reconstruction process, " + + "please check RegionGroup: %s by show regions sql command", + regionId); + } else if (configManager + .getPartitionManager() + .getAllReplicaSets(targetDataNode.getDataNodeId()) + .stream() + .noneMatch(replicaSet -> replicaSet.getRegionId().equals(regionId))) { + failMessage = + String.format( + "Submit ReconstructRegionProcedure failed, because the target DataNode %s doesn't contain Region %s", + req.getDataNodeId(), regionId); + } else if (!configManager + .getNodeManager() + .filterDataNodeThroughStatus(NodeStatus.Running) + .stream() + .map(TDataNodeConfiguration::getLocation) + .map(TDataNodeLocation::getDataNodeId) + .collect(Collectors.toSet()) + .contains(targetDataNode.getDataNodeId())) { + // Here we only check Running DataNode to implement migration, because removing nodes may not + // exist when add peer is performing + failMessage = + String.format( + "Submit ReconstructRegionProcedure failed, because the target DataNode %s is not in Running status.", + targetDataNode.getDataNodeId()); } - RegionMaintainHandler handler = env.getRegionMaintainHandler(); - final TDataNodeLocation coordinator = - handler.filterDataNodeWithOtherRegionReplica( - regionId, - destDataNode, - NodeStatus.Running, - NodeStatus.Removing, - NodeStatus.ReadOnly) - .orElse(null); - this.executor.submitProcedure() + + // 2. Check if the RegionMigrateProcedure has conflict with RemoveDataNodesProcedure + Optional> conflictRemoveDataNodesProcedure = + getExecutor().getProcedures().values().stream() + .filter( + procedure -> { + if (procedure instanceof RemoveDataNodesProcedure) { + return !procedure.isFinished(); + } + return false; + }) + .findAny(); + + if (conflictRemoveDataNodesProcedure.isPresent()) { + RemoveDataNodeHandler removeDataNodeHandler = env.getRemoveDataNodeHandler(); + List removedDataNodes = + ((RemoveDataNodesProcedure) conflictRemoveDataNodesProcedure.get()).getRemovedDataNodes(); + Set removedDataNodesRegionSet = + removeDataNodeHandler.getRemovedDataNodesRegionSet(removedDataNodes); + if (removedDataNodesRegionSet.contains(regionId)) { + failMessage = + String.format( + "Submit ReconstructRegionProcedure failed, " + + "because another RemoveDataNodesProcedure %s is already in processing which conflicts with this RegionMigrateProcedure. " + + "The RemoveDataNodesProcedure is removing the DataNodes %s which contains the region %s. " + + "For further information, please search [pid%d] in log. ", + conflictRemoveDataNodesProcedure.get().getProcId(), + removedDataNodes, + regionId, + conflictRemoveDataNodesProcedure.get().getProcId()); + } else if (removedDataNodes.contains(targetDataNode)) { + failMessage = + String.format( + "Submit ReconstructRegionProcedure failed, " + + "because another RemoveDataNodesProcedure %s is already in processing which conflicts with this RegionMigrateProcedure. " + + "The RemoveDataNodesProcedure is removing the target DataNode %s. " + + "For further information, please search [pid%d] in log. ", + conflictRemoveDataNodesProcedure.get().getProcId(), + targetDataNode, + conflictRemoveDataNodesProcedure.get().getProcId()); + } + } + + if (failMessage != null) { + LOGGER.warn(failMessage); + TSStatus failStatus = new TSStatus(TSStatusCode.MIGRATE_REGION_ERROR.getStatusCode()); + failStatus.setMessage(failMessage); + return failStatus; + } + return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); + } + + private String checkRegionMemberChangeProcedureDuplication( + TConsensusGroupId regionId, String failedMessagePrefix) { + List> otherRegionMemberChangeProcedures = + getExecutor().getProcedures().values().stream() + .filter(procedure -> !procedure.isFinished()) + .filter(procedure -> procedure instanceof RegionMemberChangeProcedure) + .map(procedure -> (RegionMemberChangeProcedure) procedure) + .filter( + regionMemberChangeProcedure -> + regionId.equals(regionMemberChangeProcedure.getRegionId())) + .collect(Collectors.toList()); + if (!otherRegionMemberChangeProcedures.isEmpty()) { + return String.format( + "%s, because region %d has some other region membership change procedures in progress, their procedure id is: %s", + failedMessagePrefix, regionId.getId(), otherRegionMemberChangeProcedures); + } + return null; } // endregion diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/AddRegionPeerProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/AddRegionPeerProcedure.java index d06f40d33312..6e292d29ae91 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/AddRegionPeerProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/AddRegionPeerProcedure.java @@ -31,7 +31,6 @@ import org.apache.iotdb.confignode.procedure.exception.ProcedureException; import org.apache.iotdb.confignode.procedure.exception.ProcedureSuspendedException; import org.apache.iotdb.confignode.procedure.exception.ProcedureYieldException; -import org.apache.iotdb.confignode.procedure.impl.StateMachineProcedure; import org.apache.iotdb.confignode.procedure.state.AddRegionPeerState; import org.apache.iotdb.confignode.procedure.store.ProcedureType; import org.apache.iotdb.db.utils.DateTimeUtils; @@ -53,10 +52,8 @@ import static org.apache.iotdb.confignode.procedure.state.AddRegionPeerState.UPDATE_REGION_LOCATION_CACHE; import static org.apache.iotdb.rpc.TSStatusCode.SUCCESS_STATUS; -public class AddRegionPeerProcedure - extends StateMachineProcedure { +public class AddRegionPeerProcedure extends RegionMemberChangeProcedure { private static final Logger LOGGER = LoggerFactory.getLogger(AddRegionPeerProcedure.class); - private TConsensusGroupId consensusGroupId; private TDataNodeLocation coordinator; @@ -70,8 +67,7 @@ public AddRegionPeerProcedure( TConsensusGroupId consensusGroupId, TDataNodeLocation coordinator, TDataNodeLocation destDataNode) { - super(); - this.consensusGroupId = consensusGroupId; + super(consensusGroupId); this.coordinator = coordinator; this.destDataNode = destDataNode; } @@ -79,7 +75,7 @@ public AddRegionPeerProcedure( @Override protected Flow executeFromState(ConfigNodeProcedureEnv env, AddRegionPeerState state) throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException { - if (consensusGroupId == null) { + if (regionId == null) { return Flow.NO_MORE_STATE; } RegionMaintainHandler handler = env.getRegionMaintainHandler(); @@ -90,11 +86,11 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, AddRegionPeerState s LOGGER.info( "[pid{}][AddRegion] started, region {} will be added to DataNode {}.", getProcId(), - consensusGroupId.getId(), + regionId.getId(), destDataNode.getDataNodeId()); - handler.addRegionLocation(consensusGroupId, destDataNode); - handler.forceUpdateRegionCache(consensusGroupId, destDataNode, RegionStatus.Adding); - TSStatus status = handler.createNewRegionPeer(consensusGroupId, destDataNode); + handler.addRegionLocation(regionId, destDataNode); + handler.forceUpdateRegionCache(regionId, destDataNode, RegionStatus.Adding); + TSStatus status = handler.createNewRegionPeer(regionId, destDataNode); setKillPoint(state); if (status.getCode() != SUCCESS_STATUS.getStatusCode()) { return warnAndRollBackAndNoMoreState(env, handler, "CREATE_NEW_REGION_PEER fail"); @@ -102,12 +98,12 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, AddRegionPeerState s setNextState(AddRegionPeerState.DO_ADD_REGION_PEER); break; case DO_ADD_REGION_PEER: - handler.forceUpdateRegionCache(consensusGroupId, destDataNode, RegionStatus.Adding); + handler.forceUpdateRegionCache(regionId, destDataNode, RegionStatus.Adding); // We don't want to re-submit AddRegionPeerTask when leader change or ConfigNode reboot if (!this.isStateDeserialized()) { TSStatus tsStatus = handler.submitAddRegionPeerTask( - this.getProcId(), destDataNode, consensusGroupId, coordinator); + this.getProcId(), destDataNode, regionId, coordinator); setKillPoint(state); if (tsStatus.getCode() != SUCCESS_STATUS.getStatusCode()) { return warnAndRollBackAndNoMoreState( @@ -133,13 +129,13 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, AddRegionPeerState s env, handler, String.format("status %s is unsupported", result.getTaskStatus())); } case UPDATE_REGION_LOCATION_CACHE: - handler.forceUpdateRegionCache(consensusGroupId, destDataNode, RegionStatus.Running); + handler.forceUpdateRegionCache(regionId, destDataNode, RegionStatus.Running); setKillPoint(state); LOGGER.info("[pid{}][AddRegion] state {} complete", getProcId(), state); LOGGER.info( "[pid{}][AddRegion] success, region {} has been added to DataNode {}. Procedure took {} (start at {}).", getProcId(), - consensusGroupId.getId(), + regionId.getId(), destDataNode.getDataNodeId(), CommonDateTimeUtils.convertMillisecondToDurationStr( System.currentTimeMillis() - getSubmittedTime()), @@ -170,11 +166,11 @@ private Flow warnAndRollBackAndNoMoreState( } else { LOGGER.warn("[pid{}][AddRegion] Start to roll back, because: {}", getProcId(), reason); } - handler.removeRegionLocation(consensusGroupId, destDataNode); + handler.removeRegionLocation(regionId, destDataNode); List correctDataNodeLocations = env.getConfigManager().getPartitionManager().getAllReplicaSets().stream() - .filter(tRegionReplicaSet -> tRegionReplicaSet.getRegionId().equals(consensusGroupId)) + .filter(tRegionReplicaSet -> tRegionReplicaSet.getRegionId().equals(regionId)) .findAny() .orElseThrow( () -> @@ -203,15 +199,14 @@ private Flow warnAndRollBackAndNoMoreState( LOGGER.info( "[pid{}][AddRegion] reset peer list: peer list of consensus group {} on DataNode {} will be reset to {}", getProcId(), - consensusGroupId, + regionId, relatedDataNodeLocationMap.values().stream() .map(TDataNodeLocation::getDataNodeId) .collect(Collectors.toList()), correctStr); Map resultMap = - handler.resetPeerList( - consensusGroupId, correctDataNodeLocations, relatedDataNodeLocationMap); + handler.resetPeerList(regionId, correctDataNodeLocations, relatedDataNodeLocationMap); resultMap.forEach( (dataNodeId, resetResult) -> { @@ -219,7 +214,7 @@ private Flow warnAndRollBackAndNoMoreState( LOGGER.info( "[pid{}][AddRegion] reset peer list: peer list of consensus group {} on DataNode {} has been successfully reset to {}", getProcId(), - consensusGroupId, + regionId, dataNodeId, correctStr); } else { @@ -227,7 +222,7 @@ private Flow warnAndRollBackAndNoMoreState( LOGGER.warn( "[pid{}][AddRegion] reset peer list: peer list of consensus group {} on DataNode {} failed to reset to {}, you may manually reset it", getProcId(), - consensusGroupId, + regionId, dataNodeId, correctStr); } @@ -259,7 +254,7 @@ protected AddRegionPeerState getInitialState() { public void serialize(DataOutputStream stream) throws IOException { stream.writeShort(ProcedureType.ADD_REGION_PEER_PROCEDURE.getTypeCode()); super.serialize(stream); - ThriftCommonsSerDeUtils.serializeTConsensusGroupId(consensusGroupId, stream); + ThriftCommonsSerDeUtils.serializeTConsensusGroupId(regionId, stream); ThriftCommonsSerDeUtils.serializeTDataNodeLocation(destDataNode, stream); ThriftCommonsSerDeUtils.serializeTDataNodeLocation(coordinator, stream); } @@ -268,7 +263,7 @@ public void serialize(DataOutputStream stream) throws IOException { public void deserialize(ByteBuffer byteBuffer) { super.deserialize(byteBuffer); try { - consensusGroupId = ThriftCommonsSerDeUtils.deserializeTConsensusGroupId(byteBuffer); + regionId = ThriftCommonsSerDeUtils.deserializeTConsensusGroupId(byteBuffer); destDataNode = ThriftCommonsSerDeUtils.deserializeTDataNodeLocation(byteBuffer); coordinator = ThriftCommonsSerDeUtils.deserializeTDataNodeLocation(byteBuffer); } catch (ThriftSerDeException e) { @@ -276,10 +271,6 @@ public void deserialize(ByteBuffer byteBuffer) { } } - public TConsensusGroupId getConsensusGroupId() { - return consensusGroupId; - } - public TDataNodeLocation getCoordinator() { return coordinator; } @@ -290,13 +281,13 @@ public boolean equals(Object obj) { return false; } AddRegionPeerProcedure procedure = (AddRegionPeerProcedure) obj; - return this.consensusGroupId.equals(procedure.consensusGroupId) + return this.regionId.equals(procedure.regionId) && this.destDataNode.equals(procedure.destDataNode) && this.coordinator.equals(procedure.coordinator); } @Override public int hashCode() { - return Objects.hash(consensusGroupId, destDataNode, coordinator); + return Objects.hash(regionId, destDataNode, coordinator); } } diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/ReconstructRegionProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/ReconstructRegionProcedure.java index a07dd3d09158..0c3d14ceb368 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/ReconstructRegionProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/ReconstructRegionProcedure.java @@ -21,32 +21,38 @@ import org.apache.iotdb.common.rpc.thrift.TConsensusGroupId; import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation; +import org.apache.iotdb.commons.exception.runtime.ThriftSerDeException; import org.apache.iotdb.commons.utils.CommonDateTimeUtils; +import org.apache.iotdb.commons.utils.ThriftCommonsSerDeUtils; import org.apache.iotdb.confignode.procedure.env.ConfigNodeProcedureEnv; import org.apache.iotdb.confignode.procedure.exception.ProcedureException; import org.apache.iotdb.confignode.procedure.exception.ProcedureSuspendedException; import org.apache.iotdb.confignode.procedure.exception.ProcedureYieldException; -import org.apache.iotdb.confignode.procedure.impl.StateMachineProcedure; import org.apache.iotdb.confignode.procedure.state.ProcedureLockState; import org.apache.iotdb.confignode.procedure.state.ReconstructRegionState; +import org.apache.iotdb.confignode.procedure.store.ProcedureType; import org.apache.iotdb.db.utils.DateTimeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.DataOutputStream; import java.io.IOException; +import java.nio.ByteBuffer; public class ReconstructRegionProcedure - extends StateMachineProcedure { + extends RegionMemberChangeProcedure { private static final Logger LOGGER = LoggerFactory.getLogger(ReconstructRegionProcedure.class); - private final TConsensusGroupId regionId; - private final TDataNodeLocation targetDataNode; - private final TDataNodeLocation coordinator; + private TDataNodeLocation targetDataNode; + private TDataNodeLocation coordinator; + + public ReconstructRegionProcedure() {} + ; public ReconstructRegionProcedure( TConsensusGroupId regionId, TDataNodeLocation targetDataNode, TDataNodeLocation coordinator) { - this.regionId = regionId; + super(regionId); this.targetDataNode = targetDataNode; this.coordinator = coordinator; } @@ -67,7 +73,7 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, ReconstructRegionSta break; case REMOVE_REGION_PEER: addChildProcedure(new RemoveRegionPeerProcedure(regionId, coordinator, targetDataNode)); - setNextState(ReconstructRegionState.REMOVE_REGION_PEER); + setNextState(ReconstructRegionState.CHECK_REMOVE_REGION_PEER); break; case CHECK_REMOVE_REGION_PEER: if (env.getConfigManager() @@ -137,6 +143,47 @@ protected ProcedureLockState acquireLock(ConfigNodeProcedureEnv configNodeProced } } + @Override + protected void releaseLock(ConfigNodeProcedureEnv configNodeProcedureEnv) { + configNodeProcedureEnv.getSchedulerLock().lock(); + try { + LOGGER.info("procedureId {} release lock.", getProcId()); + if (configNodeProcedureEnv.getRegionMigrateLock().releaseLock(this)) { + configNodeProcedureEnv + .getRegionMigrateLock() + .wakeWaitingProcedures(configNodeProcedureEnv.getScheduler()); + } + } finally { + configNodeProcedureEnv.getSchedulerLock().unlock(); + } + } + + @Override + public void serialize(DataOutputStream stream) throws IOException { + stream.writeShort(ProcedureType.RECONSTRUCT_REGION_PROCEDURE.getTypeCode()); + super.serialize(stream); + ThriftCommonsSerDeUtils.serializeTConsensusGroupId(regionId, stream); + ThriftCommonsSerDeUtils.serializeTDataNodeLocation(targetDataNode, stream); + ThriftCommonsSerDeUtils.serializeTDataNodeLocation(coordinator, stream); + } + + @Override + public void deserialize(ByteBuffer byteBuffer) { + super.deserialize(byteBuffer); + try { + regionId = ThriftCommonsSerDeUtils.deserializeTConsensusGroupId(byteBuffer); + targetDataNode = ThriftCommonsSerDeUtils.deserializeTDataNodeLocation(byteBuffer); + coordinator = ThriftCommonsSerDeUtils.deserializeTDataNodeLocation(byteBuffer); + } catch (ThriftSerDeException e) { + LOGGER.warn( + "Error in deserialize {} (procID {}). This procedure will be ignored. It may belong to old version and cannot be used now.", + this.getClass(), + this.getProcId(), + e); + throw e; + } + } + @Override protected ReconstructRegionState getState(int stateId) { return ReconstructRegionState.values()[stateId]; @@ -151,4 +198,13 @@ protected int getStateId(ReconstructRegionState reconstructRegionState) { protected ReconstructRegionState getInitialState() { return ReconstructRegionState.RECONSTRUCT_REGION_PREPARE; } + + @Override + public String toString() { + return super.toString() + + ", targetDataNode=" + + targetDataNode.getDataNodeId() + + ", coordinator=" + + coordinator.getDataNodeId(); + } } diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMemberChangeProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMemberChangeProcedure.java new file mode 100644 index 000000000000..00976e1a7eda --- /dev/null +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMemberChangeProcedure.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.iotdb.confignode.procedure.impl.region; + +import org.apache.iotdb.common.rpc.thrift.TConsensusGroupId; +import org.apache.iotdb.confignode.procedure.env.ConfigNodeProcedureEnv; +import org.apache.iotdb.confignode.procedure.impl.StateMachineProcedure; + +public abstract class RegionMemberChangeProcedure + extends StateMachineProcedure { + TConsensusGroupId regionId; + + public RegionMemberChangeProcedure() {} + + public RegionMemberChangeProcedure(TConsensusGroupId regionId) { + this.regionId = regionId; + } + + public void setRegionId(TConsensusGroupId regionId) { + this.regionId = regionId; + } + + public TConsensusGroupId getRegionId() { + return regionId; + } + + @Override + public String toString() { + return super.toString() + ", regionId=" + regionId; + } +} diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMigrateProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMigrateProcedure.java index 3c03cf49b7b2..e9123ad9004d 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMigrateProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMigrateProcedure.java @@ -27,7 +27,6 @@ import org.apache.iotdb.confignode.procedure.env.ConfigNodeProcedureEnv; import org.apache.iotdb.confignode.procedure.env.RegionMaintainHandler; import org.apache.iotdb.confignode.procedure.exception.ProcedureException; -import org.apache.iotdb.confignode.procedure.impl.StateMachineProcedure; import org.apache.iotdb.confignode.procedure.state.ProcedureLockState; import org.apache.iotdb.confignode.procedure.state.RegionTransitionState; import org.apache.iotdb.confignode.procedure.store.ProcedureType; @@ -42,15 +41,13 @@ import java.util.Objects; /** Region migrate procedure */ -public class RegionMigrateProcedure - extends StateMachineProcedure { +public class RegionMigrateProcedure extends RegionMemberChangeProcedure { private static final Logger LOGGER = LoggerFactory.getLogger(RegionMigrateProcedure.class); /** Wait region migrate finished */ - private TConsensusGroupId consensusGroupId; - private TDataNodeLocation originalDataNode; + private TDataNodeLocation destDataNode; private TDataNodeLocation coordinatorForAddPeer; private TDataNodeLocation coordinatorForRemovePeer; @@ -65,8 +62,7 @@ public RegionMigrateProcedure( TDataNodeLocation destDataNode, TDataNodeLocation coordinatorForAddPeer, TDataNodeLocation coordinatorForRemovePeer) { - super(); - this.consensusGroupId = consensusGroupId; + super(consensusGroupId); this.originalDataNode = originalDataNode; this.destDataNode = destDataNode; this.coordinatorForAddPeer = coordinatorForAddPeer; @@ -75,7 +71,7 @@ public RegionMigrateProcedure( @Override protected Flow executeFromState(ConfigNodeProcedureEnv env, RegionTransitionState state) { - if (consensusGroupId == null) { + if (regionId == null) { return Flow.NO_MORE_STATE; } RegionMaintainHandler handler = env.getRegionMaintainHandler(); @@ -85,7 +81,7 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, RegionTransitionStat LOGGER.info( "[pid{}][MigrateRegion] started, region {} will be migrated from DataNode {}({}) to {}({}).", getProcId(), - consensusGroupId.getId(), + regionId.getId(), originalDataNode.getDataNodeId(), originalDataNode.getInternalEndPoint(), destDataNode.getDataNodeId(), @@ -94,13 +90,13 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, RegionTransitionStat break; case ADD_REGION_PEER: addChildProcedure( - new AddRegionPeerProcedure(consensusGroupId, coordinatorForAddPeer, destDataNode)); + new AddRegionPeerProcedure(regionId, coordinatorForAddPeer, destDataNode)); setNextState(RegionTransitionState.CHECK_ADD_REGION_PEER); break; case CHECK_ADD_REGION_PEER: if (!env.getConfigManager() .getPartitionManager() - .isDataNodeContainsRegion(destDataNode.getDataNodeId(), consensusGroupId)) { + .isDataNodeContainsRegion(destDataNode.getDataNodeId(), regionId)) { LOGGER.warn( "[pid{}][MigrateRegion] sub-procedure AddRegionPeerProcedure failed, RegionMigrateProcedure will not continue", getProcId()); @@ -110,14 +106,13 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, RegionTransitionStat break; case REMOVE_REGION_PEER: addChildProcedure( - new RemoveRegionPeerProcedure( - consensusGroupId, coordinatorForRemovePeer, originalDataNode)); + new RemoveRegionPeerProcedure(regionId, coordinatorForRemovePeer, originalDataNode)); setNextState(RegionTransitionState.CHECK_REMOVE_REGION_PEER); break; case CHECK_REMOVE_REGION_PEER: if (env.getConfigManager() .getPartitionManager() - .isDataNodeContainsRegion(originalDataNode.getDataNodeId(), consensusGroupId)) { + .isDataNodeContainsRegion(originalDataNode.getDataNodeId(), regionId)) { LOGGER.warn( "[pid{}][MigrateRegion] success, but you may need to manually clean the old region to make everything works fine", getProcId()); @@ -125,7 +120,7 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, RegionTransitionStat LOGGER.info( "[pid{}][MigrateRegion] success, region {} has been migrated from DataNode {} to {}. Procedure took {} (started at {})", getProcId(), - consensusGroupId.getId(), + regionId.getId(), originalDataNode.getDataNodeId(), destDataNode.getDataNodeId(), CommonDateTimeUtils.convertMillisecondToDurationStr( @@ -202,7 +197,7 @@ public void serialize(DataOutputStream stream) throws IOException { super.serialize(stream); ThriftCommonsSerDeUtils.serializeTDataNodeLocation(originalDataNode, stream); ThriftCommonsSerDeUtils.serializeTDataNodeLocation(destDataNode, stream); - ThriftCommonsSerDeUtils.serializeTConsensusGroupId(consensusGroupId, stream); + ThriftCommonsSerDeUtils.serializeTConsensusGroupId(regionId, stream); ThriftCommonsSerDeUtils.serializeTDataNodeLocation(coordinatorForAddPeer, stream); ThriftCommonsSerDeUtils.serializeTDataNodeLocation(coordinatorForRemovePeer, stream); } @@ -213,7 +208,7 @@ public void deserialize(ByteBuffer byteBuffer) { try { originalDataNode = ThriftCommonsSerDeUtils.deserializeTDataNodeLocation(byteBuffer); destDataNode = ThriftCommonsSerDeUtils.deserializeTDataNodeLocation(byteBuffer); - consensusGroupId = ThriftCommonsSerDeUtils.deserializeTConsensusGroupId(byteBuffer); + regionId = ThriftCommonsSerDeUtils.deserializeTConsensusGroupId(byteBuffer); coordinatorForAddPeer = ThriftCommonsSerDeUtils.deserializeTDataNodeLocation(byteBuffer); coordinatorForRemovePeer = ThriftCommonsSerDeUtils.deserializeTDataNodeLocation(byteBuffer); } catch (ThriftSerDeException e) { @@ -234,18 +229,14 @@ public boolean equals(Object that) { && thatProc.getState() == this.getState() && thatProc.originalDataNode.equals(this.originalDataNode) && thatProc.destDataNode.equals(this.destDataNode) - && thatProc.consensusGroupId.equals(this.consensusGroupId); + && thatProc.regionId.equals(this.regionId); } return false; } @Override public int hashCode() { - return Objects.hash(this.originalDataNode, this.destDataNode, this.consensusGroupId); - } - - public TConsensusGroupId getConsensusGroupId() { - return consensusGroupId; + return Objects.hash(this.originalDataNode, this.destDataNode, this.regionId); } public TDataNodeLocation getDestDataNode() { diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RemoveRegionPeerProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RemoveRegionPeerProcedure.java index 463492357d83..cfeb93a3b425 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RemoveRegionPeerProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RemoveRegionPeerProcedure.java @@ -32,7 +32,6 @@ import org.apache.iotdb.confignode.procedure.exception.ProcedureException; import org.apache.iotdb.confignode.procedure.exception.ProcedureSuspendedException; import org.apache.iotdb.confignode.procedure.exception.ProcedureYieldException; -import org.apache.iotdb.confignode.procedure.impl.StateMachineProcedure; import org.apache.iotdb.confignode.procedure.state.RemoveRegionPeerState; import org.apache.iotdb.confignode.procedure.store.ProcedureType; import org.apache.iotdb.db.utils.DateTimeUtils; @@ -52,10 +51,8 @@ import static org.apache.iotdb.confignode.procedure.state.RemoveRegionPeerState.REMOVE_REGION_PEER; import static org.apache.iotdb.rpc.TSStatusCode.SUCCESS_STATUS; -public class RemoveRegionPeerProcedure - extends StateMachineProcedure { +public class RemoveRegionPeerProcedure extends RegionMemberChangeProcedure { private static final Logger LOGGER = LoggerFactory.getLogger(RemoveRegionPeerProcedure.class); - private TConsensusGroupId consensusGroupId; private TDataNodeLocation coordinator; private TDataNodeLocation targetDataNode; @@ -67,7 +64,7 @@ public RemoveRegionPeerProcedure( TConsensusGroupId consensusGroupId, TDataNodeLocation coordinator, TDataNodeLocation targetDataNode) { - this.consensusGroupId = consensusGroupId; + super(consensusGroupId); this.coordinator = coordinator; this.targetDataNode = targetDataNode; } @@ -77,16 +74,16 @@ private void handleTransferLeader(RegionMaintainHandler handler) LOGGER.info( "[pid{}][RemoveRegion] started, region {} will be removed from DataNode {}.", getProcId(), - consensusGroupId.getId(), + regionId.getId(), targetDataNode.getDataNodeId()); - handler.forceUpdateRegionCache(consensusGroupId, targetDataNode, RegionStatus.Removing); - handler.transferRegionLeader(consensusGroupId, targetDataNode, coordinator); + handler.forceUpdateRegionCache(regionId, targetDataNode, RegionStatus.Removing); + handler.transferRegionLeader(regionId, targetDataNode, coordinator); } @Override protected Flow executeFromState(ConfigNodeProcedureEnv env, RemoveRegionPeerState state) throws ProcedureSuspendedException, ProcedureYieldException, InterruptedException { - if (consensusGroupId == null) { + if (regionId == null) { return Flow.NO_MORE_STATE; } TSStatus tsStatus; @@ -99,10 +96,10 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, RemoveRegionPeerStat setNextState(REMOVE_REGION_PEER); break; case REMOVE_REGION_PEER: - handler.forceUpdateRegionCache(consensusGroupId, targetDataNode, RegionStatus.Removing); + handler.forceUpdateRegionCache(regionId, targetDataNode, RegionStatus.Removing); tsStatus = handler.submitRemoveRegionPeerTask( - this.getProcId(), targetDataNode, consensusGroupId, coordinator); + this.getProcId(), targetDataNode, regionId, coordinator); setKillPoint(state); if (tsStatus.getCode() != SUCCESS_STATUS.getStatusCode()) { LOGGER.warn( @@ -125,10 +122,9 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, RemoveRegionPeerStat setNextState(DELETE_OLD_REGION_PEER); break; case DELETE_OLD_REGION_PEER: - handler.forceUpdateRegionCache(consensusGroupId, targetDataNode, RegionStatus.Removing); + handler.forceUpdateRegionCache(regionId, targetDataNode, RegionStatus.Removing); tsStatus = - handler.submitDeleteOldRegionPeerTask( - this.getProcId(), targetDataNode, consensusGroupId); + handler.submitDeleteOldRegionPeerTask(this.getProcId(), targetDataNode, regionId); setKillPoint(state); if (tsStatus.getCode() != SUCCESS_STATUS.getStatusCode()) { LOGGER.warn( @@ -149,13 +145,13 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, RemoveRegionPeerStat setNextState(REMOVE_REGION_LOCATION_CACHE); break; case REMOVE_REGION_LOCATION_CACHE: - handler.removeRegionLocation(consensusGroupId, targetDataNode); + handler.removeRegionLocation(regionId, targetDataNode); setKillPoint(state); LOGGER.info("RemoveRegionPeer state {} success", state); LOGGER.info( "[pid{}][RemoveRegion] success, region {} has been removed from DataNode {}. Procedure took {} (started at {})", getProcId(), - consensusGroupId.getId(), + regionId.getId(), targetDataNode.getDataNodeId(), CommonDateTimeUtils.convertMillisecondToDurationStr( System.currentTimeMillis() - getSubmittedTime()), @@ -195,7 +191,7 @@ protected RemoveRegionPeerState getInitialState() { public void serialize(DataOutputStream stream) throws IOException { stream.writeShort(ProcedureType.REMOVE_REGION_PEER_PROCEDURE.getTypeCode()); super.serialize(stream); - ThriftCommonsSerDeUtils.serializeTConsensusGroupId(consensusGroupId, stream); + ThriftCommonsSerDeUtils.serializeTConsensusGroupId(regionId, stream); ThriftCommonsSerDeUtils.serializeTDataNodeLocation(targetDataNode, stream); ThriftCommonsSerDeUtils.serializeTDataNodeLocation(coordinator, stream); } @@ -204,7 +200,7 @@ public void serialize(DataOutputStream stream) throws IOException { public void deserialize(ByteBuffer byteBuffer) { super.deserialize(byteBuffer); try { - consensusGroupId = ThriftCommonsSerDeUtils.deserializeTConsensusGroupId(byteBuffer); + regionId = ThriftCommonsSerDeUtils.deserializeTConsensusGroupId(byteBuffer); targetDataNode = ThriftCommonsSerDeUtils.deserializeTDataNodeLocation(byteBuffer); coordinator = ThriftCommonsSerDeUtils.deserializeTDataNodeLocation(byteBuffer); } catch (ThriftSerDeException e) { @@ -212,10 +208,6 @@ public void deserialize(ByteBuffer byteBuffer) { } } - public TConsensusGroupId getConsensusGroupId() { - return consensusGroupId; - } - public TDataNodeLocation getCoordinator() { return coordinator; } @@ -230,13 +222,13 @@ public boolean equals(Object obj) { return false; } RemoveRegionPeerProcedure procedure = (RemoveRegionPeerProcedure) obj; - return this.consensusGroupId.equals(procedure.consensusGroupId) + return this.regionId.equals(procedure.regionId) && this.targetDataNode.equals(procedure.targetDataNode) && this.coordinator.equals(procedure.coordinator); } @Override public int hashCode() { - return Objects.hash(consensusGroupId, targetDataNode, coordinator); + return Objects.hash(regionId, targetDataNode, coordinator); } } diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/store/ProcedureFactory.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/store/ProcedureFactory.java index 7cb7f1ebeaeb..e258e61d8e7d 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/store/ProcedureFactory.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/store/ProcedureFactory.java @@ -40,6 +40,7 @@ import org.apache.iotdb.confignode.procedure.impl.pipe.task.StopPipeProcedureV2; import org.apache.iotdb.confignode.procedure.impl.region.AddRegionPeerProcedure; import org.apache.iotdb.confignode.procedure.impl.region.CreateRegionGroupsProcedure; +import org.apache.iotdb.confignode.procedure.impl.region.ReconstructRegionProcedure; import org.apache.iotdb.confignode.procedure.impl.region.RegionMigrateProcedure; import org.apache.iotdb.confignode.procedure.impl.region.RemoveRegionPeerProcedure; import org.apache.iotdb.confignode.procedure.impl.schema.AlterLogicalViewProcedure; @@ -124,6 +125,8 @@ public Procedure create(ByteBuffer buffer) throws IOException { case CREATE_REGION_GROUPS: procedure = new CreateRegionGroupsProcedure(); break; + case RECONSTRUCT_REGION_PROCEDURE: + procedure = new ReconstructRegionProcedure(); case DELETE_TIMESERIES_PROCEDURE: procedure = new DeleteTimeSeriesProcedure(false); break; @@ -341,6 +344,8 @@ public static ProcedureType getProcedureType(Procedure procedure) { return ProcedureType.CREATE_REGION_GROUPS; } else if (procedure instanceof DeleteTimeSeriesProcedure) { return ProcedureType.DELETE_TIMESERIES_PROCEDURE; + } else if (procedure instanceof ReconstructRegionProcedure) { + return ProcedureType.RECONSTRUCT_REGION_PROCEDURE; } else if (procedure instanceof CreateTriggerProcedure) { return ProcedureType.CREATE_TRIGGER_PROCEDURE; } else if (procedure instanceof DropTriggerProcedure) { diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/store/ProcedureType.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/store/ProcedureType.java index e423452d7ad4..1f7db7e3c43e 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/store/ProcedureType.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/store/ProcedureType.java @@ -36,10 +36,11 @@ public enum ProcedureType { DELETE_DATABASE_PROCEDURE((short) 200), REGION_MIGRATE_PROCEDURE((short) 201), CREATE_REGION_GROUPS((short) 202), + ADD_REGION_PEER_PROCEDURE((short) 203), + REMOVE_REGION_PEER_PROCEDURE((short) 204), + RECONSTRUCT_REGION_PROCEDURE((short) 205), @TestOnly - CREATE_MANY_DATABASES_PROCEDURE((short) 203), - ADD_REGION_PEER_PROCEDURE((short) 204), - REMOVE_REGION_PEER_PROCEDURE((short) 205), + CREATE_MANY_DATABASES_PROCEDURE((short) 250), /** Timeseries */ DELETE_TIMESERIES_PROCEDURE((short) 300), diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ReconstructRegionTask.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ReconstructRegionTask.java index c89a0f38cd53..2b02d74f2cba 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ReconstructRegionTask.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ReconstructRegionTask.java @@ -37,6 +37,6 @@ public ReconstructRegionTask(ReconstructRegionStatement reconstructRegionStateme @Override public ListenableFuture execute(IConfigTaskExecutor configTaskExecutor) throws InterruptedException { - return null; + return configTaskExecutor.reconstructRegion(reconstructRegionStatement); } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java index f74ad159630d..01d7a2486bd8 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java @@ -4188,6 +4188,7 @@ public Statement visitReconstructRegion(IoTDBSqlParser.ReconstructRegionContext .map(ParseTree::getText) .map(Integer::parseInt) .collect(Collectors.toList()); + regionIds.remove(regionIds.size() - 1); return new ReconstructRegionStatement(dataNodeId, regionIds); } From 9c3390c4cc664d3349debff49013c4e08a407bb6 Mon Sep 17 00:00:00 2001 From: liyuheng Date: Tue, 19 Nov 2024 17:20:34 +0800 Subject: [PATCH 04/13] fxxk it --- .../apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 | 11 +++- .../org/apache/iotdb/db/qp/sql/SqlLexer.g4 | 4 ++ .../confignode/manager/ConfigManager.java | 18 ++++++ .../iotdb/confignode/manager/IManager.java | 6 ++ .../confignode/manager/ProcedureManager.java | 10 ++++ .../thrift/ConfigNodeRPCServiceProcessor.java | 12 ++++ .../config/TreeConfigTaskVisitor.java | 24 ++++++-- .../executor/ClusterConfigTaskExecutor.java | 56 +++++++++++++++++-- .../config/executor/IConfigTaskExecutor.java | 10 +++- .../{ => region}/MigrateRegionTask.java | 4 +- .../{ => region}/ReconstructRegionTask.java | 4 +- .../queryengine/plan/parser/ASTVisitor.java | 18 +++++- .../plan/statement/StatementVisitor.java | 14 ++++- .../{ => region}/MigrateRegionStatement.java | 2 +- .../ReconstructRegionStatement.java | 2 +- .../src/main/thrift/confignode.thrift | 18 +++++- 16 files changed, 190 insertions(+), 23 deletions(-) rename iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/{ => region}/MigrateRegionTask.java (94%) rename iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/{ => region}/ReconstructRegionTask.java (93%) rename iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/{ => region}/MigrateRegionStatement.java (96%) rename iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/{ => region}/ReconstructRegionStatement.java (96%) diff --git a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 index ea8e09561d09..4018163ef7aa 100644 --- a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 +++ b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 @@ -64,7 +64,8 @@ ddlStatement | createContinuousQuery | dropContinuousQuery | showContinuousQueries // Cluster | showVariables | showCluster | showRegions | showDataNodes | showConfigNodes | showClusterId - | getRegionId | getTimeSlotList | countTimeSlotList | getSeriesSlotList | migrateRegion | reconstructRegion + | getRegionId | getTimeSlotList | countTimeSlotList | getSeriesSlotList + | migrateRegion | reconstructRegion | extendRegion | removeRegion | verifyConnection // AINode | showAINodes | createModel | dropModel | showModels | callInference @@ -541,6 +542,14 @@ reconstructRegion : RECONSTRUCT REGION regionId=INTEGER_LITERAL (COMMA regionId=INTEGER_LITERAL)* ON targetDataNodeId=INTEGER_LITERAL ; +extendRegion + : EXTEND REGION regionId=INTEGER_LITERAL TO targetDataNodeId=INTEGER_LITERAL + ; + +removeRegion + : REMOVE REGION regionId=INTEGER_LITERAL FROM targetDataNodeId=INTEGER_LITERAL + ; + verifyConnection : VERIFY CONNECTION (DETAILS)? ; diff --git a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4 b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4 index 26cfe650492d..50f957c7fcc2 100644 --- a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4 +++ b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/SqlLexer.g4 @@ -302,6 +302,10 @@ EXPLAIN : E X P L A I N ; +EXTEND + : E X T E N D + ; + EXTRACTOR : E X T R A C T O R ; diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java index c7667ee1f1a9..df0fff2be5b2 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java @@ -169,6 +169,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TDropPipeReq; import org.apache.iotdb.confignode.rpc.thrift.TDropTopicReq; import org.apache.iotdb.confignode.rpc.thrift.TDropTriggerReq; +import org.apache.iotdb.confignode.rpc.thrift.TExtendRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TFetchTableResp; import org.apache.iotdb.confignode.rpc.thrift.TGetAllPipeInfoResp; import org.apache.iotdb.confignode.rpc.thrift.TGetAllSubscriptionInfoResp; @@ -200,6 +201,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TPipeConfigTransferResp; import org.apache.iotdb.confignode.rpc.thrift.TReconstructRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TRegionRouteMapResp; +import org.apache.iotdb.confignode.rpc.thrift.TRemoveRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TSchemaNodeManagementResp; import org.apache.iotdb.confignode.rpc.thrift.TSchemaPartitionTableResp; import org.apache.iotdb.confignode.rpc.thrift.TSetDataNodeStatusReq; @@ -2366,6 +2368,22 @@ public TSStatus reconstructRegion(TReconstructRegionReq req) { : status; } + @Override + public TSStatus extendRegion(TExtendRegionReq req) { + TSStatus status = confirmLeader(); + return status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode() + ? procedureManager.reconstructRegion(req) + : status; + } + + @Override + public TSStatus removeRegion(TRemoveRegionReq req) { + TSStatus status = confirmLeader(); + return status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode() + ? procedureManager.reconstructRegion(req) + : status; + } + @Override public TSStatus createCQ(TCreateCQReq req) { TSStatus status = confirmLeader(); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java index 27f52254622f..557b8ead755f 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/IManager.java @@ -94,6 +94,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TDropPipeReq; import org.apache.iotdb.confignode.rpc.thrift.TDropTopicReq; import org.apache.iotdb.confignode.rpc.thrift.TDropTriggerReq; +import org.apache.iotdb.confignode.rpc.thrift.TExtendRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TFetchTableResp; import org.apache.iotdb.confignode.rpc.thrift.TGetAllPipeInfoResp; import org.apache.iotdb.confignode.rpc.thrift.TGetAllSubscriptionInfoResp; @@ -124,6 +125,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TPipeConfigTransferResp; import org.apache.iotdb.confignode.rpc.thrift.TReconstructRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TRegionRouteMapResp; +import org.apache.iotdb.confignode.rpc.thrift.TRemoveRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TSchemaNodeManagementResp; import org.apache.iotdb.confignode.rpc.thrift.TSchemaPartitionTableResp; import org.apache.iotdb.confignode.rpc.thrift.TSetDataNodeStatusReq; @@ -813,6 +815,10 @@ TDataPartitionTableResp getOrCreateDataPartition( TSStatus reconstructRegion(TReconstructRegionReq req); + TSStatus extendRegion(TExtendRegionReq req); + + TSStatus removeRegion(TRemoveRegionReq req); + TSStatus createCQ(TCreateCQReq req); TSStatus dropCQ(TDropCQReq req); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java index 4b13fa9dc7b7..7a83b3eb54bb 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java @@ -128,8 +128,10 @@ import org.apache.iotdb.confignode.rpc.thrift.TDeleteTableDeviceReq; import org.apache.iotdb.confignode.rpc.thrift.TDeleteTableDeviceResp; import org.apache.iotdb.confignode.rpc.thrift.TDropPipePluginReq; +import org.apache.iotdb.confignode.rpc.thrift.TExtendRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TMigrateRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TReconstructRegionReq; +import org.apache.iotdb.confignode.rpc.thrift.TRemoveRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TSubscribeReq; import org.apache.iotdb.confignode.rpc.thrift.TUnsubscribeReq; import org.apache.iotdb.consensus.ConsensusFactory; @@ -967,6 +969,14 @@ public TSStatus reconstructRegion(TReconstructRegionReq req) { return RpcUtils.SUCCESS_STATUS; } + public TSStatus extendRegion(TExtendRegionReq req) { + + } + + public TSStatus removeRegion(TRemoveRegionReq req) { + + } + private TSStatus checkReconstructRegion( TReconstructRegionReq req, TConsensusGroupId regionId, diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java index a0470920121a..46886142583a 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java @@ -136,6 +136,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TDropPipeReq; import org.apache.iotdb.confignode.rpc.thrift.TDropTopicReq; import org.apache.iotdb.confignode.rpc.thrift.TDropTriggerReq; +import org.apache.iotdb.confignode.rpc.thrift.TExtendRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TFetchTableResp; import org.apache.iotdb.confignode.rpc.thrift.TGetAllPipeInfoResp; import org.apache.iotdb.confignode.rpc.thrift.TGetAllSubscriptionInfoResp; @@ -168,6 +169,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TPipeConfigTransferResp; import org.apache.iotdb.confignode.rpc.thrift.TReconstructRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TRegionRouteMapResp; +import org.apache.iotdb.confignode.rpc.thrift.TRemoveRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TSchemaNodeManagementReq; import org.apache.iotdb.confignode.rpc.thrift.TSchemaNodeManagementResp; import org.apache.iotdb.confignode.rpc.thrift.TSchemaPartitionReq; @@ -1239,6 +1241,16 @@ public TSStatus reconstructRegion(TReconstructRegionReq req) { return configManager.reconstructRegion(req); } + @Override + public TSStatus extendRegion(TExtendRegionReq req) throws TException { + return null; + } + + @Override + public TSStatus removeRegion(TRemoveRegionReq req) throws TException { + return null; + } + @Override public TSStatus createCQ(TCreateCQReq req) { return configManager.createCQ(req); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TreeConfigTaskVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TreeConfigTaskVisitor.java index 855cdec714e6..183439153a77 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TreeConfigTaskVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TreeConfigTaskVisitor.java @@ -37,8 +37,6 @@ import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.GetRegionIdTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.GetSeriesSlotListTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.GetTimeSlotListTask; -import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.MigrateRegionTask; -import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.ReconstructRegionTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.SetTTLTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.ShowAINodesTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.ShowClusterDetailsTask; @@ -58,6 +56,10 @@ import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.model.CreateModelTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.model.DropModelTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.model.ShowModelsTask; +import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.region.ExtendRegionTask; +import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.region.MigrateRegionTask; +import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.region.ReconstructRegionTask; +import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.region.RemoveRegionTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.template.AlterSchemaTemplateTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.template.CreateSchemaTemplateTask; import org.apache.iotdb.db.queryengine.plan.execution.config.metadata.template.DeactivateSchemaTemplateTask; @@ -112,8 +114,6 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetRegionIdStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetSeriesSlotListStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetTimeSlotListStatement; -import org.apache.iotdb.db.queryengine.plan.statement.metadata.MigrateRegionStatement; -import org.apache.iotdb.db.queryengine.plan.statement.metadata.ReconstructRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.SetTTLStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowClusterIdStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowClusterStatement; @@ -140,6 +140,10 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.ShowPipesStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.StartPipeStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.StopPipeStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.ExtendRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.MigrateRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.ReconstructRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.RemoveRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.CreateTopicStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.DropTopicStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.ShowSubscriptionsStatement; @@ -572,6 +576,18 @@ public IConfigTask visitReconstructRegion( return new ReconstructRegionTask(reconstructRegionStatement); } + @Override + public IConfigTask visitExtendRegion( + ExtendRegionStatement extendRegionStatement, MPPQueryContext context) { + return new ExtendRegionTask(extendRegionStatement); + } + + @Override + public IConfigTask visitRemoveRegion( + RemoveRegionStatement removeRegionStatement, MPPQueryContext context) { + return new RemoveRegionTask(removeRegionStatement); + } + @Override public IConfigTask visitCreateContinuousQuery( CreateContinuousQueryStatement createContinuousQueryStatement, MPPQueryContext context) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java index ae3da4d7a3b8..2c2b1107e815 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java @@ -92,6 +92,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TDropPipeReq; import org.apache.iotdb.confignode.rpc.thrift.TDropTopicReq; import org.apache.iotdb.confignode.rpc.thrift.TDropTriggerReq; +import org.apache.iotdb.confignode.rpc.thrift.TExtendRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TFetchTableResp; import org.apache.iotdb.confignode.rpc.thrift.TGetAllPipeInfoResp; import org.apache.iotdb.confignode.rpc.thrift.TGetDatabaseReq; @@ -109,6 +110,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TPipeConfigTransferResp; import org.apache.iotdb.confignode.rpc.thrift.TReconstructRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TRegionInfo; +import org.apache.iotdb.confignode.rpc.thrift.TRemoveRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TShowAINodesResp; import org.apache.iotdb.confignode.rpc.thrift.TShowCQResp; import org.apache.iotdb.confignode.rpc.thrift.TShowClusterResp; @@ -215,8 +217,9 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetRegionIdStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetSeriesSlotListStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetTimeSlotListStatement; -import org.apache.iotdb.db.queryengine.plan.statement.metadata.MigrateRegionStatement; -import org.apache.iotdb.db.queryengine.plan.statement.metadata.ReconstructRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.ExtendRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.MigrateRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.ReconstructRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.SetTTLStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowClusterStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowDatabaseStatement; @@ -231,6 +234,7 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.ShowPipesStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.StartPipeStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.StopPipeStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.RemoveRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.CreateTopicStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.DropTopicStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.ShowSubscriptionsStatement; @@ -2778,8 +2782,8 @@ public SettableFuture reconstructRegion( CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) { final TReconstructRegionReq req = new TReconstructRegionReq( - reconstructRegionStatement.getDataNodeId(), - reconstructRegionStatement.getRegionIds()); + reconstructRegionStatement.getRegionIds(), + reconstructRegionStatement.getDataNodeId()); final TSStatus status = configNodeClient.reconstructRegion(req); if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { future.setException(new IoTDBException(status.message, status.code)); @@ -2793,6 +2797,50 @@ public SettableFuture reconstructRegion( return future; } + @Override + public SettableFuture extendRegion(ExtendRegionStatement extendRegionStatement) { + final SettableFuture future = SettableFuture.create(); + try (ConfigNodeClient configNodeClient = + CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) { + final TExtendRegionReq req = + new TExtendRegionReq( + extendRegionStatement.getRegionId(), + extendRegionStatement.getDataNodeId()); + final TSStatus status = configNodeClient.extendRegion(req); + if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { + future.setException(new IoTDBException(status.message, status.code)); + return future; + } else { + future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS)); + } + } catch (Exception e) { + future.setException(e); + } + return future; + } + + @Override + public SettableFuture removeRegion(RemoveRegionStatement removeRegionStatement) { + final SettableFuture future = SettableFuture.create(); + try (ConfigNodeClient configNodeClient = + CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) { + final TRemoveRegionReq req = + new TRemoveRegionReq( + removeRegionStatement.getRegionId(), + removeRegionStatement.getDataNodeId()); + final TSStatus status = configNodeClient.removeRegion(req); + if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { + future.setException(new IoTDBException(status.message, status.code)); + return future; + } else { + future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS)); + } + } catch (Exception e) { + future.setException(e); + } + return future; + } + @Override public SettableFuture createContinuousQuery( CreateContinuousQueryStatement createContinuousQueryStatement, MPPQueryContext context) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/IConfigTaskExecutor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/IConfigTaskExecutor.java index 285cf619ebef..3b70a90f00c7 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/IConfigTaskExecutor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/IConfigTaskExecutor.java @@ -51,8 +51,6 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetRegionIdStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetSeriesSlotListStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetTimeSlotListStatement; -import org.apache.iotdb.db.queryengine.plan.statement.metadata.MigrateRegionStatement; -import org.apache.iotdb.db.queryengine.plan.statement.metadata.ReconstructRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.SetTTLStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowClusterStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowDatabaseStatement; @@ -67,6 +65,10 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.ShowPipesStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.StartPipeStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.StopPipeStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.ExtendRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.MigrateRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.ReconstructRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.RemoveRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.CreateTopicStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.DropTopicStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.ShowSubscriptionsStatement; @@ -246,6 +248,10 @@ SettableFuture countTimeSlotList( SettableFuture reconstructRegion( ReconstructRegionStatement reconstructRegionStatement); + SettableFuture extendRegion(ExtendRegionStatement extendRegionStatement); + + SettableFuture removeRegion(RemoveRegionStatement removeRegionStatement); + SettableFuture createContinuousQuery( CreateContinuousQueryStatement createContinuousQueryStatement, MPPQueryContext context); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/MigrateRegionTask.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/region/MigrateRegionTask.java similarity index 94% rename from iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/MigrateRegionTask.java rename to iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/region/MigrateRegionTask.java index e85454613bef..fd22585aa8cf 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/MigrateRegionTask.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/region/MigrateRegionTask.java @@ -17,12 +17,12 @@ * under the License. */ -package org.apache.iotdb.db.queryengine.plan.execution.config.metadata; +package org.apache.iotdb.db.queryengine.plan.execution.config.metadata.region; import org.apache.iotdb.db.queryengine.plan.execution.config.ConfigTaskResult; import org.apache.iotdb.db.queryengine.plan.execution.config.IConfigTask; import org.apache.iotdb.db.queryengine.plan.execution.config.executor.IConfigTaskExecutor; -import org.apache.iotdb.db.queryengine.plan.statement.metadata.MigrateRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.MigrateRegionStatement; import com.google.common.util.concurrent.ListenableFuture; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ReconstructRegionTask.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/region/ReconstructRegionTask.java similarity index 93% rename from iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ReconstructRegionTask.java rename to iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/region/ReconstructRegionTask.java index 2b02d74f2cba..f5276ed64e7c 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/ReconstructRegionTask.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/region/ReconstructRegionTask.java @@ -17,12 +17,12 @@ * under the License. */ -package org.apache.iotdb.db.queryengine.plan.execution.config.metadata; +package org.apache.iotdb.db.queryengine.plan.execution.config.metadata.region; import org.apache.iotdb.db.queryengine.plan.execution.config.ConfigTaskResult; import org.apache.iotdb.db.queryengine.plan.execution.config.IConfigTask; import org.apache.iotdb.db.queryengine.plan.execution.config.executor.IConfigTaskExecutor; -import org.apache.iotdb.db.queryengine.plan.statement.metadata.ReconstructRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.ReconstructRegionStatement; import com.google.common.util.concurrent.ListenableFuture; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java index 01d7a2486bd8..f51773ab5b63 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java @@ -148,8 +148,6 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetRegionIdStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetSeriesSlotListStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetTimeSlotListStatement; -import org.apache.iotdb.db.queryengine.plan.statement.metadata.MigrateRegionStatement; -import org.apache.iotdb.db.queryengine.plan.statement.metadata.ReconstructRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.SetTTLStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowChildNodesStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowChildPathsStatement; @@ -181,6 +179,10 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.ShowPipesStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.StartPipeStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.StopPipeStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.ExtendRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.MigrateRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.ReconstructRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.RemoveRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.CreateTopicStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.DropTopicStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.ShowSubscriptionsStatement; @@ -4192,6 +4194,18 @@ public Statement visitReconstructRegion(IoTDBSqlParser.ReconstructRegionContext return new ReconstructRegionStatement(dataNodeId, regionIds); } + @Override + public Statement visitExtendRegion(IoTDBSqlParser.ExtendRegionContext ctx) { + return new ExtendRegionStatement( + Integer.parseInt(ctx.regionId.getText()), Integer.parseInt(ctx.targetDataNodeId.getText())); + } + + @Override + public Statement visitRemoveRegion(IoTDBSqlParser.RemoveRegionContext ctx) { + return new RemoveRegionStatement( + Integer.parseInt(ctx.regionId.getText()), Integer.parseInt(ctx.targetDataNodeId.getText())); + } + @Override public Statement visitVerifyConnection(IoTDBSqlParser.VerifyConnectionContext ctx) { return new TestConnectionStatement(ctx.DETAILS() != null); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/StatementVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/StatementVisitor.java index eec93cb7a7e4..7f4181be8b35 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/StatementVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/StatementVisitor.java @@ -55,8 +55,6 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetRegionIdStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetSeriesSlotListStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetTimeSlotListStatement; -import org.apache.iotdb.db.queryengine.plan.statement.metadata.MigrateRegionStatement; -import org.apache.iotdb.db.queryengine.plan.statement.metadata.ReconstructRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.SetTTLStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowChildNodesStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowChildPathsStatement; @@ -88,6 +86,10 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.ShowPipesStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.StartPipeStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.StopPipeStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.ExtendRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.MigrateRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.ReconstructRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.RemoveRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.CreateTopicStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.DropTopicStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.ShowSubscriptionsStatement; @@ -583,6 +585,14 @@ public R visitReconstructRegion( return visitStatement(reconstructRegionStatement, context); } + public R visitExtendRegion(ExtendRegionStatement extendRegionStatement, C context) { + return visitStatement(extendRegionStatement, context); + } + + public R visitRemoveRegion(RemoveRegionStatement removeRegionStatement, C context) { + return visitStatement(removeRegionStatement, context); + } + public R visitDeactivateTemplate( DeactivateTemplateStatement deactivateTemplateStatement, C context) { return visitStatement(deactivateTemplateStatement, context); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/MigrateRegionStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/region/MigrateRegionStatement.java similarity index 96% rename from iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/MigrateRegionStatement.java rename to iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/region/MigrateRegionStatement.java index 6127dbc2bfb2..616357f53795 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/MigrateRegionStatement.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/region/MigrateRegionStatement.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.iotdb.db.queryengine.plan.statement.metadata; +package org.apache.iotdb.db.queryengine.plan.statement.metadata.region; import org.apache.iotdb.commons.path.PartialPath; import org.apache.iotdb.db.queryengine.plan.analyze.QueryType; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ReconstructRegionStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/region/ReconstructRegionStatement.java similarity index 96% rename from iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ReconstructRegionStatement.java rename to iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/region/ReconstructRegionStatement.java index f231f7359733..cd22e61ad7f7 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/ReconstructRegionStatement.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/region/ReconstructRegionStatement.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.iotdb.db.queryengine.plan.statement.metadata; +package org.apache.iotdb.db.queryengine.plan.statement.metadata.region; import org.apache.iotdb.commons.path.PartialPath; import org.apache.iotdb.db.queryengine.plan.analyze.QueryType; diff --git a/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift b/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift index 2a7cfb163740..0a9d8860d4c8 100644 --- a/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift +++ b/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift @@ -313,8 +313,18 @@ struct TMigrateRegionReq { } struct TReconstructRegionReq { - 1: required i32 dataNodeId - 2: required list regionIds + 1: required list regionIds + 2: required i32 dataNodeId +} + +struct TExtendRegionReq { + 1: required i32 regionId + 2: required i32 dataNodeId +} + +struct TRemoveRegionReq { + 1: required i32 regionId + 2: required i32 dataNodeId } // Authorize @@ -1543,6 +1553,10 @@ service IConfigNodeRPCService { common.TSStatus reconstructRegion(TReconstructRegionReq req) + common.TSStatus extendRegion(TExtendRegionReq req) + + common.TSStatus removeRegion(TRemoveRegionReq req) + /** Kill query */ common.TSStatus killQuery(string queryId, i32 dataNodeId) From 718a5030b9fec964835e736d81f8fcecb53f414c Mon Sep 17 00:00:00 2001 From: liyuheng Date: Tue, 19 Nov 2024 17:27:11 +0800 Subject: [PATCH 05/13] add files --- .../metadata/region/ExtendRegionTask.java | 42 ++++++++++++ .../metadata/region/RemoveRegionTask.java | 42 ++++++++++++ .../region/ExtendRegionStatement.java | 64 +++++++++++++++++++ .../region/RemoveRegionStatement.java | 64 +++++++++++++++++++ 4 files changed, 212 insertions(+) create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/region/ExtendRegionTask.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/region/RemoveRegionTask.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/region/ExtendRegionStatement.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/region/RemoveRegionStatement.java diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/region/ExtendRegionTask.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/region/ExtendRegionTask.java new file mode 100644 index 000000000000..00dafd9d1549 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/region/ExtendRegionTask.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.iotdb.db.queryengine.plan.execution.config.metadata.region; + +import org.apache.iotdb.db.queryengine.plan.execution.config.ConfigTaskResult; +import org.apache.iotdb.db.queryengine.plan.execution.config.IConfigTask; +import org.apache.iotdb.db.queryengine.plan.execution.config.executor.IConfigTaskExecutor; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.ExtendRegionStatement; + +import com.google.common.util.concurrent.ListenableFuture; + +public class ExtendRegionTask implements IConfigTask { + + protected final ExtendRegionStatement statement; + + public ExtendRegionTask(ExtendRegionStatement statement) { + this.statement = statement; + } + + @Override + public ListenableFuture execute(IConfigTaskExecutor configTaskExecutor) + throws InterruptedException { + return configTaskExecutor.extendRegion(statement); + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/region/RemoveRegionTask.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/region/RemoveRegionTask.java new file mode 100644 index 000000000000..26ecea097f74 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/region/RemoveRegionTask.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.iotdb.db.queryengine.plan.execution.config.metadata.region; + +import org.apache.iotdb.db.queryengine.plan.execution.config.ConfigTaskResult; +import org.apache.iotdb.db.queryengine.plan.execution.config.IConfigTask; +import org.apache.iotdb.db.queryengine.plan.execution.config.executor.IConfigTaskExecutor; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.RemoveRegionStatement; + +import com.google.common.util.concurrent.ListenableFuture; + +public class RemoveRegionTask implements IConfigTask { + + protected final RemoveRegionStatement statement; + + public RemoveRegionTask(RemoveRegionStatement statement) { + this.statement = statement; + } + + @Override + public ListenableFuture execute(IConfigTaskExecutor configTaskExecutor) + throws InterruptedException { + return configTaskExecutor.removeRegion(statement); + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/region/ExtendRegionStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/region/ExtendRegionStatement.java new file mode 100644 index 000000000000..581ba6bf10fe --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/region/ExtendRegionStatement.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.iotdb.db.queryengine.plan.statement.metadata.region; + +import org.apache.iotdb.commons.path.PartialPath; +import org.apache.iotdb.db.queryengine.plan.analyze.QueryType; +import org.apache.iotdb.db.queryengine.plan.statement.IConfigStatement; +import org.apache.iotdb.db.queryengine.plan.statement.Statement; +import org.apache.iotdb.db.queryengine.plan.statement.StatementVisitor; + +import java.util.Collections; +import java.util.List; + +public class ExtendRegionStatement extends Statement implements IConfigStatement { + + private final int regionId; + private final int dataNodeId; + + public ExtendRegionStatement(int regionId, int dataNodeId) { + super(); + this.regionId = regionId; + this.dataNodeId = dataNodeId; + } + + public int getRegionId() { + return regionId; + } + + public int getDataNodeId() { + return dataNodeId; + } + + @Override + public R accept(StatementVisitor visitor, C context) { + return visitor.visitExtendRegion(this, context); + } + + @Override + public QueryType getQueryType() { + return QueryType.WRITE; + } + + @Override + public List getPaths() { + return Collections.emptyList(); + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/region/RemoveRegionStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/region/RemoveRegionStatement.java new file mode 100644 index 000000000000..fae5bebad70e --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/metadata/region/RemoveRegionStatement.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.iotdb.db.queryengine.plan.statement.metadata.region; + +import org.apache.iotdb.commons.path.PartialPath; +import org.apache.iotdb.db.queryengine.plan.analyze.QueryType; +import org.apache.iotdb.db.queryengine.plan.statement.IConfigStatement; +import org.apache.iotdb.db.queryengine.plan.statement.Statement; +import org.apache.iotdb.db.queryengine.plan.statement.StatementVisitor; + +import java.util.Collections; +import java.util.List; + +public class RemoveRegionStatement extends Statement implements IConfigStatement { + + private final int regionId; + private final int dataNodeId; + + public RemoveRegionStatement(int regionId, int dataNodeId) { + super(); + this.regionId = regionId; + this.dataNodeId = dataNodeId; + } + + public int getRegionId() { + return regionId; + } + + public int getDataNodeId() { + return dataNodeId; + } + + @Override + public R accept(StatementVisitor visitor, C context) { + return visitor.visitRemoveRegion(this, context); + } + + @Override + public QueryType getQueryType() { + return QueryType.WRITE; + } + + @Override + public List getPaths() { + return Collections.emptyList(); + } +} From 3cac681917943d3bf9ef3c30d189362d8da2bae3 Mon Sep 17 00:00:00 2001 From: liyuheng Date: Fri, 27 Dec 2024 17:41:57 +0800 Subject: [PATCH 06/13] merge master & save, need to do submit procedure --- .../confignode/manager/ConfigManager.java | 8 +++--- .../confignode/manager/ProcedureManager.java | 9 ++++--- .../impl/region/AddRegionPeerProcedure.java | 6 ++--- .../impl/region/RegionMigrateProcedure.java | 6 ++--- .../region/RemoveRegionPeerProcedure.java | 12 ++++----- .../db/protocol/client/ConfigNodeClient.java | 14 ++++++++++ .../executor/ClusterConfigTaskExecutor.java | 26 +++++++++---------- 7 files changed, 48 insertions(+), 33 deletions(-) diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java index bab68b0d6f19..0baa745c0345 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java @@ -2394,16 +2394,16 @@ public TSStatus reconstructRegion(TReconstructRegionReq req) { public TSStatus extendRegion(TExtendRegionReq req) { TSStatus status = confirmLeader(); return status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode() - ? procedureManager.reconstructRegion(req) - : status; + ? procedureManager.extendRegion(req) + : status; } @Override public TSStatus removeRegion(TRemoveRegionReq req) { TSStatus status = confirmLeader(); return status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode() - ? procedureManager.reconstructRegion(req) - : status; + ? procedureManager.removeRegion(req) + : status; } @Override diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java index 65509703ca90..a90f8b751be8 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java @@ -910,7 +910,7 @@ public TSStatus reconstructRegion(TReconstructRegionReq req) { RegionMaintainHandler handler = env.getRegionMaintainHandler(); final TDataNodeLocation targetDataNode = configManager.getNodeManager().getRegisteredDataNode(req.getDataNodeId()).getLocation(); - try (AutoCloseableLock autoCloseableLock = + try (AutoCloseableLock ignoredLock = AutoCloseableLock.acquire(env.getSubmitRegionMigrateLock())) { List procedures = new ArrayList<>(); for (int x : req.getRegionIds()) { @@ -947,12 +947,13 @@ public TSStatus reconstructRegion(TReconstructRegionReq req) { } public TSStatus extendRegion(TExtendRegionReq req) { + try (AutoCloseableLock ignoredLock = + AutoCloseableLock.acquire(env.getSubmitRegionMigrateLock())) { + } } - public TSStatus removeRegion(TRemoveRegionReq req) { - - } + public TSStatus removeRegion(TRemoveRegionReq req) {} private TSStatus checkReconstructRegion( TReconstructRegionReq req, diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/AddRegionPeerProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/AddRegionPeerProcedure.java index 57397f103383..0d0c1044b155 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/AddRegionPeerProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/AddRegionPeerProcedure.java @@ -86,7 +86,7 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, AddRegionPeerState s LOGGER.info( "[pid{}][AddRegion] started, {} will be added to DataNode {}.", getProcId(), - regionId, + regionId, handler.simplifiedLocation(destDataNode)); handler.addRegionLocation(regionId, destDataNode); handler.forceUpdateRegionCache(regionId, destDataNode, RegionStatus.Adding); @@ -136,8 +136,8 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, AddRegionPeerState s LOGGER.info( "[pid{}][AddRegion] success, {} has been added to DataNode {}. Procedure took {} (start at {}).", getProcId(), - regionId, - handler.simplifiedLocation(destDataNode), + regionId, + handler.simplifiedLocation(destDataNode), CommonDateTimeUtils.convertMillisecondToDurationStr( System.currentTimeMillis() - getSubmittedTime()), DateTimeUtils.convertLongToDate(getSubmittedTime(), "ms")); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMigrateProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMigrateProcedure.java index c6a6e3d0b2db..fb4e45749fdc 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMigrateProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMigrateProcedure.java @@ -82,8 +82,8 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, RegionTransitionStat "[pid{}][MigrateRegion] started, {} will be migrated from DataNode {} to {}.", getProcId(), regionId, - handler.simplifiedLocation(originalDataNode), - handler.simplifiedLocation(destDataNode)); + handler.simplifiedLocation(originalDataNode), + handler.simplifiedLocation(destDataNode)); setNextState(RegionTransitionState.ADD_REGION_PEER); break; case ADD_REGION_PEER: @@ -111,7 +111,7 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, RegionTransitionStat String cleanHint = ""; if (env.getConfigManager() .getPartitionManager() - .isDataNodeContainsRegion(originalDataNode.getDataNodeId(), consensusGroupId)) { + .isDataNodeContainsRegion(originalDataNode.getDataNodeId(), regionId)) { cleanHint = "but you may need to restart the related DataNode to make sure everything is cleaned up. "; } diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RemoveRegionPeerProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RemoveRegionPeerProcedure.java index 6095579c03f6..d90fa3fcd801 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RemoveRegionPeerProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RemoveRegionPeerProcedure.java @@ -106,8 +106,8 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, RemoveRegionPeerStat "[pid{}][RemoveRegion] {} task submitted failed, ConfigNode believe current peer list of {} is {}. Procedure will continue. You should manually clear peer list.", getProcId(), state, - consensusGroupId, - handler.getRegionReplicaSetString(consensusGroupId)); + regionId, + handler.getRegionReplicaSetString(regionId)); setNextState(DELETE_OLD_REGION_PEER); return Flow.HAS_MORE_STATE; } @@ -118,8 +118,8 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, RemoveRegionPeerStat "[pid{}][RemoveRegion] {} executed failed, ConfigNode believe current peer list of {} is {}. Procedure will continue. You should manually clear peer list.", getProcId(), state, - consensusGroupId, - handler.getRegionReplicaSetString(consensusGroupId)); + regionId, + handler.getRegionReplicaSetString(regionId)); setNextState(DELETE_OLD_REGION_PEER); return Flow.HAS_MORE_STATE; } @@ -134,7 +134,7 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, RemoveRegionPeerStat LOGGER.warn( "[pid{}][RemoveRegion] DELETE_OLD_REGION_PEER task submitted failed, procedure will continue. You should manually delete region file. {}", getProcId(), - consensusGroupId); + regionId); setNextState(REMOVE_REGION_LOCATION_CACHE); return Flow.HAS_MORE_STATE; } @@ -144,7 +144,7 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, RemoveRegionPeerStat LOGGER.warn( "[pid{}][RemoveRegion] DELETE_OLD_REGION_PEER executed failed, procedure will continue. You should manually delete region file. {}", getProcId(), - consensusGroupId); + regionId); setNextState(REMOVE_REGION_LOCATION_CACHE); return Flow.HAS_MORE_STATE; } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java index 45f6fcb959b7..26403e068dc1 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/client/ConfigNodeClient.java @@ -99,6 +99,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TDropPipeReq; import org.apache.iotdb.confignode.rpc.thrift.TDropTopicReq; import org.apache.iotdb.confignode.rpc.thrift.TDropTriggerReq; +import org.apache.iotdb.confignode.rpc.thrift.TExtendRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TFetchTableResp; import org.apache.iotdb.confignode.rpc.thrift.TGetAllPipeInfoResp; import org.apache.iotdb.confignode.rpc.thrift.TGetAllSubscriptionInfoResp; @@ -132,6 +133,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TPipeConfigTransferResp; import org.apache.iotdb.confignode.rpc.thrift.TReconstructRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TRegionRouteMapResp; +import org.apache.iotdb.confignode.rpc.thrift.TRemoveRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TSchemaNodeManagementReq; import org.apache.iotdb.confignode.rpc.thrift.TSchemaNodeManagementResp; import org.apache.iotdb.confignode.rpc.thrift.TSchemaPartitionReq; @@ -1198,6 +1200,18 @@ public TSStatus reconstructRegion(TReconstructRegionReq req) throws TException { () -> client.reconstructRegion(req), status -> !updateConfigNodeLeader(status)); } + @Override + public TSStatus extendRegion(TExtendRegionReq req) throws TException { + return executeRemoteCallWithRetry( + () -> client.extendRegion(req), status -> !updateConfigNodeLeader(status)); + } + + @Override + public TSStatus removeRegion(TRemoveRegionReq req) throws TException { + return executeRemoteCallWithRetry( + () -> client.removeRegion(req), status -> !updateConfigNodeLeader(status)); + } + @Override public TSStatus createCQ(TCreateCQReq req) throws TException { return executeRemoteCallWithRetry( diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java index d80cfc21a902..50ff49dd54f3 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java @@ -218,9 +218,6 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetRegionIdStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetSeriesSlotListStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.GetTimeSlotListStatement; -import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.ExtendRegionStatement; -import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.MigrateRegionStatement; -import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.ReconstructRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.SetTTLStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowClusterStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowDatabaseStatement; @@ -235,6 +232,9 @@ import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.ShowPipesStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.StartPipeStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.pipe.StopPipeStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.ExtendRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.MigrateRegionStatement; +import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.ReconstructRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.region.RemoveRegionStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.CreateTopicStatement; import org.apache.iotdb.db.queryengine.plan.statement.metadata.subscription.DropTopicStatement; @@ -2789,14 +2789,14 @@ public SettableFuture reconstructRegion( } @Override - public SettableFuture extendRegion(ExtendRegionStatement extendRegionStatement) { + public SettableFuture extendRegion( + ExtendRegionStatement extendRegionStatement) { final SettableFuture future = SettableFuture.create(); try (ConfigNodeClient configNodeClient = - CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) { + CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) { final TExtendRegionReq req = - new TExtendRegionReq( - extendRegionStatement.getRegionId(), - extendRegionStatement.getDataNodeId()); + new TExtendRegionReq( + extendRegionStatement.getRegionId(), extendRegionStatement.getDataNodeId()); final TSStatus status = configNodeClient.extendRegion(req); if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { future.setException(new IoTDBException(status.message, status.code)); @@ -2811,14 +2811,14 @@ public SettableFuture extendRegion(ExtendRegionStatement exten } @Override - public SettableFuture removeRegion(RemoveRegionStatement removeRegionStatement) { + public SettableFuture removeRegion( + RemoveRegionStatement removeRegionStatement) { final SettableFuture future = SettableFuture.create(); try (ConfigNodeClient configNodeClient = - CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) { + CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) { final TRemoveRegionReq req = - new TRemoveRegionReq( - removeRegionStatement.getRegionId(), - removeRegionStatement.getDataNodeId()); + new TRemoveRegionReq( + removeRegionStatement.getRegionId(), removeRegionStatement.getDataNodeId()); final TSStatus status = configNodeClient.removeRegion(req); if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { future.setException(new IoTDBException(status.message, status.code)); From 0da1e383d902000679f2c6a0227734470c7b1a78 Mon Sep 17 00:00:00 2001 From: liyuheng Date: Mon, 6 Jan 2025 12:07:13 +0800 Subject: [PATCH 07/13] basically done --- .../org/apache/iotdb/rpc/TSStatusCode.java | 3 + .../confignode/manager/ProcedureManager.java | 510 ++++++++++-------- .../procedure/env/RegionMaintainHandler.java | 2 +- .../impl/region/AddRegionPeerProcedure.java | 49 +- .../thrift/ConfigNodeRPCServiceProcessor.java | 4 +- 5 files changed, 334 insertions(+), 234 deletions(-) diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java index 84145d01d795..334cd09a0d4c 100644 --- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java +++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java @@ -172,6 +172,9 @@ public enum TSStatusCode { REGION_LEADER_CHANGE_ERROR(905), NO_AVAILABLE_REGION_GROUP(906), LACK_PARTITION_ALLOCATION(907), + RECONSTRUCT_REGION_ERROR(908), + EXTEND_REGION_ERROR(909), + REMOVE_REGION_PEER_ERROR(910), // Cluster Manager ADD_CONFIGNODE_ERROR(1000), diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java index a90f8b751be8..9552e2ae8b50 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java @@ -74,11 +74,13 @@ import org.apache.iotdb.confignode.procedure.impl.pipe.task.DropPipeProcedureV2; import org.apache.iotdb.confignode.procedure.impl.pipe.task.StartPipeProcedureV2; import org.apache.iotdb.confignode.procedure.impl.pipe.task.StopPipeProcedureV2; +import org.apache.iotdb.confignode.procedure.impl.region.AddRegionPeerProcedure; import org.apache.iotdb.confignode.procedure.impl.region.CreateRegionGroupsProcedure; import org.apache.iotdb.confignode.procedure.impl.region.ReconstructRegionProcedure; import org.apache.iotdb.confignode.procedure.impl.region.RegionMemberChangeProcedure; import org.apache.iotdb.confignode.procedure.impl.region.RegionMigrateProcedure; import org.apache.iotdb.confignode.procedure.impl.region.RegionMigrationPlan; +import org.apache.iotdb.confignode.procedure.impl.region.RemoveRegionPeerProcedure; import org.apache.iotdb.confignode.procedure.impl.schema.AlterLogicalViewProcedure; import org.apache.iotdb.confignode.procedure.impl.schema.DeactivateTemplateProcedure; import org.apache.iotdb.confignode.procedure.impl.schema.DeleteDatabaseProcedure; @@ -163,8 +165,6 @@ import java.util.concurrent.locks.ReentrantLock; import java.util.stream.Collectors; -import static org.apache.iotdb.confignode.conf.ConfigNodeConstant.REGION_MIGRATE_PROCESS; - public class ProcedureManager { private static final Logger LOGGER = LoggerFactory.getLogger(ProcedureManager.class); @@ -683,6 +683,8 @@ public TSStatus checkRemoveDataNodes(List dataNodeLocations) return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); } + // region region operation related check + /** * Checks whether region migration is allowed. * @@ -693,59 +695,21 @@ public TSStatus checkRemoveDataNodes(List dataNodeLocations) * @param coordinatorForAddPeer the DataNode location acting as the coordinator for adding a peer * @return the status of the migration request (TSStatus) */ - private TSStatus checkRegionMigrate( + private TSStatus checkMigrateRegion( TMigrateRegionReq migrateRegionReq, TConsensusGroupId regionGroupId, TDataNodeLocation originalDataNode, TDataNodeLocation destDataNode, TDataNodeLocation coordinatorForAddPeer) { - String failMessage = null; - // 1. Check if the RegionMigrateProcedure has conflict with another RegionMigrateProcedure - Optional> anotherMigrateProcedure = - getExecutor().getProcedures().values().stream() - .filter( - procedure -> { - if (procedure instanceof RegionMigrateProcedure) { - return !procedure.isFinished() - && ((RegionMigrateProcedure) procedure).getRegionId().equals(regionGroupId); - } - return false; - }) - .findAny(); - ConfigNodeConfig conf = ConfigNodeDescriptor.getInstance().getConf(); - if (TConsensusGroupType.DataRegion == regionGroupId.getType() - && ConsensusFactory.SIMPLE_CONSENSUS.equals(conf.getDataRegionConsensusProtocolClass())) { - failMessage = - "The region you are trying to migrate is using SimpleConsensus, and SimpleConsensus not supports region migration."; - } else if (TConsensusGroupType.SchemaRegion == regionGroupId.getType() - && ConsensusFactory.SIMPLE_CONSENSUS.equals(conf.getSchemaRegionConsensusProtocolClass())) { - failMessage = - "The region you are trying to migrate is using SimpleConsensus, and SimpleConsensus not supports region migration."; - } else if (anotherMigrateProcedure.isPresent()) { - failMessage = - String.format( - "Submit RegionMigrateProcedure failed, " - + "because another RegionMigrateProcedure of the same consensus group %d is already in processing. " - + "A consensus group is able to have at most 1 RegionMigrateProcedure at the same time. " - + "For further information, please search [pid%d] in log. ", - regionGroupId.getId(), anotherMigrateProcedure.get().getProcId()); - } else if (originalDataNode == null) { - failMessage = - String.format( - "Submit RegionMigrateProcedure failed, because no original DataNode %d", - migrateRegionReq.getFromId()); - } else if (destDataNode == null) { - failMessage = - String.format( - "Submit RegionMigrateProcedure failed, because no target DataNode %s", - migrateRegionReq.getToId()); - } else if (coordinatorForAddPeer == null) { - failMessage = - String.format( - "%s, There are no other DataNodes could be selected to perform the add peer process, " - + "please check RegionGroup: %s by show regions sql command", - REGION_MIGRATE_PROCESS, regionGroupId); - } else if (configManager + String failMessage = + regionOperationCommonCheck( + regionGroupId, + destDataNode, + Arrays.asList( + new Pair<>("Original DataNode", originalDataNode), + new Pair<>("Destination DataNode", destDataNode), + new Pair<>("Coordinator for add peer", coordinatorForAddPeer))); + if (configManager .getPartitionManager() .getAllReplicaSets(originalDataNode.getDataNodeId()) .stream() @@ -763,23 +727,179 @@ private TSStatus checkRegionMigrate( String.format( "Submit RegionMigrateProcedure failed, because the target DataNode %s already contains Region %s", migrateRegionReq.getToId(), migrateRegionReq.getRegionId()); - } else if (!configManager - .getNodeManager() - .filterDataNodeThroughStatus(NodeStatus.Running) + } + + if (failMessage != null) { + LOGGER.warn(failMessage); + TSStatus failStatus = new TSStatus(TSStatusCode.MIGRATE_REGION_ERROR.getStatusCode()); + failStatus.setMessage(failMessage); + return failStatus; + } + return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); + } + + private TSStatus checkReconstructRegion( + TReconstructRegionReq req, + TConsensusGroupId regionId, + TDataNodeLocation targetDataNode, + TDataNodeLocation coordinator) { + String failMessage = + regionOperationCommonCheck( + regionId, + targetDataNode, + Arrays.asList( + new Pair<>("Target DataNode", targetDataNode), + new Pair<>("Coordinator", coordinator))); + + ConfigNodeConfig conf = ConfigNodeDescriptor.getInstance().getConf(); + if (configManager + .getPartitionManager() + .getAllReplicaSetsMap(regionId.getType()) + .get(regionId) + .getDataNodeLocationsSize() + == 1) { + failMessage = String.format("%s only has 1 replica, it cannot be reconstructed", regionId); + } else if (configManager + .getPartitionManager() + .getAllReplicaSets(targetDataNode.getDataNodeId()) + .stream() + .noneMatch(replicaSet -> replicaSet.getRegionId().equals(regionId))) { + failMessage = + String.format( + "Submit ReconstructRegionProcedure failed, because the target DataNode %s doesn't contain Region %s", + req.getDataNodeId(), regionId); + } + + if (failMessage != null) { + LOGGER.warn(failMessage); + TSStatus failStatus = new TSStatus(TSStatusCode.RECONSTRUCT_REGION_ERROR.getStatusCode()); + failStatus.setMessage(failMessage); + return failStatus; + } + return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); + } + + private TSStatus checkExtendRegion( + TExtendRegionReq req, + TConsensusGroupId regionId, + TDataNodeLocation targetDataNode, + TDataNodeLocation coordinator) { + String failMessage = + regionOperationCommonCheck( + regionId, + targetDataNode, + Arrays.asList( + new Pair<>("Target DataNode", targetDataNode), + new Pair<>("Coordinator", coordinator))); + if (configManager + .getPartitionManager() + .getAllReplicaSets(targetDataNode.getDataNodeId()) + .stream() + .anyMatch(replicaSet -> replicaSet.getRegionId().equals(regionId))) { + failMessage = + String.format( + "Target DataNode %s already contains region %s", + targetDataNode.getDataNodeId(), req.getRegionId()); + } + + if (failMessage != null) { + LOGGER.warn(failMessage); + TSStatus failStatus = new TSStatus(TSStatusCode.RECONSTRUCT_REGION_ERROR.getStatusCode()); + failStatus.setMessage(failMessage); + return failStatus; + } + return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); + } + + private TSStatus checkRemoveRegion( + TRemoveRegionReq req, + TConsensusGroupId regionId, + TDataNodeLocation targetDataNode, + TDataNodeLocation coordinator) { + String failMessage = + regionOperationCommonCheck( + regionId, + targetDataNode, + Arrays.asList( + new Pair<>("Target DataNode", targetDataNode), + new Pair<>("Coordinator", coordinator))); + + ConfigNodeConfig conf = ConfigNodeDescriptor.getInstance().getConf(); + if (configManager + .getPartitionManager() + .getAllReplicaSetsMap(regionId.getType()) + .get(regionId) + .getDataNodeLocationsSize() + == 1) { + failMessage = String.format("%s only has 1 replica, it cannot be removed", regionId); + } else if (configManager + .getPartitionManager() + .getAllReplicaSets(targetDataNode.getDataNodeId()) .stream() - .map(TDataNodeConfiguration::getLocation) - .map(TDataNodeLocation::getDataNodeId) - .collect(Collectors.toSet()) - .contains(migrateRegionReq.getToId())) { + .noneMatch(replicaSet -> replicaSet.getRegionId().equals(regionId))) { + failMessage = + String.format( + "Target DataNode %s doesn't contain Region %s", req.getDataNodeId(), regionId); + } + + if (failMessage != null) { + LOGGER.warn(failMessage); + TSStatus failStatus = new TSStatus(TSStatusCode.REMOVE_REGION_PEER_ERROR.getStatusCode()); + failStatus.setMessage(failMessage); + return failStatus; + } + return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); + } + + /** + * The common checks of all region operations, include migration, reconstruction, extension, + * removing + * + * @param regionId region group id, also called consensus group id + * @param targetDataNode DataNode should in Running status + * @param relatedDataNodes Pair + * @return The reason if check failed, or null if check pass + */ + private String regionOperationCommonCheck( + TConsensusGroupId regionId, + TDataNodeLocation targetDataNode, + List> relatedDataNodes) { + String failMessage; + + ConfigNodeConfig conf = ConfigNodeDescriptor.getInstance().getConf(); + if (TConsensusGroupType.DataRegion == regionId.getType() + && ConsensusFactory.SIMPLE_CONSENSUS.equals(conf.getDataRegionConsensusProtocolClass())) { + failMessage = "SimpleConsensus not supports region operation."; + } else if (TConsensusGroupType.SchemaRegion == regionId.getType() + && ConsensusFactory.SIMPLE_CONSENSUS.equals(conf.getSchemaRegionConsensusProtocolClass())) { + failMessage = "SimpleConsensus not supports region operation."; + } else if ((failMessage = checkRegionOperationDuplication(regionId)) != null) { + // need to do nothing more + } else if (relatedDataNodes.stream().anyMatch(pair -> pair.getRight() == null)) { + Pair nullPair = + relatedDataNodes.stream().filter(pair -> pair.getRight() == null).findAny().get(); + failMessage = String.format("Cannot find %s", nullPair.getLeft()); + } else if (targetDataNode != null + && !configManager.getNodeManager().filterDataNodeThroughStatus(NodeStatus.Running).stream() + .map(TDataNodeConfiguration::getLocation) + .map(TDataNodeLocation::getDataNodeId) + .collect(Collectors.toSet()) + .contains(targetDataNode.getDataNodeId())) { // Here we only check Running DataNode to implement migration, because removing nodes may not // exist when add peer is performing failMessage = String.format( - "Submit RegionMigrateProcedure failed, because the destDataNode %s is ReadOnly or Unknown.", - migrateRegionReq.getToId()); + "Target DataNode %s is not in Running status.", targetDataNode.getDataNodeId()); + } else if ((failMessage = checkRegionOperationWithRemoveDataNode(regionId, targetDataNode)) + != null) { + // need to do nothing more } - // 2. Check if the RegionMigrateProcedure has conflict with RemoveDataNodesProcedure + return failMessage; + } + + private String checkRegionOperationWithRemoveDataNode( + TConsensusGroupId regionId, TDataNodeLocation targetDataNode) { Optional> conflictRemoveDataNodesProcedure = getExecutor().getProcedures().values().stream() .filter( @@ -797,39 +917,48 @@ private TSStatus checkRegionMigrate( ((RemoveDataNodesProcedure) conflictRemoveDataNodesProcedure.get()).getRemovedDataNodes(); Set removedDataNodesRegionSet = removeDataNodeHandler.getRemovedDataNodesRegionSet(removedDataNodes); - if (removedDataNodesRegionSet.contains(regionGroupId)) { - failMessage = - String.format( - "Submit RegionMigrateProcedure failed, " - + "because another RemoveDataNodesProcedure %s is already in processing which conflicts with this RegionMigrateProcedure. " - + "The RemoveDataNodesProcedure is removing the DataNodes %s which contains the region %s. " - + "For further information, please search [pid%d] in log. ", - conflictRemoveDataNodesProcedure.get().getProcId(), - removedDataNodes, - regionGroupId, - conflictRemoveDataNodesProcedure.get().getProcId()); - } else if (removedDataNodes.contains(destDataNode)) { - failMessage = - String.format( - "Submit RegionMigrateProcedure failed, " - + "because another RemoveDataNodesProcedure %s is already in processing which conflicts with this RegionMigrateProcedure. " - + "The RemoveDataNodesProcedure is removing the target DataNode %s. " - + "For further information, please search [pid%d] in log. ", - conflictRemoveDataNodesProcedure.get().getProcId(), - destDataNode, - conflictRemoveDataNodesProcedure.get().getProcId()); + if (removedDataNodesRegionSet.contains(regionId)) { + return String.format( + "Another RemoveDataNodesProcedure %s is already in processing which conflicts with this procedure. " + + "The RemoveDataNodesProcedure is removing the DataNodes %s which contains the region %s. " + + "For further information, please search [pid%d] in log. ", + conflictRemoveDataNodesProcedure.get().getProcId(), + removedDataNodes, + regionId, + conflictRemoveDataNodesProcedure.get().getProcId()); + } else if (removedDataNodes.contains(targetDataNode)) { + return String.format( + "Another RemoveDataNodesProcedure %s is already in processing which conflicts with this procedure. " + + "The RemoveDataNodesProcedure is removing the target DataNode %s. " + + "For further information, please search [pid%d] in log. ", + conflictRemoveDataNodesProcedure.get().getProcId(), + targetDataNode, + conflictRemoveDataNodesProcedure.get().getProcId()); } } + return null; + } - if (failMessage != null) { - LOGGER.warn(failMessage); - TSStatus failStatus = new TSStatus(TSStatusCode.MIGRATE_REGION_ERROR.getStatusCode()); - failStatus.setMessage(failMessage); - return failStatus; + private String checkRegionOperationDuplication(TConsensusGroupId regionId) { + List> otherRegionMemberChangeProcedures = + getExecutor().getProcedures().values().stream() + .filter(procedure -> !procedure.isFinished()) + .filter(procedure -> procedure instanceof RegionMemberChangeProcedure) + .map(procedure -> (RegionMemberChangeProcedure) procedure) + .filter( + regionMemberChangeProcedure -> + regionId.equals(regionMemberChangeProcedure.getRegionId())) + .collect(Collectors.toList()); + if (!otherRegionMemberChangeProcedures.isEmpty()) { + return String.format( + "%s has some other region operation procedures in progress, their procedure id is: %s", + regionId, otherRegionMemberChangeProcedures); } - return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); + return null; } + // end region + public TSStatus migrateRegion(TMigrateRegionReq migrateRegionReq) { env.getSubmitRegionMigrateLock().lock(); try { @@ -874,7 +1003,7 @@ public TSStatus migrateRegion(TMigrateRegionReq migrateRegionReq) { final TDataNodeLocation coordinatorForRemovePeer = destDataNode; TSStatus status = - checkRegionMigrate( + checkMigrateRegion( migrateRegionReq, regionGroupId, originalDataNode, @@ -948,142 +1077,97 @@ public TSStatus reconstructRegion(TReconstructRegionReq req) { public TSStatus extendRegion(TExtendRegionReq req) { try (AutoCloseableLock ignoredLock = - AutoCloseableLock.acquire(env.getSubmitRegionMigrateLock())) { + AutoCloseableLock.acquire(env.getSubmitRegionMigrateLock())) { + TConsensusGroupId regionId; + Optional optional = + configManager + .getPartitionManager() + .generateTConsensusGroupIdByRegionId(req.getRegionId()); + if (optional.isPresent()) { + regionId = optional.get(); + } else { + LOGGER.error("get region group id fail"); + return new TSStatus(TSStatusCode.EXTEND_REGION_ERROR.getStatusCode()) + .setMessage("get region group id fail"); + } + // find target dn + final TDataNodeLocation targetDataNode = + configManager.getNodeManager().getRegisteredDataNode(req.getDataNodeId()).getLocation(); + // select coordinator for adding peer + RegionMaintainHandler handler = env.getRegionMaintainHandler(); + // TODO: choose the DataNode which has lowest load + final TDataNodeLocation coordinator = + handler + .filterDataNodeWithOtherRegionReplica( + regionId, + targetDataNode, + NodeStatus.Running, + NodeStatus.Removing, + NodeStatus.ReadOnly) + .orElse(null); + // do the check + TSStatus status = checkExtendRegion(req, regionId, targetDataNode, coordinator); + if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { + return status; + } + // submit procedure + AddRegionPeerProcedure procedure = + new AddRegionPeerProcedure(regionId, coordinator, targetDataNode); + this.executor.submitProcedure(procedure); + LOGGER.info("[ExtendRegion] Submit AddRegionPeerProcedure successfully: {}", procedure); + + return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); } } - public TSStatus removeRegion(TRemoveRegionReq req) {} + public TSStatus removeRegion(TRemoveRegionReq req) { + try (AutoCloseableLock ignoredLock = + AutoCloseableLock.acquire(env.getSubmitRegionMigrateLock())) { + TConsensusGroupId regionId; + Optional optional = + configManager + .getPartitionManager() + .generateTConsensusGroupIdByRegionId(req.getRegionId()); + if (optional.isPresent()) { + regionId = optional.get(); + } else { + LOGGER.error("get region group id fail"); + return new TSStatus(TSStatusCode.REMOVE_REGION_PEER_ERROR.getStatusCode()) + .setMessage("get region group id fail"); + } - private TSStatus checkReconstructRegion( - TReconstructRegionReq req, - TConsensusGroupId regionId, - TDataNodeLocation targetDataNode, - TDataNodeLocation coordinator) { - String failMessage = null; + // find target dn + final TDataNodeLocation targetDataNode = + configManager.getNodeManager().getRegisteredDataNode(req.getDataNodeId()).getLocation(); - ConfigNodeConfig conf = ConfigNodeDescriptor.getInstance().getConf(); - if (TConsensusGroupType.DataRegion == regionId.getType() - && conf.getDataReplicationFactor() == 1) { - failMessage = - String.format( - "You are trying to reconstruct data region %s. This region is a single replica and does not support region reconstruction.", - regionId.getId()); - } else if (TConsensusGroupType.SchemaRegion == regionId.getType() - && conf.getSchemaReplicationFactor() == 1) { - failMessage = - String.format( - "You are trying to reconstruct schema region %s. This region is a single replica and does not support region reconstruction.", - regionId.getId()); - } else if ((failMessage = - checkRegionMemberChangeProcedureDuplication( - regionId, "Submit reconstruct region procedure failed")) - != null) { - // need to do nothing more - } else if (targetDataNode == null) { - failMessage = - String.format( - "Submit ReconstructRegionProcedure failed, because cannot find target DataNode %d", - req.getDataNodeId()); - } else if (coordinator == null) { - failMessage = - String.format( - "Submit ReconstructRegionProcedure failed, because there are no other DataNodes could be selected to perform the reconstruction process, " - + "please check RegionGroup: %s by show regions sql command", - regionId); - } else if (configManager - .getPartitionManager() - .getAllReplicaSets(targetDataNode.getDataNodeId()) - .stream() - .noneMatch(replicaSet -> replicaSet.getRegionId().equals(regionId))) { - failMessage = - String.format( - "Submit ReconstructRegionProcedure failed, because the target DataNode %s doesn't contain Region %s", - req.getDataNodeId(), regionId); - } else if (!configManager - .getNodeManager() - .filterDataNodeThroughStatus(NodeStatus.Running) - .stream() - .map(TDataNodeConfiguration::getLocation) - .map(TDataNodeLocation::getDataNodeId) - .collect(Collectors.toSet()) - .contains(targetDataNode.getDataNodeId())) { - // Here we only check Running DataNode to implement migration, because removing nodes may not - // exist when add peer is performing - failMessage = - String.format( - "Submit ReconstructRegionProcedure failed, because the target DataNode %s is not in Running status.", - targetDataNode.getDataNodeId()); - } - - // 2. Check if the RegionMigrateProcedure has conflict with RemoveDataNodesProcedure - Optional> conflictRemoveDataNodesProcedure = - getExecutor().getProcedures().values().stream() - .filter( - procedure -> { - if (procedure instanceof RemoveDataNodesProcedure) { - return !procedure.isFinished(); - } - return false; - }) - .findAny(); + // select coordinator for removing peer + RegionMaintainHandler handler = env.getRegionMaintainHandler(); + final TDataNodeLocation coordinator = + handler + .filterDataNodeWithOtherRegionReplica( + regionId, + targetDataNode, + NodeStatus.Running, + NodeStatus.Removing, + NodeStatus.ReadOnly) + .orElse(null); - if (conflictRemoveDataNodesProcedure.isPresent()) { - RemoveDataNodeHandler removeDataNodeHandler = env.getRemoveDataNodeHandler(); - List removedDataNodes = - ((RemoveDataNodesProcedure) conflictRemoveDataNodesProcedure.get()).getRemovedDataNodes(); - Set removedDataNodesRegionSet = - removeDataNodeHandler.getRemovedDataNodesRegionSet(removedDataNodes); - if (removedDataNodesRegionSet.contains(regionId)) { - failMessage = - String.format( - "Submit ReconstructRegionProcedure failed, " - + "because another RemoveDataNodesProcedure %s is already in processing which conflicts with this RegionMigrateProcedure. " - + "The RemoveDataNodesProcedure is removing the DataNodes %s which contains the region %s. " - + "For further information, please search [pid%d] in log. ", - conflictRemoveDataNodesProcedure.get().getProcId(), - removedDataNodes, - regionId, - conflictRemoveDataNodesProcedure.get().getProcId()); - } else if (removedDataNodes.contains(targetDataNode)) { - failMessage = - String.format( - "Submit ReconstructRegionProcedure failed, " - + "because another RemoveDataNodesProcedure %s is already in processing which conflicts with this RegionMigrateProcedure. " - + "The RemoveDataNodesProcedure is removing the target DataNode %s. " - + "For further information, please search [pid%d] in log. ", - conflictRemoveDataNodesProcedure.get().getProcId(), - targetDataNode, - conflictRemoveDataNodesProcedure.get().getProcId()); + // do the check + TSStatus status = checkRemoveRegion(req, regionId, targetDataNode, coordinator); + if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { + return status; } - } - if (failMessage != null) { - LOGGER.warn(failMessage); - TSStatus failStatus = new TSStatus(TSStatusCode.MIGRATE_REGION_ERROR.getStatusCode()); - failStatus.setMessage(failMessage); - return failStatus; - } - return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); - } + // submit procedure + RemoveRegionPeerProcedure procedure = + new RemoveRegionPeerProcedure(regionId, coordinator, targetDataNode); + this.executor.submitProcedure(procedure); + LOGGER.info( + "[RemoveRegionPeer] Submit RemoveRegionPeerProcedure successfully: {}", procedure); - private String checkRegionMemberChangeProcedureDuplication( - TConsensusGroupId regionId, String failedMessagePrefix) { - List> otherRegionMemberChangeProcedures = - getExecutor().getProcedures().values().stream() - .filter(procedure -> !procedure.isFinished()) - .filter(procedure -> procedure instanceof RegionMemberChangeProcedure) - .map(procedure -> (RegionMemberChangeProcedure) procedure) - .filter( - regionMemberChangeProcedure -> - regionId.equals(regionMemberChangeProcedure.getRegionId())) - .collect(Collectors.toList()); - if (!otherRegionMemberChangeProcedures.isEmpty()) { - return String.format( - "%s, because region %d has some other region membership change procedures in progress, their procedure id is: %s", - failedMessagePrefix, regionId.getId(), otherRegionMemberChangeProcedures); + return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode()); } - return null; } // endregion diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/env/RegionMaintainHandler.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/env/RegionMaintainHandler.java index 1671c696c8fb..92415ec72c9b 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/env/RegionMaintainHandler.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/env/RegionMaintainHandler.java @@ -97,7 +97,7 @@ public static String getIdWithRpcEndpoint(TDataNodeLocation location) { location.getDataNodeId(), location.getClientRpcEndPoint()); } - public String simplifiedLocation(TDataNodeLocation dataNodeLocation) { + public static String simplifiedLocation(TDataNodeLocation dataNodeLocation) { return dataNodeLocation.getDataNodeId() + "@" + dataNodeLocation.getInternalEndPoint().getIp(); } diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/AddRegionPeerProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/AddRegionPeerProcedure.java index 0d0c1044b155..f967bb7e3bbf 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/AddRegionPeerProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/AddRegionPeerProcedure.java @@ -49,6 +49,7 @@ import java.util.stream.Collectors; import static org.apache.iotdb.commons.utils.KillPoint.KillPoint.setKillPoint; +import static org.apache.iotdb.confignode.procedure.env.RegionMaintainHandler.simplifiedLocation; import static org.apache.iotdb.confignode.procedure.state.AddRegionPeerState.UPDATE_REGION_LOCATION_CACHE; import static org.apache.iotdb.rpc.TSStatusCode.SUCCESS_STATUS; @@ -57,7 +58,7 @@ public class AddRegionPeerProcedure extends RegionMemberChangeProcedure correctDataNodeLocations = env.getConfigManager().getPartitionManager().getAllReplicaSets().stream() @@ -178,7 +179,7 @@ private Flow warnAndRollBackAndNoMoreState( new ProcedureException( "[pid{}][AddRegion] Cannot roll back, because cannot find the correct locations")) .getDataNodeLocations(); - if (correctDataNodeLocations.remove(destDataNode)) { + if (correctDataNodeLocations.remove(targetDataNode)) { LOGGER.warn( "[pid{}][AddRegion] It appears that consensus write has not modified the local partition table. " + "Please verify whether a leader change has occurred during this stage. " @@ -191,7 +192,7 @@ private Flow warnAndRollBackAndNoMoreState( .collect(Collectors.toList()) .toString(); List relatedDataNodeLocations = new ArrayList<>(correctDataNodeLocations); - relatedDataNodeLocations.add(destDataNode); + relatedDataNodeLocations.add(targetDataNode); Map relatedDataNodeLocationMap = relatedDataNodeLocations.stream() .collect( @@ -256,7 +257,7 @@ public void serialize(DataOutputStream stream) throws IOException { stream.writeShort(ProcedureType.ADD_REGION_PEER_PROCEDURE.getTypeCode()); super.serialize(stream); ThriftCommonsSerDeUtils.serializeTConsensusGroupId(regionId, stream); - ThriftCommonsSerDeUtils.serializeTDataNodeLocation(destDataNode, stream); + ThriftCommonsSerDeUtils.serializeTDataNodeLocation(targetDataNode, stream); ThriftCommonsSerDeUtils.serializeTDataNodeLocation(coordinator, stream); } @@ -265,7 +266,7 @@ public void deserialize(ByteBuffer byteBuffer) { super.deserialize(byteBuffer); try { regionId = ThriftCommonsSerDeUtils.deserializeTConsensusGroupId(byteBuffer); - destDataNode = ThriftCommonsSerDeUtils.deserializeTDataNodeLocation(byteBuffer); + targetDataNode = ThriftCommonsSerDeUtils.deserializeTDataNodeLocation(byteBuffer); coordinator = ThriftCommonsSerDeUtils.deserializeTDataNodeLocation(byteBuffer); } catch (ThriftSerDeException e) { LOGGER.error("Error in deserialize {}", this.getClass(), e); @@ -283,12 +284,24 @@ public boolean equals(Object obj) { } AddRegionPeerProcedure procedure = (AddRegionPeerProcedure) obj; return this.regionId.equals(procedure.regionId) - && this.destDataNode.equals(procedure.destDataNode) + && this.targetDataNode.equals(procedure.targetDataNode) && this.coordinator.equals(procedure.coordinator); } @Override public int hashCode() { - return Objects.hash(regionId, destDataNode, coordinator); + return Objects.hash(regionId, targetDataNode, coordinator); + } + + @Override + public String toString() { + return "AddRegionPeerProcedure{" + + "regionId=" + + regionId + + ", coordinator=" + + simplifiedLocation(coordinator) + + ", targetDataNode=" + + simplifiedLocation(targetDataNode) + + '}'; } } diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java index 8862db54b0e0..da176c4562c2 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/service/thrift/ConfigNodeRPCServiceProcessor.java @@ -1241,12 +1241,12 @@ public TSStatus reconstructRegion(TReconstructRegionReq req) { @Override public TSStatus extendRegion(TExtendRegionReq req) throws TException { - return null; + return configManager.extendRegion(req); } @Override public TSStatus removeRegion(TRemoveRegionReq req) throws TException { - return null; + return configManager.removeRegion(req); } @Override From b92cb10a4bd154926e0dac0b8f3b4bb48a940402 Mon Sep 17 00:00:00 2001 From: liyuheng Date: Mon, 6 Jan 2025 12:23:28 +0800 Subject: [PATCH 08/13] rename RegionMemberChangeProcedure to RegionOperationProcedure --- .../apache/iotdb/confignode/manager/ProcedureManager.java | 8 ++++---- .../procedure/impl/region/AddRegionPeerProcedure.java | 2 +- .../procedure/impl/region/ReconstructRegionProcedure.java | 2 +- .../procedure/impl/region/RegionMigrateProcedure.java | 2 +- ...ChangeProcedure.java => RegionOperationProcedure.java} | 6 +++--- .../procedure/impl/region/RemoveRegionPeerProcedure.java | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) rename iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/{RegionMemberChangeProcedure.java => RegionOperationProcedure.java} (89%) diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java index 9552e2ae8b50..500c309b7d49 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java @@ -77,7 +77,7 @@ import org.apache.iotdb.confignode.procedure.impl.region.AddRegionPeerProcedure; import org.apache.iotdb.confignode.procedure.impl.region.CreateRegionGroupsProcedure; import org.apache.iotdb.confignode.procedure.impl.region.ReconstructRegionProcedure; -import org.apache.iotdb.confignode.procedure.impl.region.RegionMemberChangeProcedure; +import org.apache.iotdb.confignode.procedure.impl.region.RegionOperationProcedure; import org.apache.iotdb.confignode.procedure.impl.region.RegionMigrateProcedure; import org.apache.iotdb.confignode.procedure.impl.region.RegionMigrationPlan; import org.apache.iotdb.confignode.procedure.impl.region.RemoveRegionPeerProcedure; @@ -940,11 +940,11 @@ private String checkRegionOperationWithRemoveDataNode( } private String checkRegionOperationDuplication(TConsensusGroupId regionId) { - List> otherRegionMemberChangeProcedures = + List> otherRegionMemberChangeProcedures = getExecutor().getProcedures().values().stream() .filter(procedure -> !procedure.isFinished()) - .filter(procedure -> procedure instanceof RegionMemberChangeProcedure) - .map(procedure -> (RegionMemberChangeProcedure) procedure) + .filter(procedure -> procedure instanceof RegionOperationProcedure) + .map(procedure -> (RegionOperationProcedure) procedure) .filter( regionMemberChangeProcedure -> regionId.equals(regionMemberChangeProcedure.getRegionId())) diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/AddRegionPeerProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/AddRegionPeerProcedure.java index f967bb7e3bbf..3da3e0e8abb2 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/AddRegionPeerProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/AddRegionPeerProcedure.java @@ -53,7 +53,7 @@ import static org.apache.iotdb.confignode.procedure.state.AddRegionPeerState.UPDATE_REGION_LOCATION_CACHE; import static org.apache.iotdb.rpc.TSStatusCode.SUCCESS_STATUS; -public class AddRegionPeerProcedure extends RegionMemberChangeProcedure { +public class AddRegionPeerProcedure extends RegionOperationProcedure { private static final Logger LOGGER = LoggerFactory.getLogger(AddRegionPeerProcedure.class); private TDataNodeLocation coordinator; diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/ReconstructRegionProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/ReconstructRegionProcedure.java index 0c3d14ceb368..5b36788a712a 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/ReconstructRegionProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/ReconstructRegionProcedure.java @@ -41,7 +41,7 @@ import java.nio.ByteBuffer; public class ReconstructRegionProcedure - extends RegionMemberChangeProcedure { + extends RegionOperationProcedure { private static final Logger LOGGER = LoggerFactory.getLogger(ReconstructRegionProcedure.class); private TDataNodeLocation targetDataNode; diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMigrateProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMigrateProcedure.java index fb4e45749fdc..951d521784b6 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMigrateProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMigrateProcedure.java @@ -41,7 +41,7 @@ import java.util.Objects; /** Region migrate procedure */ -public class RegionMigrateProcedure extends RegionMemberChangeProcedure { +public class RegionMigrateProcedure extends RegionOperationProcedure { private static final Logger LOGGER = LoggerFactory.getLogger(RegionMigrateProcedure.class); diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMemberChangeProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionOperationProcedure.java similarity index 89% rename from iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMemberChangeProcedure.java rename to iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionOperationProcedure.java index 00976e1a7eda..ad0cb38ac82d 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionMemberChangeProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RegionOperationProcedure.java @@ -23,13 +23,13 @@ import org.apache.iotdb.confignode.procedure.env.ConfigNodeProcedureEnv; import org.apache.iotdb.confignode.procedure.impl.StateMachineProcedure; -public abstract class RegionMemberChangeProcedure +public abstract class RegionOperationProcedure extends StateMachineProcedure { TConsensusGroupId regionId; - public RegionMemberChangeProcedure() {} + public RegionOperationProcedure() {} - public RegionMemberChangeProcedure(TConsensusGroupId regionId) { + public RegionOperationProcedure(TConsensusGroupId regionId) { this.regionId = regionId; } diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RemoveRegionPeerProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RemoveRegionPeerProcedure.java index d90fa3fcd801..64905361250f 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RemoveRegionPeerProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/RemoveRegionPeerProcedure.java @@ -51,7 +51,7 @@ import static org.apache.iotdb.confignode.procedure.state.RemoveRegionPeerState.REMOVE_REGION_PEER; import static org.apache.iotdb.rpc.TSStatusCode.SUCCESS_STATUS; -public class RemoveRegionPeerProcedure extends RegionMemberChangeProcedure { +public class RemoveRegionPeerProcedure extends RegionOperationProcedure { private static final Logger LOGGER = LoggerFactory.getLogger(RemoveRegionPeerProcedure.class); private TDataNodeLocation coordinator; private TDataNodeLocation targetDataNode; From 3618729955ed417f564499139e96f5df60971027 Mon Sep 17 00:00:00 2001 From: liyuheng Date: Mon, 6 Jan 2025 15:01:05 +0800 Subject: [PATCH 09/13] move function & files --- ...grateDataNodeCrashITFrameworkForIoTV1.java | 2 +- ...grateDataNodeCrashITFrameworkForIoTV2.java | 2 +- ...egionOperationReliabilityITFramework.java} | 36 ++--------- ...TDBRegionMigrateNormalITForIoTV2Batch.java | 6 +- ...oTDBRegionMigrateOtherITForIoTV2Batch.java | 6 +- ...DBRegionMigrateNormalITForIoTV2Stream.java | 6 +- ...TDBRegionMigrateOtherITForIoTV2Stream.java | 6 +- ...BRegionMigrateDataNodeCrashForIoTV1IT.java | 4 +- ...gionMigrateDataNodeCrashForIoTV2Batch.java | 4 +- ...ionMigrateDataNodeCrashForIoTV2Stream.java | 4 +- ...IoTDBRegionMigrateClusterCrashIoTV1IT.java | 4 +- ...DBRegionMigrateConfigNodeCrashIoTV1IT.java | 4 +- ...DBRegionMigrateClusterCrashIoTV2Batch.java | 4 +- ...egionMigrateConfigNodeCrashIoTV2Batch.java | 4 +- ...BRegionMigrateClusterCrashIoTV2Stream.java | 4 +- ...gionMigrateConfigNodeCrashIoTV2Stream.java | 4 +- .../IoTDBRemoveDataNodeITFramework.java | 14 ++--- .../it/autocreate/IoTDBPipeAutoDropIT.java | 10 ++-- .../it/tablemodel/IoTDBPipeAutoDropIT.java | 10 ++-- .../org/apache/iotdb/util/MagicUtils.java | 60 +++++++++++++++++++ 20 files changed, 115 insertions(+), 79 deletions(-) rename integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/{IoTDBRegionMigrateReliabilityITFramework.java => IoTDBRegionOperationReliabilityITFramework.java} (95%) rename integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/{ => iotv2}/batch/IoTDBRegionMigrateNormalITForIoTV2Batch.java (93%) rename integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/{ => iotv2}/batch/IoTDBRegionMigrateOtherITForIoTV2Batch.java (94%) rename integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/{ => iotv2}/stream/IoTDBRegionMigrateNormalITForIoTV2Stream.java (94%) rename integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/{ => iotv2}/stream/IoTDBRegionMigrateOtherITForIoTV2Stream.java (95%) create mode 100644 integration-test/src/test/java/org/apache/iotdb/util/MagicUtils.java diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionMigrateDataNodeCrashITFrameworkForIoTV1.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionMigrateDataNodeCrashITFrameworkForIoTV1.java index 334e91352ec8..7899d570bc4e 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionMigrateDataNodeCrashITFrameworkForIoTV1.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionMigrateDataNodeCrashITFrameworkForIoTV1.java @@ -26,7 +26,7 @@ import org.junit.Before; public class IoTDBRegionMigrateDataNodeCrashITFrameworkForIoTV1 - extends IoTDBRegionMigrateReliabilityITFramework { + extends IoTDBRegionOperationReliabilityITFramework { @Override @Before diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionMigrateDataNodeCrashITFrameworkForIoTV2.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionMigrateDataNodeCrashITFrameworkForIoTV2.java index 54635c00a5c7..e48178600739 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionMigrateDataNodeCrashITFrameworkForIoTV2.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionMigrateDataNodeCrashITFrameworkForIoTV2.java @@ -22,7 +22,7 @@ import org.apache.iotdb.commons.utils.KillPoint.KillNode; public class IoTDBRegionMigrateDataNodeCrashITFrameworkForIoTV2 - extends IoTDBRegionMigrateReliabilityITFramework { + extends IoTDBRegionOperationReliabilityITFramework { @SafeVarargs public final > void success(T... dataNodeKillPoints) throws Exception { diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionMigrateReliabilityITFramework.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java similarity index 95% rename from integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionMigrateReliabilityITFramework.java rename to integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java index d82022587a58..99f5883e114d 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionMigrateReliabilityITFramework.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java @@ -39,6 +39,7 @@ import org.apache.iotdb.itbase.exception.InconsistentDataException; import org.apache.iotdb.metrics.utils.SystemType; +import org.apache.iotdb.util.MagicUtils; import org.apache.thrift.TException; import org.awaitility.Awaitility; import org.awaitility.core.ConditionTimeoutException; @@ -52,9 +53,6 @@ import java.io.File; import java.io.IOException; import java.io.InputStreamReader; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Proxy; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; @@ -77,9 +75,9 @@ import java.util.function.Consumer; import java.util.stream.Collectors; -public class IoTDBRegionMigrateReliabilityITFramework { +public class IoTDBRegionOperationReliabilityITFramework { private static final Logger LOGGER = - LoggerFactory.getLogger(IoTDBRegionMigrateReliabilityITFramework.class); + LoggerFactory.getLogger(IoTDBRegionOperationReliabilityITFramework.class); private static final String INSERTION1 = "INSERT INTO root.sg.d1(timestamp,speed,temperature) values(100, 1, 2)"; private static final String INSERTION2 = @@ -208,9 +206,9 @@ public void generalTestWithAllOptions( EnvFactory.getEnv().registerDataNodeKillPoints(new ArrayList<>(dataNodeKeywords)); EnvFactory.getEnv().initClusterEnvironment(configNodeNum, dataNodeNum); - try (final Connection connection = closeQuietly(EnvFactory.getEnv().getConnection()); - final Statement statement = closeQuietly(connection.createStatement()); - SyncConfigNodeIServiceClient client = + try (final Connection connection = MagicUtils.makeItCloseQuietly(EnvFactory.getEnv().getConnection()); + final Statement statement = MagicUtils.makeItCloseQuietly(connection.createStatement()); + SyncConfigNodeIServiceClient client = (SyncConfigNodeIServiceClient) EnvFactory.getEnv().getLeaderConfigNodeConnection()) { statement.execute(INSERTION1); @@ -703,26 +701,4 @@ protected static > KeySetView buildSet(T... k return result; } - public static T closeQuietly(T t) { - InvocationHandler handler = - (proxy, method, args) -> { - try { - if (method.getName().equals("close")) { - try { - method.invoke(t, args); - } catch (Throwable e) { - LOGGER.warn("Exception happens during close(): ", e); - } - return null; - } else { - return method.invoke(t, args); - } - } catch (InvocationTargetException e) { - throw e.getTargetException(); - } - }; - return (T) - Proxy.newProxyInstance( - t.getClass().getClassLoader(), t.getClass().getInterfaces(), handler); - } } diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/batch/IoTDBRegionMigrateNormalITForIoTV2Batch.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/batch/IoTDBRegionMigrateNormalITForIoTV2Batch.java similarity index 93% rename from integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/batch/IoTDBRegionMigrateNormalITForIoTV2Batch.java rename to integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/batch/IoTDBRegionMigrateNormalITForIoTV2Batch.java index fed2a6629787..8527591f35f9 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/batch/IoTDBRegionMigrateNormalITForIoTV2Batch.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/batch/IoTDBRegionMigrateNormalITForIoTV2Batch.java @@ -17,10 +17,10 @@ * under the License. */ -package org.apache.iotdb.confignode.it.regionmigration.pass.commit.batch; +package org.apache.iotdb.confignode.it.regionmigration.pass.commit.iotv2.batch; import org.apache.iotdb.commons.utils.KillPoint.KillNode; -import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework; +import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework; import org.apache.iotdb.it.framework.IoTDBTestRunner; import org.apache.iotdb.itbase.category.ClusterIT; @@ -31,7 +31,7 @@ @Category({ClusterIT.class}) @RunWith(IoTDBTestRunner.class) public class IoTDBRegionMigrateNormalITForIoTV2Batch - extends IoTDBRegionMigrateReliabilityITFramework { + extends IoTDBRegionOperationReliabilityITFramework { @Test public void normal1C2DTest() throws Exception { successTest(1, 1, 1, 2, noKillPoints(), noKillPoints(), KillNode.ALL_NODES); diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/batch/IoTDBRegionMigrateOtherITForIoTV2Batch.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/batch/IoTDBRegionMigrateOtherITForIoTV2Batch.java similarity index 94% rename from integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/batch/IoTDBRegionMigrateOtherITForIoTV2Batch.java rename to integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/batch/IoTDBRegionMigrateOtherITForIoTV2Batch.java index a99b49c30ce1..5051011ca798 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/batch/IoTDBRegionMigrateOtherITForIoTV2Batch.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/batch/IoTDBRegionMigrateOtherITForIoTV2Batch.java @@ -17,11 +17,11 @@ * under the License. */ -package org.apache.iotdb.confignode.it.regionmigration.pass.commit.batch; +package org.apache.iotdb.confignode.it.regionmigration.pass.commit.iotv2.batch; import org.apache.iotdb.commons.utils.KillPoint.KillNode; import org.apache.iotdb.commons.utils.KillPoint.NeverTriggeredKillPoint; -import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework; +import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework; import org.apache.iotdb.it.framework.IoTDBTestRunner; import org.apache.iotdb.itbase.category.ClusterIT; @@ -33,7 +33,7 @@ @RunWith(IoTDBTestRunner.class) @Category({ClusterIT.class}) public class IoTDBRegionMigrateOtherITForIoTV2Batch - extends IoTDBRegionMigrateReliabilityITFramework { + extends IoTDBRegionOperationReliabilityITFramework { @Test public void badKillPoint() throws Exception { try { diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/stream/IoTDBRegionMigrateNormalITForIoTV2Stream.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/stream/IoTDBRegionMigrateNormalITForIoTV2Stream.java similarity index 94% rename from integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/stream/IoTDBRegionMigrateNormalITForIoTV2Stream.java rename to integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/stream/IoTDBRegionMigrateNormalITForIoTV2Stream.java index afba878bd39a..73651762e14d 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/stream/IoTDBRegionMigrateNormalITForIoTV2Stream.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/stream/IoTDBRegionMigrateNormalITForIoTV2Stream.java @@ -17,10 +17,10 @@ * under the License. */ -package org.apache.iotdb.confignode.it.regionmigration.pass.commit.stream; +package org.apache.iotdb.confignode.it.regionmigration.pass.commit.iotv2.stream; import org.apache.iotdb.commons.utils.KillPoint.KillNode; -import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework; +import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework; import org.apache.iotdb.consensus.ConsensusFactory; import org.apache.iotdb.it.env.EnvFactory; import org.apache.iotdb.it.framework.IoTDBTestRunner; @@ -34,7 +34,7 @@ @Category({ClusterIT.class}) @RunWith(IoTDBTestRunner.class) public class IoTDBRegionMigrateNormalITForIoTV2Stream - extends IoTDBRegionMigrateReliabilityITFramework { + extends IoTDBRegionOperationReliabilityITFramework { @Override @Before diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/stream/IoTDBRegionMigrateOtherITForIoTV2Stream.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/stream/IoTDBRegionMigrateOtherITForIoTV2Stream.java similarity index 95% rename from integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/stream/IoTDBRegionMigrateOtherITForIoTV2Stream.java rename to integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/stream/IoTDBRegionMigrateOtherITForIoTV2Stream.java index 9406f2f2fcbe..a4a159e3d40a 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/stream/IoTDBRegionMigrateOtherITForIoTV2Stream.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/stream/IoTDBRegionMigrateOtherITForIoTV2Stream.java @@ -17,11 +17,11 @@ * under the License. */ -package org.apache.iotdb.confignode.it.regionmigration.pass.commit.stream; +package org.apache.iotdb.confignode.it.regionmigration.pass.commit.iotv2.stream; import org.apache.iotdb.commons.utils.KillPoint.KillNode; import org.apache.iotdb.commons.utils.KillPoint.NeverTriggeredKillPoint; -import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework; +import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework; import org.apache.iotdb.consensus.ConsensusFactory; import org.apache.iotdb.it.env.EnvFactory; import org.apache.iotdb.it.framework.IoTDBTestRunner; @@ -36,7 +36,7 @@ @RunWith(IoTDBTestRunner.class) @Category({ClusterIT.class}) public class IoTDBRegionMigrateOtherITForIoTV2Stream - extends IoTDBRegionMigrateReliabilityITFramework { + extends IoTDBRegionOperationReliabilityITFramework { @Override @Before diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/datanodecrash/iotv1/IoTDBRegionMigrateDataNodeCrashForIoTV1IT.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/datanodecrash/iotv1/IoTDBRegionMigrateDataNodeCrashForIoTV1IT.java index 704ae82af3c9..50beb4ec5493 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/datanodecrash/iotv1/IoTDBRegionMigrateDataNodeCrashForIoTV1IT.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/datanodecrash/iotv1/IoTDBRegionMigrateDataNodeCrashForIoTV1IT.java @@ -21,7 +21,7 @@ import org.apache.iotdb.commons.utils.KillPoint.DataNodeKillPoints; import org.apache.iotdb.commons.utils.KillPoint.KillNode; -import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework; +import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework; import org.apache.iotdb.consensus.ConsensusFactory; import org.apache.iotdb.it.env.EnvFactory; import org.apache.iotdb.it.framework.IoTDBTestRunner; @@ -35,7 +35,7 @@ @Category({DailyIT.class}) @RunWith(IoTDBTestRunner.class) public class IoTDBRegionMigrateDataNodeCrashForIoTV1IT - extends IoTDBRegionMigrateReliabilityITFramework { + extends IoTDBRegionOperationReliabilityITFramework { // region Coordinator DataNode crash tests private final int dataReplicateFactor = 2; diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/datanodecrash/iotv2/batch/IoTDBRegionMigrateDataNodeCrashForIoTV2Batch.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/datanodecrash/iotv2/batch/IoTDBRegionMigrateDataNodeCrashForIoTV2Batch.java index 4938ed6d8b83..16b9819301a0 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/datanodecrash/iotv2/batch/IoTDBRegionMigrateDataNodeCrashForIoTV2Batch.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/datanodecrash/iotv2/batch/IoTDBRegionMigrateDataNodeCrashForIoTV2Batch.java @@ -21,7 +21,7 @@ import org.apache.iotdb.commons.utils.KillPoint.DataNodeKillPoints; import org.apache.iotdb.commons.utils.KillPoint.KillNode; -import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework; +import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework; import org.apache.iotdb.it.framework.IoTDBTestRunner; import org.apache.iotdb.itbase.category.DailyIT; @@ -32,7 +32,7 @@ @Category({DailyIT.class}) @RunWith(IoTDBTestRunner.class) public class IoTDBRegionMigrateDataNodeCrashForIoTV2Batch - extends IoTDBRegionMigrateReliabilityITFramework { + extends IoTDBRegionOperationReliabilityITFramework { // region Coordinator DataNode crash tests private final int dataReplicateFactor = 2; diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/datanodecrash/iotv2/stream/IoTDBRegionMigrateDataNodeCrashForIoTV2Stream.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/datanodecrash/iotv2/stream/IoTDBRegionMigrateDataNodeCrashForIoTV2Stream.java index adadc8d0de9f..e6a39210b592 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/datanodecrash/iotv2/stream/IoTDBRegionMigrateDataNodeCrashForIoTV2Stream.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/datanodecrash/iotv2/stream/IoTDBRegionMigrateDataNodeCrashForIoTV2Stream.java @@ -21,7 +21,7 @@ import org.apache.iotdb.commons.utils.KillPoint.DataNodeKillPoints; import org.apache.iotdb.commons.utils.KillPoint.KillNode; -import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework; +import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework; import org.apache.iotdb.consensus.ConsensusFactory; import org.apache.iotdb.it.env.EnvFactory; import org.apache.iotdb.it.framework.IoTDBTestRunner; @@ -35,7 +35,7 @@ @Category({DailyIT.class}) @RunWith(IoTDBTestRunner.class) public class IoTDBRegionMigrateDataNodeCrashForIoTV2Stream - extends IoTDBRegionMigrateReliabilityITFramework { + extends IoTDBRegionOperationReliabilityITFramework { // region Coordinator DataNode crash tests private final int dataReplicateFactor = 2; diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv1/IoTDBRegionMigrateClusterCrashIoTV1IT.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv1/IoTDBRegionMigrateClusterCrashIoTV1IT.java index 7f2bfb3066b2..544c4b568170 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv1/IoTDBRegionMigrateClusterCrashIoTV1IT.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv1/IoTDBRegionMigrateClusterCrashIoTV1IT.java @@ -19,7 +19,7 @@ package org.apache.iotdb.confignode.it.regionmigration.pass.daily.iotv1; -import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework; +import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework; import org.apache.iotdb.confignode.procedure.state.AddRegionPeerState; import org.apache.iotdb.confignode.procedure.state.RemoveRegionPeerState; import org.apache.iotdb.consensus.ConsensusFactory; @@ -35,7 +35,7 @@ @Category({DailyIT.class}) @RunWith(IoTDBTestRunner.class) public class IoTDBRegionMigrateClusterCrashIoTV1IT - extends IoTDBRegionMigrateReliabilityITFramework { + extends IoTDBRegionOperationReliabilityITFramework { @Override @Before diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv1/IoTDBRegionMigrateConfigNodeCrashIoTV1IT.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv1/IoTDBRegionMigrateConfigNodeCrashIoTV1IT.java index e63ded6baf42..ebda0c36ee32 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv1/IoTDBRegionMigrateConfigNodeCrashIoTV1IT.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv1/IoTDBRegionMigrateConfigNodeCrashIoTV1IT.java @@ -21,7 +21,7 @@ import org.apache.iotdb.commons.utils.KillPoint.KillNode; import org.apache.iotdb.commons.utils.KillPoint.KillPoint; -import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework; +import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework; import org.apache.iotdb.confignode.procedure.state.AddRegionPeerState; import org.apache.iotdb.confignode.procedure.state.RegionTransitionState; import org.apache.iotdb.confignode.procedure.state.RemoveRegionPeerState; @@ -43,7 +43,7 @@ @Category({DailyIT.class}) @RunWith(IoTDBTestRunner.class) public class IoTDBRegionMigrateConfigNodeCrashIoTV1IT - extends IoTDBRegionMigrateReliabilityITFramework { + extends IoTDBRegionOperationReliabilityITFramework { @Override @Before diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv2/batch/IoTDBRegionMigrateClusterCrashIoTV2Batch.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv2/batch/IoTDBRegionMigrateClusterCrashIoTV2Batch.java index faf1c21778fb..36d7598dcee4 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv2/batch/IoTDBRegionMigrateClusterCrashIoTV2Batch.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv2/batch/IoTDBRegionMigrateClusterCrashIoTV2Batch.java @@ -19,7 +19,7 @@ package org.apache.iotdb.confignode.it.regionmigration.pass.daily.iotv2.batch; -import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework; +import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework; import org.apache.iotdb.confignode.procedure.state.AddRegionPeerState; import org.apache.iotdb.confignode.procedure.state.RemoveRegionPeerState; import org.apache.iotdb.it.framework.IoTDBTestRunner; @@ -32,7 +32,7 @@ @Category({DailyIT.class}) @RunWith(IoTDBTestRunner.class) public class IoTDBRegionMigrateClusterCrashIoTV2Batch - extends IoTDBRegionMigrateReliabilityITFramework { + extends IoTDBRegionOperationReliabilityITFramework { @Test public void clusterCrash1() throws Exception { diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv2/batch/IoTDBRegionMigrateConfigNodeCrashIoTV2Batch.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv2/batch/IoTDBRegionMigrateConfigNodeCrashIoTV2Batch.java index f3fa4a055ead..5dc3a303628f 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv2/batch/IoTDBRegionMigrateConfigNodeCrashIoTV2Batch.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv2/batch/IoTDBRegionMigrateConfigNodeCrashIoTV2Batch.java @@ -21,7 +21,7 @@ import org.apache.iotdb.commons.utils.KillPoint.KillNode; import org.apache.iotdb.commons.utils.KillPoint.KillPoint; -import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework; +import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework; import org.apache.iotdb.confignode.procedure.state.AddRegionPeerState; import org.apache.iotdb.confignode.procedure.state.RegionTransitionState; import org.apache.iotdb.confignode.procedure.state.RemoveRegionPeerState; @@ -40,7 +40,7 @@ @Category({DailyIT.class}) @RunWith(IoTDBTestRunner.class) public class IoTDBRegionMigrateConfigNodeCrashIoTV2Batch - extends IoTDBRegionMigrateReliabilityITFramework { + extends IoTDBRegionOperationReliabilityITFramework { @Test @Ignore public void cnCrashDuringPreCheckTest() throws Exception { diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv2/stream/IoTDBRegionMigrateClusterCrashIoTV2Stream.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv2/stream/IoTDBRegionMigrateClusterCrashIoTV2Stream.java index 4c11e39cf8d3..951ff951ec34 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv2/stream/IoTDBRegionMigrateClusterCrashIoTV2Stream.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv2/stream/IoTDBRegionMigrateClusterCrashIoTV2Stream.java @@ -19,7 +19,7 @@ package org.apache.iotdb.confignode.it.regionmigration.pass.daily.iotv2.stream; -import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework; +import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework; import org.apache.iotdb.confignode.procedure.state.AddRegionPeerState; import org.apache.iotdb.confignode.procedure.state.RemoveRegionPeerState; import org.apache.iotdb.consensus.ConsensusFactory; @@ -35,7 +35,7 @@ @Category({DailyIT.class}) @RunWith(IoTDBTestRunner.class) public class IoTDBRegionMigrateClusterCrashIoTV2Stream - extends IoTDBRegionMigrateReliabilityITFramework { + extends IoTDBRegionOperationReliabilityITFramework { @Override @Before diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv2/stream/IoTDBRegionMigrateConfigNodeCrashIoTV2Stream.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv2/stream/IoTDBRegionMigrateConfigNodeCrashIoTV2Stream.java index d7c1a14d19bf..66fe3566b25d 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv2/stream/IoTDBRegionMigrateConfigNodeCrashIoTV2Stream.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/daily/iotv2/stream/IoTDBRegionMigrateConfigNodeCrashIoTV2Stream.java @@ -21,7 +21,7 @@ import org.apache.iotdb.commons.utils.KillPoint.KillNode; import org.apache.iotdb.commons.utils.KillPoint.KillPoint; -import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework; +import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework; import org.apache.iotdb.confignode.procedure.state.AddRegionPeerState; import org.apache.iotdb.confignode.procedure.state.RegionTransitionState; import org.apache.iotdb.confignode.procedure.state.RemoveRegionPeerState; @@ -43,7 +43,7 @@ @Category({DailyIT.class}) @RunWith(IoTDBTestRunner.class) public class IoTDBRegionMigrateConfigNodeCrashIoTV2Stream - extends IoTDBRegionMigrateReliabilityITFramework { + extends IoTDBRegionOperationReliabilityITFramework { @Override @Before diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/removedatanode/IoTDBRemoveDataNodeITFramework.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/removedatanode/IoTDBRemoveDataNodeITFramework.java index 5082c7beda01..87052a99c4af 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/removedatanode/IoTDBRemoveDataNodeITFramework.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/removedatanode/IoTDBRemoveDataNodeITFramework.java @@ -51,8 +51,8 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; -import static org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework.closeQuietly; -import static org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework.getRegionMap; +import static org.apache.iotdb.util.MagicUtils.makeItCloseQuietly; +import static org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework.getRegionMap; public class IoTDBRemoveDataNodeITFramework { private static final Logger LOGGER = @@ -143,9 +143,9 @@ public void testRemoveDataNode( dataRegionPerDataNode * dataNodeNum / dataReplicateFactor); EnvFactory.getEnv().initClusterEnvironment(configNodeNum, dataNodeNum); - try (final Connection connection = closeQuietly(EnvFactory.getEnv().getConnection()); - final Statement statement = closeQuietly(connection.createStatement()); - SyncConfigNodeIServiceClient client = + try (final Connection connection = makeItCloseQuietly(EnvFactory.getEnv().getConnection()); + final Statement statement = makeItCloseQuietly(connection.createStatement()); + SyncConfigNodeIServiceClient client = (SyncConfigNodeIServiceClient) EnvFactory.getEnv().getLeaderConfigNodeConnection()) { // Insert data @@ -238,8 +238,8 @@ public void testRemoveDataNode( LOGGER.error("Unexpected error:", e); } - try (final Connection connection = closeQuietly(EnvFactory.getEnv().getConnection()); - final Statement statement = closeQuietly(connection.createStatement())) { + try (final Connection connection = makeItCloseQuietly(EnvFactory.getEnv().getConnection()); + final Statement statement = makeItCloseQuietly(connection.createStatement())) { // Check the data region distribution after removing data nodes ResultSet result = statement.executeQuery(SHOW_REGIONS); diff --git a/integration-test/src/test/java/org/apache/iotdb/pipe/it/autocreate/IoTDBPipeAutoDropIT.java b/integration-test/src/test/java/org/apache/iotdb/pipe/it/autocreate/IoTDBPipeAutoDropIT.java index c30006a73f4d..f131f7d2c130 100644 --- a/integration-test/src/test/java/org/apache/iotdb/pipe/it/autocreate/IoTDBPipeAutoDropIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/pipe/it/autocreate/IoTDBPipeAutoDropIT.java @@ -43,7 +43,7 @@ import java.util.Map; import java.util.concurrent.TimeUnit; -import static org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework.closeQuietly; +import static org.apache.iotdb.util.MagicUtils.makeItCloseQuietly; import static org.awaitility.Awaitility.await; @RunWith(IoTDBTestRunner.class) @@ -93,8 +93,8 @@ public void testAutoDropInHistoricalTransfer() throws Exception { "count(root.db.d1.s1),", Collections.singleton("1,")); - try (final Connection connection = closeQuietly(senderEnv.getConnection()); - final Statement statement = closeQuietly(connection.createStatement()); ) { + try (final Connection connection = makeItCloseQuietly(senderEnv.getConnection()); + final Statement statement = makeItCloseQuietly(connection.createStatement()); ) { ResultSet result = statement.executeQuery("show pipes"); await() .pollInSameThread() @@ -168,8 +168,8 @@ public void testAutoDropInHistoricalTransferWithTimeRange() throws Exception { "count(root.db.d1.s1),", Collections.singleton("3,")); - try (final Connection connection = closeQuietly(senderEnv.getConnection()); - final Statement statement = closeQuietly(connection.createStatement()); ) { + try (final Connection connection = makeItCloseQuietly(senderEnv.getConnection()); + final Statement statement = makeItCloseQuietly(connection.createStatement()); ) { ResultSet result = statement.executeQuery("show pipes"); await() .pollInSameThread() diff --git a/integration-test/src/test/java/org/apache/iotdb/pipe/it/tablemodel/IoTDBPipeAutoDropIT.java b/integration-test/src/test/java/org/apache/iotdb/pipe/it/tablemodel/IoTDBPipeAutoDropIT.java index bae1dda7a739..95d944242066 100644 --- a/integration-test/src/test/java/org/apache/iotdb/pipe/it/tablemodel/IoTDBPipeAutoDropIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/pipe/it/tablemodel/IoTDBPipeAutoDropIT.java @@ -44,7 +44,7 @@ import java.util.concurrent.TimeUnit; import java.util.function.Consumer; -import static org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionMigrateReliabilityITFramework.closeQuietly; +import static org.apache.iotdb.util.MagicUtils.makeItCloseQuietly; import static org.awaitility.Awaitility.await; @RunWith(IoTDBTestRunner.class) @@ -105,8 +105,8 @@ public void testAutoDropInHistoricalTransfer() throws Exception { handleFailure); } - try (final Connection connection = closeQuietly(senderEnv.getConnection()); - final Statement statement = closeQuietly(connection.createStatement()); ) { + try (final Connection connection = makeItCloseQuietly(senderEnv.getConnection()); + final Statement statement = makeItCloseQuietly(connection.createStatement()); ) { ResultSet result = statement.executeQuery("show pipes"); await() .pollInSameThread() @@ -187,8 +187,8 @@ public void testAutoDropInHistoricalTransferWithTimeRange() throws Exception { handleFailure); } - try (final Connection connection = closeQuietly(senderEnv.getConnection()); - final Statement statement = closeQuietly(connection.createStatement()); ) { + try (final Connection connection = makeItCloseQuietly(senderEnv.getConnection()); + final Statement statement = makeItCloseQuietly(connection.createStatement()); ) { ResultSet result = statement.executeQuery("show pipes"); await() .pollInSameThread() diff --git a/integration-test/src/test/java/org/apache/iotdb/util/MagicUtils.java b/integration-test/src/test/java/org/apache/iotdb/util/MagicUtils.java new file mode 100644 index 000000000000..0adf40f7590f --- /dev/null +++ b/integration-test/src/test/java/org/apache/iotdb/util/MagicUtils.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.iotdb.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Proxy; + +public class MagicUtils { + + private static Logger LOGGER = LoggerFactory.getLogger(MagicUtils.class); + + /** + * Ignore all exceptions during close() + * @param t target object + * @return object which will close without exception + */ + public static T makeItCloseQuietly(T t) { + InvocationHandler handler = + (proxy, method, args) -> { + try { + if (method.getName().equals("close")) { + try { + method.invoke(t, args); + } catch (Throwable e) { + LOGGER.warn("Exception happens during close(): ", e); + } + return null; + } else { + return method.invoke(t, args); + } + } catch (InvocationTargetException e) { + throw e.getTargetException(); + } + }; + return (T) + Proxy.newProxyInstance( + t.getClass().getClassLoader(), t.getClass().getInterfaces(), handler); + } +} From a2bcb7de6991d5524b93660ecde516facb116960 Mon Sep 17 00:00:00 2001 From: liyuheng Date: Mon, 6 Jan 2025 17:30:31 +0800 Subject: [PATCH 10/13] add IT --- ...RegionOperationReliabilityITFramework.java | 128 +++++++++----- ...B_RegionGroupExpandAndShrink_IoTV1_IT.java | 156 ++++++++++++++++++ ...TDBRegionMigrateNormalITForIoTV2Batch.java | 2 +- ...oTDBRegionMigrateOtherITForIoTV2Batch.java | 2 +- ...DBRegionMigrateNormalITForIoTV2Stream.java | 2 +- ...TDBRegionMigrateOtherITForIoTV2Stream.java | 2 +- .../IoTDBRemoveDataNodeITFramework.java | 18 +- .../it/autocreate/IoTDBPipeAutoDropIT.java | 4 +- .../it/tablemodel/IoTDBPipeAutoDropIT.java | 4 +- .../org/apache/iotdb/util/MagicUtils.java | 53 +++--- .../confignode/manager/ProcedureManager.java | 2 +- .../region/ReconstructRegionProcedure.java | 3 +- 12 files changed, 286 insertions(+), 90 deletions(-) create mode 100644 integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/IoTDB_RegionGroupExpandAndShrink_IoTV1_IT.java rename integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/{iotv2 => }/batch/IoTDBRegionMigrateNormalITForIoTV2Batch.java (99%) rename integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/{iotv2 => }/batch/IoTDBRegionMigrateOtherITForIoTV2Batch.java (99%) rename integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/{iotv2 => }/stream/IoTDBRegionMigrateNormalITForIoTV2Stream.java (99%) rename integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/{iotv2 => }/stream/IoTDBRegionMigrateOtherITForIoTV2Stream.java (99%) diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java index 99f5883e114d..442fb4248e78 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java @@ -21,6 +21,7 @@ import org.apache.iotdb.common.rpc.thrift.TConsensusGroupType; import org.apache.iotdb.commons.client.sync.SyncConfigNodeIServiceClient; +import org.apache.iotdb.commons.cluster.RegionStatus; import org.apache.iotdb.commons.concurrent.IoTDBThreadPoolFactory; import org.apache.iotdb.commons.conf.IoTDBConstant; import org.apache.iotdb.commons.schema.column.ColumnHeaderConstant; @@ -36,10 +37,8 @@ import org.apache.iotdb.it.env.cluster.node.AbstractNodeWrapper; import org.apache.iotdb.it.env.cluster.node.ConfigNodeWrapper; import org.apache.iotdb.it.env.cluster.node.DataNodeWrapper; -import org.apache.iotdb.itbase.exception.InconsistentDataException; import org.apache.iotdb.metrics.utils.SystemType; -import org.apache.iotdb.util.MagicUtils; import org.apache.thrift.TException; import org.awaitility.Awaitility; import org.awaitility.core.ConditionTimeoutException; @@ -73,16 +72,19 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Consumer; +import java.util.function.Predicate; import java.util.stream.Collectors; +import static org.apache.iotdb.util.MagicUtils.makeItCloseQuietly; + public class IoTDBRegionOperationReliabilityITFramework { private static final Logger LOGGER = LoggerFactory.getLogger(IoTDBRegionOperationReliabilityITFramework.class); - private static final String INSERTION1 = + public static final String INSERTION1 = "INSERT INTO root.sg.d1(timestamp,speed,temperature) values(100, 1, 2)"; private static final String INSERTION2 = "INSERT INTO root.sg.d1(timestamp,speed,temperature) values(101, 3, 4)"; - private static final String FLUSH_COMMAND = "flush"; + public static final String FLUSH_COMMAND = "flush on cluster"; private static final String SHOW_REGIONS = "show regions"; private static final String SHOW_DATANODES = "show datanodes"; private static final String COUNT_TIMESERIES = "select count(*) from root.sg.**"; @@ -206,35 +208,26 @@ public void generalTestWithAllOptions( EnvFactory.getEnv().registerDataNodeKillPoints(new ArrayList<>(dataNodeKeywords)); EnvFactory.getEnv().initClusterEnvironment(configNodeNum, dataNodeNum); - try (final Connection connection = MagicUtils.makeItCloseQuietly(EnvFactory.getEnv().getConnection()); - final Statement statement = MagicUtils.makeItCloseQuietly(connection.createStatement()); - SyncConfigNodeIServiceClient client = + try (final Connection connection = makeItCloseQuietly(EnvFactory.getEnv().getConnection()); + final Statement statement = makeItCloseQuietly(connection.createStatement()); + SyncConfigNodeIServiceClient client = (SyncConfigNodeIServiceClient) EnvFactory.getEnv().getLeaderConfigNodeConnection()) { + // prepare data statement.execute(INSERTION1); + statement.execute(FLUSH_COMMAND); - ResultSet result = statement.executeQuery(SHOW_REGIONS); - Map> regionMap = getRegionMap(result); - - result = statement.executeQuery(SHOW_DATANODES); - Set allDataNodeId = new HashSet<>(); - while (result.next()) { - allDataNodeId.add(result.getInt(ColumnHeaderConstant.NODE_ID)); - } + // collect necessary information + Map> regionMap = getDataRegionMap(statement); + Set allDataNodeId = getAllDataNodes(statement); + // select region migration related DataNodes final int selectedRegion = selectRegion(regionMap); final int originalDataNode = selectOriginalDataNode(regionMap, selectedRegion); - final int destDataNode = selectDestDataNode(allDataNodeId, regionMap, selectedRegion); - + final int destDataNode = + selectDataNodeNotContainsRegion(allDataNodeId, regionMap, selectedRegion); checkRegionFileExist(originalDataNode); checkPeersExist(regionMap.get(selectedRegion), originalDataNode, selectedRegion); - try { - awaitUntilFlush(statement, originalDataNode); - } catch (ConditionTimeoutException e) { - LOGGER.error("Flush timeout:", e); - Assert.fail(); - } - // set kill points if (killNode == KillNode.ORIGINAL_DATANODE) { setDataNodeKillPoints( @@ -268,8 +261,19 @@ public void generalTestWithAllOptions( statement.execute(buildRegionMigrateCommand(selectedRegion, originalDataNode, destDataNode)); boolean success = false; + Predicate migrateRegionPredicate = + tShowRegionResp -> { + Map> newRegionMap = + getRegionMap(tShowRegionResp.getRegionInfoList()); + Set dataNodes = newRegionMap.get(selectedRegion); + return !dataNodes.contains(originalDataNode) && dataNodes.contains(destDataNode); + }; try { - awaitUntilSuccess(client, selectedRegion, originalDataNode, destDataNode); + awaitUntilSuccess( + client, + migrateRegionPredicate, + Optional.of(destDataNode), + Optional.of(originalDataNode)); success = true; } catch (ConditionTimeoutException e) { if (expectMigrateSuccess) { @@ -299,9 +303,16 @@ public void generalTestWithAllOptions( } LOGGER.info("test pass"); - } catch (InconsistentDataException ignore) { + } + } + protected Set getAllDataNodes(Statement statement) throws Exception { + ResultSet result = statement.executeQuery(SHOW_DATANODES); + Set allDataNodeId = new HashSet<>(); + while (result.next()) { + allDataNodeId.add(result.getInt(ColumnHeaderConstant.NODE_ID)); } + return allDataNodeId; } private void setConfigNodeKillPoints( @@ -418,8 +429,8 @@ private static String buildRegionMigrateCommand(int who, int from, int to) { return result; } - public static Map> getRegionMap(ResultSet showRegionsResult) - throws SQLException { + public static Map> getDataRegionMap(Statement statement) throws Exception { + ResultSet showRegionsResult = statement.executeQuery(SHOW_REGIONS); Map> regionMap = new HashMap<>(); while (showRegionsResult.next()) { if (String.valueOf(TConsensusGroupType.DataRegion) @@ -432,7 +443,18 @@ public static Map> getRegionMap(ResultSet showRegionsResul return regionMap; } - private static Map> getRegionMap(List regionInfoList) { + public static Map> getAllRegionMap(Statement statement) throws Exception { + ResultSet showRegionsResult = statement.executeQuery(SHOW_REGIONS); + Map> regionMap = new HashMap<>(); + while (showRegionsResult.next()) { + int regionId = showRegionsResult.getInt(ColumnHeaderConstant.REGION_ID); + int dataNodeId = showRegionsResult.getInt(ColumnHeaderConstant.DATA_NODE_ID); + regionMap.computeIfAbsent(regionId, id -> new HashSet<>()).add(dataNodeId); + } + return regionMap; + } + + protected static Map> getRegionMap(List regionInfoList) { Map> regionMap = new HashMap<>(); regionInfoList.forEach( regionInfo -> { @@ -444,7 +466,22 @@ private static Map> getRegionMap(List regionI return regionMap; } - private static int selectRegion(Map> regionMap) { + protected static Map> getRunningRegionMap( + List regionInfoList) { + Map> regionMap = new HashMap<>(); + regionInfoList.stream() + .filter(regionInfo -> RegionStatus.Running.getStatus().equals(regionInfo.getStatus())) + .forEach( + regionInfo -> { + int regionId = regionInfo.getConsensusGroupId().getId(); + regionMap + .computeIfAbsent(regionId, regionId1 -> new HashSet<>()) + .add(regionInfo.getDataNodeId()); + }); + return regionMap; + } + + protected static int selectRegion(Map> regionMap) { return regionMap.keySet().stream().findAny().orElseThrow(() -> new RuntimeException("gg")); } @@ -455,7 +492,7 @@ private static int selectOriginalDataNode( .orElseThrow(() -> new RuntimeException("cannot find original DataNode")); } - private static int selectDestDataNode( + protected static int selectDataNodeNotContainsRegion( Set dataNodeSet, Map> regionMap, int selectedRegion) { return dataNodeSet.stream() .filter(dataNodeId -> !regionMap.get(selectedRegion).contains(dataNodeId)) @@ -463,7 +500,16 @@ private static int selectDestDataNode( .orElseThrow(() -> new RuntimeException("cannot find dest DataNode")); } - private static void awaitUntilFlush(Statement statement, int originalDataNode) { + protected static int selectDataNodeContainsRegion( + Set dataNodeSet, Map> regionMap, int selectedRegion) { + return dataNodeSet.stream() + .filter(dataNodeId -> regionMap.get(selectedRegion).contains(dataNodeId)) + .findAny() + .orElseThrow(() -> new RuntimeException("cannot find dest DataNode")); + } + + // I believe this function is not necessary, just keep it here in case it's necessary + private static void awaitUntilFlush(Statement statement, int originalDataNode) throws Exception { long startTime = System.currentTimeMillis(); File sequence = new File(buildDataPath(originalDataNode, true)); File unsequence = new File(buildDataPath(originalDataNode, false)); @@ -486,11 +532,11 @@ private static void awaitUntilFlush(Statement statement, int originalDataNode) { LOGGER.info("Flush cost time: {}ms", System.currentTimeMillis() - startTime); } - private static void awaitUntilSuccess( + protected static void awaitUntilSuccess( SyncConfigNodeIServiceClient client, - int selectedRegion, - int originalDataNode, - int destDataNode) { + Predicate predicate, + Optional dataNodeExpectInRegionGroup, + Optional dataNodeExpectNotInRegionGroup) { AtomicReference> lastTimeDataNodes = new AtomicReference<>(); AtomicReference lastException = new AtomicReference<>(); AtomicReference clientRef = new AtomicReference<>(client); @@ -502,10 +548,7 @@ private static void awaitUntilSuccess( () -> { try { TShowRegionResp resp = clientRef.get().showRegion(new TShowRegionReq()); - Map> newRegionMap = getRegionMap(resp.getRegionInfoList()); - Set dataNodes = newRegionMap.get(selectedRegion); - lastTimeDataNodes.set(dataNodes); - return !dataNodes.contains(originalDataNode) && dataNodes.contains(destDataNode); + return predicate.test(resp); } catch (TException e) { clientRef.set( (SyncConfigNodeIServiceClient) @@ -526,8 +569,8 @@ private static void awaitUntilSuccess( throw e; } String actualSetStr = lastTimeDataNodes.get().toString(); - lastTimeDataNodes.get().remove(originalDataNode); - lastTimeDataNodes.get().add(destDataNode); + dataNodeExpectNotInRegionGroup.ifPresent(x -> lastTimeDataNodes.get().remove(x)); + dataNodeExpectInRegionGroup.ifPresent(x -> lastTimeDataNodes.get().add(x)); String expectSetStr = lastTimeDataNodes.toString(); LOGGER.error("DataNode Set {} is unexpected, expect {}", actualSetStr, expectSetStr); if (lastException.get() == null) { @@ -700,5 +743,4 @@ protected static > KeySetView buildSet(T... k Arrays.stream(keywords).map(KillPoint::enumToString).collect(Collectors.toList())); return result; } - } diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/IoTDB_RegionGroupExpandAndShrink_IoTV1_IT.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/IoTDB_RegionGroupExpandAndShrink_IoTV1_IT.java new file mode 100644 index 000000000000..9f2898010dbd --- /dev/null +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/IoTDB_RegionGroupExpandAndShrink_IoTV1_IT.java @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.iotdb.confignode.it.regionmigration.pass.commit; + +import org.apache.iotdb.commons.client.sync.SyncConfigNodeIServiceClient; +import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework; +import org.apache.iotdb.confignode.rpc.thrift.TShowRegionResp; +import org.apache.iotdb.consensus.ConsensusFactory; +import org.apache.iotdb.it.env.EnvFactory; +import org.apache.iotdb.it.framework.IoTDBTestRunner; +import org.apache.iotdb.itbase.category.ClusterIT; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Connection; +import java.sql.Statement; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Predicate; + +import static org.apache.iotdb.util.MagicUtils.makeItCloseQuietly; + +@Category({ClusterIT.class}) +@RunWith(IoTDBTestRunner.class) +public class IoTDB_RegionGroupExpandAndShrink_IoTV1_IT + extends IoTDBRegionOperationReliabilityITFramework { + private static final String EXPAND_FORMAT = "extend region %d to %d"; + private static final String SHRINK_FORMAT = "remove region %d from %d"; + + private static Logger LOGGER = + LoggerFactory.getLogger(IoTDB_RegionGroupExpandAndShrink_IoTV1_IT.class); + + /** + * 1. Expand: {a} -> {a,b} -> ... -> {a,b,c,d,e} + * + *

2. Check + * + *

3. Shrink: {a,b,c,d,e} -> {a,c,d,e} -> ... -> {d} + * + *

4. Check + */ + @Test + public void normal1C5DTest() throws Exception { + EnvFactory.getEnv() + .getConfig() + .getCommonConfig() + .setDataRegionConsensusProtocolClass(ConsensusFactory.IOT_CONSENSUS_V2) + .setDataReplicationFactor(1) + .setSchemaReplicationFactor(1); + + EnvFactory.getEnv().initClusterEnvironment(1, 5); + + try (final Connection connection = makeItCloseQuietly(EnvFactory.getEnv().getConnection()); + final Statement statement = makeItCloseQuietly(connection.createStatement()); + SyncConfigNodeIServiceClient client = + (SyncConfigNodeIServiceClient) EnvFactory.getEnv().getLeaderConfigNodeConnection()) { + // prepare data + statement.execute(INSERTION1); + statement.execute(FLUSH_COMMAND); + + // collect necessary information + Map> regionMap = getAllRegionMap(statement); + Set allDataNodeId = getAllDataNodes(statement); + + // expect one data region, one schema region + Assert.assertEquals(2, regionMap.size()); + + // expand + for (int selectedRegion : regionMap.keySet()) { + for (int i = 0; i < 4; i++) { + int targetDataNode = + selectDataNodeNotContainsRegion(allDataNodeId, regionMap, selectedRegion); + regionGroupExpand(statement, client, selectedRegion, targetDataNode); + // update regionMap every time + regionMap = getAllRegionMap(statement); + } + } + + // shrink + for (int selectedRegion : regionMap.keySet()) { + for (int i = 0; i < 4; i++) { + int targetDataNode = + selectDataNodeContainsRegion(allDataNodeId, regionMap, selectedRegion); + regionGroupShrink(statement, client, selectedRegion, targetDataNode); + // update regionMap every time + regionMap = getAllRegionMap(statement); + } + } + } + } + + private void regionGroupExpand( + Statement statement, + SyncConfigNodeIServiceClient client, + int selectedRegion, + int targetDataNode) + throws Exception { + statement.execute(String.format(EXPAND_FORMAT, selectedRegion, targetDataNode)); + + Predicate expandRegionPredicate = + tShowRegionResp -> { + Map> newRegionMap = + getRunningRegionMap(tShowRegionResp.getRegionInfoList()); + Set dataNodes = newRegionMap.get(selectedRegion); + return dataNodes.contains(targetDataNode); + }; + + awaitUntilSuccess(client, expandRegionPredicate, Optional.of(targetDataNode), Optional.empty()); + + LOGGER.info("Region {} has expanded to DataNode {}", selectedRegion, targetDataNode); + } + + private void regionGroupShrink( + Statement statement, + SyncConfigNodeIServiceClient client, + int selectedRegion, + int targetDataNode) + throws Exception { + statement.execute(String.format(SHRINK_FORMAT, selectedRegion, targetDataNode)); + + Predicate shrinkRegionPredicate = + tShowRegionResp -> { + Map> newRegionMap = + getRegionMap(tShowRegionResp.getRegionInfoList()); + Set dataNodes = newRegionMap.get(selectedRegion); + return !dataNodes.contains(targetDataNode); + }; + + awaitUntilSuccess(client, shrinkRegionPredicate, Optional.empty(), Optional.of(targetDataNode)); + + LOGGER.info("Region {} has shrunk from DataNode {}", selectedRegion, targetDataNode); + } +} diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/batch/IoTDBRegionMigrateNormalITForIoTV2Batch.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/batch/IoTDBRegionMigrateNormalITForIoTV2Batch.java similarity index 99% rename from integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/batch/IoTDBRegionMigrateNormalITForIoTV2Batch.java rename to integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/batch/IoTDBRegionMigrateNormalITForIoTV2Batch.java index 8527591f35f9..1b1c6edaaad2 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/batch/IoTDBRegionMigrateNormalITForIoTV2Batch.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/batch/IoTDBRegionMigrateNormalITForIoTV2Batch.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.iotdb.confignode.it.regionmigration.pass.commit.iotv2.batch; +package org.apache.iotdb.confignode.it.regionmigration.pass.commit.batch; import org.apache.iotdb.commons.utils.KillPoint.KillNode; import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework; diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/batch/IoTDBRegionMigrateOtherITForIoTV2Batch.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/batch/IoTDBRegionMigrateOtherITForIoTV2Batch.java similarity index 99% rename from integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/batch/IoTDBRegionMigrateOtherITForIoTV2Batch.java rename to integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/batch/IoTDBRegionMigrateOtherITForIoTV2Batch.java index 5051011ca798..e18f0140e0ee 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/batch/IoTDBRegionMigrateOtherITForIoTV2Batch.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/batch/IoTDBRegionMigrateOtherITForIoTV2Batch.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.iotdb.confignode.it.regionmigration.pass.commit.iotv2.batch; +package org.apache.iotdb.confignode.it.regionmigration.pass.commit.batch; import org.apache.iotdb.commons.utils.KillPoint.KillNode; import org.apache.iotdb.commons.utils.KillPoint.NeverTriggeredKillPoint; diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/stream/IoTDBRegionMigrateNormalITForIoTV2Stream.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/stream/IoTDBRegionMigrateNormalITForIoTV2Stream.java similarity index 99% rename from integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/stream/IoTDBRegionMigrateNormalITForIoTV2Stream.java rename to integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/stream/IoTDBRegionMigrateNormalITForIoTV2Stream.java index 73651762e14d..095002a214d6 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/stream/IoTDBRegionMigrateNormalITForIoTV2Stream.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/stream/IoTDBRegionMigrateNormalITForIoTV2Stream.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.iotdb.confignode.it.regionmigration.pass.commit.iotv2.stream; +package org.apache.iotdb.confignode.it.regionmigration.pass.commit.stream; import org.apache.iotdb.commons.utils.KillPoint.KillNode; import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework; diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/stream/IoTDBRegionMigrateOtherITForIoTV2Stream.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/stream/IoTDBRegionMigrateOtherITForIoTV2Stream.java similarity index 99% rename from integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/stream/IoTDBRegionMigrateOtherITForIoTV2Stream.java rename to integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/stream/IoTDBRegionMigrateOtherITForIoTV2Stream.java index a4a159e3d40a..a246aac8327e 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/iotv2/stream/IoTDBRegionMigrateOtherITForIoTV2Stream.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/stream/IoTDBRegionMigrateOtherITForIoTV2Stream.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.iotdb.confignode.it.regionmigration.pass.commit.iotv2.stream; +package org.apache.iotdb.confignode.it.regionmigration.pass.commit.stream; import org.apache.iotdb.commons.utils.KillPoint.KillNode; import org.apache.iotdb.commons.utils.KillPoint.NeverTriggeredKillPoint; diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/removedatanode/IoTDBRemoveDataNodeITFramework.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/removedatanode/IoTDBRemoveDataNodeITFramework.java index 87052a99c4af..8ae9cdba714a 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/removedatanode/IoTDBRemoveDataNodeITFramework.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/removedatanode/IoTDBRemoveDataNodeITFramework.java @@ -51,8 +51,8 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; +import static org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework.getDataRegionMap; import static org.apache.iotdb.util.MagicUtils.makeItCloseQuietly; -import static org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework.getRegionMap; public class IoTDBRemoveDataNodeITFramework { private static final Logger LOGGER = @@ -144,15 +144,14 @@ public void testRemoveDataNode( EnvFactory.getEnv().initClusterEnvironment(configNodeNum, dataNodeNum); try (final Connection connection = makeItCloseQuietly(EnvFactory.getEnv().getConnection()); - final Statement statement = makeItCloseQuietly(connection.createStatement()); - SyncConfigNodeIServiceClient client = + final Statement statement = makeItCloseQuietly(connection.createStatement()); + SyncConfigNodeIServiceClient client = (SyncConfigNodeIServiceClient) EnvFactory.getEnv().getLeaderConfigNodeConnection()) { // Insert data statement.execute(INSERTION1); - ResultSet result = statement.executeQuery(SHOW_REGIONS); - Map> regionMap = getRegionMap(result); + Map> regionMap = getDataRegionMap(statement); regionMap.forEach( (key, valueSet) -> { LOGGER.info("Key: {}, Value: {}", key, valueSet); @@ -162,7 +161,7 @@ public void testRemoveDataNode( }); // Get all data nodes - result = statement.executeQuery(SHOW_DATANODES); + ResultSet result = statement.executeQuery(SHOW_DATANODES); Set allDataNodeId = new HashSet<>(); while (result.next()) { allDataNodeId.add(result.getInt(ColumnHeaderConstant.NODE_ID)); @@ -239,11 +238,10 @@ public void testRemoveDataNode( } try (final Connection connection = makeItCloseQuietly(EnvFactory.getEnv().getConnection()); - final Statement statement = makeItCloseQuietly(connection.createStatement())) { + final Statement statement = makeItCloseQuietly(connection.createStatement())) { // Check the data region distribution after removing data nodes - ResultSet result = statement.executeQuery(SHOW_REGIONS); - Map> afterRegionMap = getRegionMap(result); + Map> afterRegionMap = getDataRegionMap(statement); afterRegionMap.forEach( (key, valueSet) -> { LOGGER.info("Key: {}, Value: {}", key, valueSet); @@ -253,7 +251,7 @@ public void testRemoveDataNode( }); if (rejoinRemovedDataNode) { - result = statement.executeQuery(SHOW_DATANODES); + ResultSet result = statement.executeQuery(SHOW_DATANODES); Set allDataNodeId = new HashSet<>(); while (result.next()) { allDataNodeId.add(result.getInt(ColumnHeaderConstant.NODE_ID)); diff --git a/integration-test/src/test/java/org/apache/iotdb/pipe/it/autocreate/IoTDBPipeAutoDropIT.java b/integration-test/src/test/java/org/apache/iotdb/pipe/it/autocreate/IoTDBPipeAutoDropIT.java index f131f7d2c130..adff5e5f53da 100644 --- a/integration-test/src/test/java/org/apache/iotdb/pipe/it/autocreate/IoTDBPipeAutoDropIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/pipe/it/autocreate/IoTDBPipeAutoDropIT.java @@ -94,7 +94,7 @@ public void testAutoDropInHistoricalTransfer() throws Exception { Collections.singleton("1,")); try (final Connection connection = makeItCloseQuietly(senderEnv.getConnection()); - final Statement statement = makeItCloseQuietly(connection.createStatement()); ) { + final Statement statement = makeItCloseQuietly(connection.createStatement()); ) { ResultSet result = statement.executeQuery("show pipes"); await() .pollInSameThread() @@ -169,7 +169,7 @@ public void testAutoDropInHistoricalTransferWithTimeRange() throws Exception { Collections.singleton("3,")); try (final Connection connection = makeItCloseQuietly(senderEnv.getConnection()); - final Statement statement = makeItCloseQuietly(connection.createStatement()); ) { + final Statement statement = makeItCloseQuietly(connection.createStatement()); ) { ResultSet result = statement.executeQuery("show pipes"); await() .pollInSameThread() diff --git a/integration-test/src/test/java/org/apache/iotdb/pipe/it/tablemodel/IoTDBPipeAutoDropIT.java b/integration-test/src/test/java/org/apache/iotdb/pipe/it/tablemodel/IoTDBPipeAutoDropIT.java index 95d944242066..8f19b7f32a7f 100644 --- a/integration-test/src/test/java/org/apache/iotdb/pipe/it/tablemodel/IoTDBPipeAutoDropIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/pipe/it/tablemodel/IoTDBPipeAutoDropIT.java @@ -106,7 +106,7 @@ public void testAutoDropInHistoricalTransfer() throws Exception { } try (final Connection connection = makeItCloseQuietly(senderEnv.getConnection()); - final Statement statement = makeItCloseQuietly(connection.createStatement()); ) { + final Statement statement = makeItCloseQuietly(connection.createStatement()); ) { ResultSet result = statement.executeQuery("show pipes"); await() .pollInSameThread() @@ -188,7 +188,7 @@ public void testAutoDropInHistoricalTransferWithTimeRange() throws Exception { } try (final Connection connection = makeItCloseQuietly(senderEnv.getConnection()); - final Statement statement = makeItCloseQuietly(connection.createStatement()); ) { + final Statement statement = makeItCloseQuietly(connection.createStatement()); ) { ResultSet result = statement.executeQuery("show pipes"); await() .pollInSameThread() diff --git a/integration-test/src/test/java/org/apache/iotdb/util/MagicUtils.java b/integration-test/src/test/java/org/apache/iotdb/util/MagicUtils.java index 0adf40f7590f..e6213a72b71b 100644 --- a/integration-test/src/test/java/org/apache/iotdb/util/MagicUtils.java +++ b/integration-test/src/test/java/org/apache/iotdb/util/MagicUtils.java @@ -28,33 +28,34 @@ public class MagicUtils { - private static Logger LOGGER = LoggerFactory.getLogger(MagicUtils.class); + private static Logger LOGGER = LoggerFactory.getLogger(MagicUtils.class); - /** - * Ignore all exceptions during close() - * @param t target object - * @return object which will close without exception - */ - public static T makeItCloseQuietly(T t) { - InvocationHandler handler = - (proxy, method, args) -> { - try { - if (method.getName().equals("close")) { - try { - method.invoke(t, args); - } catch (Throwable e) { - LOGGER.warn("Exception happens during close(): ", e); - } - return null; - } else { - return method.invoke(t, args); + /** + * Ignore all exceptions during close() + * + * @param t target object + * @return object which will close without exception + */ + public static T makeItCloseQuietly(T t) { + InvocationHandler handler = + (proxy, method, args) -> { + try { + if (method.getName().equals("close")) { + try { + method.invoke(t, args); + } catch (Throwable e) { + LOGGER.warn("Exception happens during close(): ", e); } - } catch (InvocationTargetException e) { - throw e.getTargetException(); + return null; + } else { + return method.invoke(t, args); } - }; - return (T) - Proxy.newProxyInstance( - t.getClass().getClassLoader(), t.getClass().getInterfaces(), handler); - } + } catch (InvocationTargetException e) { + throw e.getTargetException(); + } + }; + return (T) + Proxy.newProxyInstance( + t.getClass().getClassLoader(), t.getClass().getInterfaces(), handler); + } } diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java index 500c309b7d49..3b0d3da9613f 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ProcedureManager.java @@ -77,9 +77,9 @@ import org.apache.iotdb.confignode.procedure.impl.region.AddRegionPeerProcedure; import org.apache.iotdb.confignode.procedure.impl.region.CreateRegionGroupsProcedure; import org.apache.iotdb.confignode.procedure.impl.region.ReconstructRegionProcedure; -import org.apache.iotdb.confignode.procedure.impl.region.RegionOperationProcedure; import org.apache.iotdb.confignode.procedure.impl.region.RegionMigrateProcedure; import org.apache.iotdb.confignode.procedure.impl.region.RegionMigrationPlan; +import org.apache.iotdb.confignode.procedure.impl.region.RegionOperationProcedure; import org.apache.iotdb.confignode.procedure.impl.region.RemoveRegionPeerProcedure; import org.apache.iotdb.confignode.procedure.impl.schema.AlterLogicalViewProcedure; import org.apache.iotdb.confignode.procedure.impl.schema.DeactivateTemplateProcedure; diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/ReconstructRegionProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/ReconstructRegionProcedure.java index 5b36788a712a..e3ea34718870 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/ReconstructRegionProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/region/ReconstructRegionProcedure.java @@ -40,8 +40,7 @@ import java.io.IOException; import java.nio.ByteBuffer; -public class ReconstructRegionProcedure - extends RegionOperationProcedure { +public class ReconstructRegionProcedure extends RegionOperationProcedure { private static final Logger LOGGER = LoggerFactory.getLogger(ReconstructRegionProcedure.class); private TDataNodeLocation targetDataNode; From c79dd8526a6987a86331d536fc11ca5d37d19ffa Mon Sep 17 00:00:00 2001 From: liyuheng Date: Tue, 7 Jan 2025 12:03:33 +0800 Subject: [PATCH 11/13] add reconstruct IT --- .../org/apache/iotdb/it/env/EnvFactory.java | 5 ++++ .../iotdb/it/env/cluster/env/AbstractEnv.java | 4 ++++ .../it/env/cluster/node/AINodeWrapper.java | 5 ++++ .../env/cluster/node/AbstractNodeWrapper.java | 11 +++++++++ .../env/cluster/node/ConfigNodeWrapper.java | 5 ++++ .../it/env/cluster/node/DataNodeWrapper.java | 5 ++++ ...RegionOperationReliabilityITFramework.java | 23 +++++++++++++++++++ ...B_RegionGroupExpandAndShrink_IoTV1_IT.java | 3 ++- 8 files changed, 60 insertions(+), 1 deletion(-) diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/EnvFactory.java b/integration-test/src/main/java/org/apache/iotdb/it/env/EnvFactory.java index ce8046708a87..a71e4e7a3aee 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/EnvFactory.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/EnvFactory.java @@ -20,6 +20,7 @@ package org.apache.iotdb.it.env; import org.apache.iotdb.it.env.cluster.env.AIEnv; +import org.apache.iotdb.it.env.cluster.env.AbstractEnv; import org.apache.iotdb.it.env.cluster.env.Cluster1Env; import org.apache.iotdb.it.env.cluster.env.SimpleEnv; import org.apache.iotdb.it.env.remote.env.RemoteServerEnv; @@ -75,4 +76,8 @@ public static BaseEnv getEnv() { } return env; } + + public static AbstractEnv getAbstractEnv() { + return (AbstractEnv) getEnv(); + } } diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java index f675f96606ab..ccf226bafd2c 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/env/AbstractEnv.java @@ -330,6 +330,10 @@ private Map countNodeStatus(final Map nodeStat return result; } + public void checkNodeInStatus(int nodeId, NodeStatus expectation) { + checkClusterStatus(nodeStatusMap -> expectation.getStatus().equals(nodeStatusMap.get(nodeId))); + } + public void checkClusterStatusWithoutUnknown() { checkClusterStatus( nodeStatusMap -> nodeStatusMap.values().stream().noneMatch("Unknown"::equals)); diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/AINodeWrapper.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/AINodeWrapper.java index c503dfc00e7d..8da2437aed68 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/AINodeWrapper.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/AINodeWrapper.java @@ -90,6 +90,11 @@ public String getLogDirPath() { + getTimeForLogDirectory(startTime); } + @Override + String getNodeType() { + return "ainode"; + } + @Override public void start() { try { diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/AbstractNodeWrapper.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/AbstractNodeWrapper.java index c42db717a935..3316f6e9888d 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/AbstractNodeWrapper.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/AbstractNodeWrapper.java @@ -630,6 +630,17 @@ public String getNodePath() { return System.getProperty(USER_DIR) + File.separator + TARGET + File.separator + getId(); } + public String getDataPath() { + return getNodePath() + File.separator + + IoTDBConstant.DATA_FOLDER_NAME + + File.separator + + getNodeType() + + File.separator + + IoTDBConstant.DATA_FOLDER_NAME; + } + + abstract String getNodeType(); + public void dumpJVMSnapshot(String testCaseName) { JMXServiceURL url; try { diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/ConfigNodeWrapper.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/ConfigNodeWrapper.java index 2b3211fe8681..aafb3641fc1d 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/ConfigNodeWrapper.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/ConfigNodeWrapper.java @@ -139,6 +139,11 @@ protected void addStartCmdParams(final List params) { "-s")); } + @Override + String getNodeType() { + return "confignode"; + } + @Override protected void reloadMutableFields() { mutableCommonProperties.setProperty(CONFIG_NODE_CONSENSUS_PROTOCOL_CLASS, SIMPLE_CONSENSUS); diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/DataNodeWrapper.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/DataNodeWrapper.java index 127f9b331857..3df21cb42a69 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/DataNodeWrapper.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/DataNodeWrapper.java @@ -175,6 +175,11 @@ protected void addStartCmdParams(final List params) { "-s")); } + @Override + String getNodeType() { + return "datanode"; + } + @Override protected void reloadMutableFields() { mutableCommonProperties.setProperty(CONFIG_NODE_CONSENSUS_PROTOCOL_CLASS, SIMPLE_CONSENSUS); diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java index 442fb4248e78..69d82bcc6812 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java @@ -32,6 +32,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TShowRegionResp; import org.apache.iotdb.consensus.ConsensusFactory; import org.apache.iotdb.consensus.iot.IoTConsensusServerImpl; +import org.apache.iotdb.isession.SessionDataSet; import org.apache.iotdb.it.env.EnvFactory; import org.apache.iotdb.it.env.cluster.env.AbstractEnv; import org.apache.iotdb.it.env.cluster.node.AbstractNodeWrapper; @@ -39,7 +40,11 @@ import org.apache.iotdb.it.env.cluster.node.DataNodeWrapper; import org.apache.iotdb.metrics.utils.SystemType; +import org.apache.iotdb.rpc.IoTDBConnectionException; +import org.apache.iotdb.rpc.StatementExecutionException; +import org.apache.iotdb.session.Session; import org.apache.thrift.TException; +import org.apache.tsfile.read.common.Field; import org.awaitility.Awaitility; import org.awaitility.core.ConditionTimeoutException; import org.junit.After; @@ -66,6 +71,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap.KeySetView; import java.util.concurrent.ExecutorService; @@ -743,4 +749,21 @@ protected static > KeySetView buildSet(T... k Arrays.stream(keywords).map(KillPoint::enumToString).collect(Collectors.toList())); return result; } + + protected static Map getRegionStatusWithoutRunning(Session session) throws IoTDBConnectionException, StatementExecutionException { + SessionDataSet dataSet = session.executeQueryStatement("show regions"); + final int regionIdIndex = dataSet.getColumnNames().indexOf("RegionId"); + final int regionStatusIndex = dataSet.getColumnNames().indexOf("Status"); + dataSet.setFetchSize(1024); + Map result = new TreeMap<>(); + while (dataSet.hasNext()) { + List fields = dataSet.next().getFields(); + final int regionId = fields.get(regionIdIndex).getIntV(); + final String regionStatus = fields.get(regionStatusIndex).toString(); + if (!"Running".equals(regionStatus)) { + result.putIfAbsent(regionId, regionStatus); + } + } + return result; + } } diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/IoTDB_RegionGroupExpandAndShrink_IoTV1_IT.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/IoTDB_RegionGroupExpandAndShrink_IoTV1_IT.java index 9f2898010dbd..03b65994a756 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/IoTDB_RegionGroupExpandAndShrink_IoTV1_IT.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/pass/commit/IoTDB_RegionGroupExpandAndShrink_IoTV1_IT.java @@ -67,7 +67,8 @@ public void normal1C5DTest() throws Exception { EnvFactory.getEnv() .getConfig() .getCommonConfig() - .setDataRegionConsensusProtocolClass(ConsensusFactory.IOT_CONSENSUS_V2) + .setDataRegionConsensusProtocolClass(ConsensusFactory.IOT_CONSENSUS) + .setSchemaRegionConsensusProtocolClass(ConsensusFactory.RATIS_CONSENSUS) .setDataReplicationFactor(1) .setSchemaReplicationFactor(1); From 6f8cb311fbd2a7471311bfe15e6c6dedd8dbd260 Mon Sep 17 00:00:00 2001 From: liyuheng Date: Tue, 7 Jan 2025 12:24:35 +0800 Subject: [PATCH 12/13] spotless --- .../it/env/cluster/node/AbstractNodeWrapper.java | 13 +++++++------ .../IoTDBRegionOperationReliabilityITFramework.java | 5 +++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/AbstractNodeWrapper.java b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/AbstractNodeWrapper.java index 3316f6e9888d..3b6d84069819 100644 --- a/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/AbstractNodeWrapper.java +++ b/integration-test/src/main/java/org/apache/iotdb/it/env/cluster/node/AbstractNodeWrapper.java @@ -631,12 +631,13 @@ public String getNodePath() { } public String getDataPath() { - return getNodePath() + File.separator - + IoTDBConstant.DATA_FOLDER_NAME - + File.separator - + getNodeType() - + File.separator - + IoTDBConstant.DATA_FOLDER_NAME; + return getNodePath() + + File.separator + + IoTDBConstant.DATA_FOLDER_NAME + + File.separator + + getNodeType() + + File.separator + + IoTDBConstant.DATA_FOLDER_NAME; } abstract String getNodeType(); diff --git a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java index 69d82bcc6812..92cf2b877079 100644 --- a/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java +++ b/integration-test/src/test/java/org/apache/iotdb/confignode/it/regionmigration/IoTDBRegionOperationReliabilityITFramework.java @@ -39,10 +39,10 @@ import org.apache.iotdb.it.env.cluster.node.ConfigNodeWrapper; import org.apache.iotdb.it.env.cluster.node.DataNodeWrapper; import org.apache.iotdb.metrics.utils.SystemType; - import org.apache.iotdb.rpc.IoTDBConnectionException; import org.apache.iotdb.rpc.StatementExecutionException; import org.apache.iotdb.session.Session; + import org.apache.thrift.TException; import org.apache.tsfile.read.common.Field; import org.awaitility.Awaitility; @@ -750,7 +750,8 @@ protected static > KeySetView buildSet(T... k return result; } - protected static Map getRegionStatusWithoutRunning(Session session) throws IoTDBConnectionException, StatementExecutionException { + protected static Map getRegionStatusWithoutRunning(Session session) + throws IoTDBConnectionException, StatementExecutionException { SessionDataSet dataSet = session.executeQueryStatement("show regions"); final int regionIdIndex = dataSet.getColumnNames().indexOf("RegionId"); final int regionStatusIndex = dataSet.getColumnNames().indexOf("Status"); From 7e1e00a408de1a7bdbe8971d5b8a8694f506d1b0 Mon Sep 17 00:00:00 2001 From: liyuheng Date: Tue, 7 Jan 2025 14:39:27 +0800 Subject: [PATCH 13/13] fix IT --- .../iotdb/db/it/IoTDBSyntaxConventionStringLiteralIT.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBSyntaxConventionStringLiteralIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBSyntaxConventionStringLiteralIT.java index 72b40c5c9dc4..8de2d3c7e002 100644 --- a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBSyntaxConventionStringLiteralIT.java +++ b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBSyntaxConventionStringLiteralIT.java @@ -256,8 +256,7 @@ public void testIllegalFilePath() { String errorMsg1 = TSStatusCode.SQL_PARSE_ERROR.getStatusCode() - + ": Error occurred while parsing SQL to physical plan: " - + "line 1:7 mismatched input 'path' expecting STRING_LITERAL"; + + ": Error occurred while parsing SQL to physical plan: line 1:7 no viable alternative at input 'REMOVE path'"; try (Connection connection = EnvFactory.getEnv().getConnection(); Statement statement = connection.createStatement()) { statement.execute("REMOVE path");