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 c6271c134cb0..34029a0176c6 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 @@ -94,7 +94,7 @@ utilityStatement | showQueries | showDiskUsage | showCurrentTimestamp | killQuery | grantWatermarkEmbedding | revokeWatermarkEmbedding | loadConfiguration | loadTimeseries | loadFile | removeFile | unloadFile | setSqlDialect | showCurrentSqlDialect | showCurrentUser - | repairDataPartitionTable + | repairDataPartitionTable | showRepairDataPartitionTableProgress ; /** @@ -1244,6 +1244,11 @@ repairDataPartitionTable : REPAIR DATA PARTITION TABLE ; +// Show Repair Data Partition Table Progress +showRepairDataPartitionTableProgress + : SHOW REPAIR DATA PARTITION TABLE PROGRESS + ; + // Explain explain : EXPLAIN (ANALYZE VERBOSE?)? selectStatement? 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 5c5cbe4a186a..f2cf1fcb31e0 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 @@ -1203,6 +1203,10 @@ REPAIR : R E P A I R ; +PROGRESS + : P R O G R E S S + ; + SCHEMA_REPLICATION_FACTOR : S C H E M A '_' R E P L I C A T I O N '_' F A C T O R ; @@ -1399,4 +1403,4 @@ fragment V: [vV]; fragment W: [wW]; fragment X: [xX]; fragment Y: [yY]; -fragment Z: [zZ]; \ No newline at end of file +fragment Z: [zZ]; diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/sync/CnToDnSyncRequestType.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/sync/CnToDnSyncRequestType.java index 790fd637d616..ca7fc7a37b2a 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/sync/CnToDnSyncRequestType.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/sync/CnToDnSyncRequestType.java @@ -41,6 +41,7 @@ public enum CnToDnSyncRequestType { COLLECT_EARLIEST_TIMESLOTS, GENERATE_DATA_PARTITION_TABLE, GENERATE_DATA_PARTITION_TABLE_HEART_BEAT, + GET_DATA_PARTITION_TABLE_GENERATOR_PROGRESS, // PartitionCache INVALIDATE_PARTITION_CACHE, diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/sync/SyncDataNodeClientPool.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/sync/SyncDataNodeClientPool.java index b9cf775459c2..5a06719e7b4c 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/sync/SyncDataNodeClientPool.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/sync/SyncDataNodeClientPool.java @@ -150,6 +150,9 @@ private void buildActionMap() { CnToDnSyncRequestType.GENERATE_DATA_PARTITION_TABLE_HEART_BEAT, (req, client) -> client.generateDataPartitionTableHeartbeat((TGenerateDataPartitionTableReq) req)); + actionMapBuilder.put( + CnToDnSyncRequestType.GET_DATA_PARTITION_TABLE_GENERATOR_PROGRESS, + (req, client) -> client.getDataPartitionTableGeneratorProgress()); actionMap = actionMapBuilder.build(); } 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 34533362d44e..57e7499239d3 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 @@ -234,6 +234,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TShowPipePluginReq; import org.apache.iotdb.confignode.rpc.thrift.TShowPipeReq; import org.apache.iotdb.confignode.rpc.thrift.TShowPipeResp; +import org.apache.iotdb.confignode.rpc.thrift.TShowRepairDataPartitionTableProgressResp; import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionReq; import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionResp; import org.apache.iotdb.confignode.rpc.thrift.TShowTable4InformationSchemaResp; @@ -1167,6 +1168,17 @@ public TSStatus dataPartitionTableIntegrityCheck() { return partitionManager.dataPartitionTableIntegrityCheck(); } + @Override + public TShowRepairDataPartitionTableProgressResp showRepairDataPartitionTableProgress() { + TSStatus status = confirmLeader(); + if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { + return new TShowRepairDataPartitionTableProgressResp(status, "UNKNOWN", 0.0) + .setMessage(status.getMessage()); + } + + return partitionManager.showRepairDataPartitionTableProgress(); + } + private void printNewCreatedDataPartition( GetOrCreateDataPartitionPlan getOrCreateDataPartitionPlan, TDataPartitionTableResp resp) { final String lineSeparator = System.lineSeparator(); 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 4dce39a9e98f..f4bd98a1643b 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 @@ -152,6 +152,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TShowPipePluginReq; import org.apache.iotdb.confignode.rpc.thrift.TShowPipeReq; import org.apache.iotdb.confignode.rpc.thrift.TShowPipeResp; +import org.apache.iotdb.confignode.rpc.thrift.TShowRepairDataPartitionTableProgressResp; import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionReq; import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionResp; import org.apache.iotdb.confignode.rpc.thrift.TShowTable4InformationSchemaResp; @@ -479,6 +480,8 @@ TDataPartitionTableResp getOrCreateDataPartition( TSStatus dataPartitionTableIntegrityCheck(); + TShowRepairDataPartitionTableProgressResp showRepairDataPartitionTableProgress(); + /** * Get AuditLogger. * 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 3de0f4247d80..1c90036b7653 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 @@ -69,6 +69,7 @@ import org.apache.iotdb.confignode.procedure.impl.node.RemoveAINodeProcedure; import org.apache.iotdb.confignode.procedure.impl.node.RemoveConfigNodeProcedure; import org.apache.iotdb.confignode.procedure.impl.node.RemoveDataNodesProcedure; +import org.apache.iotdb.confignode.procedure.impl.partition.DataPartitionTableIntegrityCheckProcedure; import org.apache.iotdb.confignode.procedure.impl.pipe.plugin.CreatePipePluginProcedure; import org.apache.iotdb.confignode.procedure.impl.pipe.plugin.DropPipePluginProcedure; import org.apache.iotdb.confignode.procedure.impl.pipe.runtime.PipeHandleLeaderChangeProcedure; @@ -2340,6 +2341,18 @@ public boolean isExistUnfinishedProcedure( return false; } + public Optional + getUnfinishedDataPartitionTableIntegrityCheckProcedure() { + for (Procedure procedure : getExecutor().getProcedures().values()) { + if (!procedure.isFinished() + && procedure instanceof DataPartitionTableIntegrityCheckProcedure) { + return Optional.of((DataPartitionTableIntegrityCheckProcedure) procedure); + } + } + + return Optional.empty(); + } + // ====================================================== /* GET-SET Region diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/partition/PartitionManager.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/partition/PartitionManager.java index da7a19cfdb5a..77197c55832a 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/partition/PartitionManager.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/partition/PartitionManager.java @@ -89,6 +89,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TGetRegionIdReq; import org.apache.iotdb.confignode.rpc.thrift.TGetSeriesSlotListReq; import org.apache.iotdb.confignode.rpc.thrift.TGetTimeSlotListReq; +import org.apache.iotdb.confignode.rpc.thrift.TShowRepairDataPartitionTableProgressResp; import org.apache.iotdb.confignode.rpc.thrift.TTimeSlotList; import org.apache.iotdb.consensus.exception.ConsensusException; import org.apache.iotdb.mpp.rpc.thrift.TCreateDataRegionReq; @@ -541,6 +542,18 @@ public void markDataPartitionTableIntegrityCheckProcedureFinished() { dataPartitionTableIntegrityCheckProcedureRunning.set(false); } + public TShowRepairDataPartitionTableProgressResp showRepairDataPartitionTableProgress() { + return configManager + .getProcedureManager() + .getUnfinishedDataPartitionTableIntegrityCheckProcedure() + .map(procedure -> procedure.getProgress(configManager.getProcedureManager().getEnv())) + .orElseGet( + () -> + new TShowRepairDataPartitionTableProgressResp( + RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS), "IDLE", 100.0) + .setMessage("No running DataPartitionTable integrity check procedure")); + } + private TSStatus consensusWritePartitionResult(ConfigPhysicalPlan plan) { TSStatus status = getConsensusManager().confirmLeader(); if (status.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) { diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/partition/DataPartitionTableIntegrityCheckProcedure.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/partition/DataPartitionTableIntegrityCheckProcedure.java index f3d539576d4b..f25f7abfe8d4 100644 --- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/partition/DataPartitionTableIntegrityCheckProcedure.java +++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/partition/DataPartitionTableIntegrityCheckProcedure.java @@ -41,11 +41,14 @@ import org.apache.iotdb.confignode.procedure.impl.StateMachineProcedure; import org.apache.iotdb.confignode.procedure.state.DataPartitionTableIntegrityCheckProcedureState; import org.apache.iotdb.confignode.procedure.store.ProcedureType; +import org.apache.iotdb.confignode.rpc.thrift.TShowRepairDataPartitionTableProgressResp; import org.apache.iotdb.confignode.rpc.thrift.TTimeSlotList; import org.apache.iotdb.mpp.rpc.thrift.TGenerateDataPartitionTableHeartbeatResp; import org.apache.iotdb.mpp.rpc.thrift.TGenerateDataPartitionTableReq; import org.apache.iotdb.mpp.rpc.thrift.TGenerateDataPartitionTableResp; +import org.apache.iotdb.mpp.rpc.thrift.TGetDataPartitionTableGeneratorProgressResp; import org.apache.iotdb.mpp.rpc.thrift.TGetEarliestTimeslotsResp; +import org.apache.iotdb.rpc.RpcUtils; import org.apache.iotdb.rpc.TSStatusCode; import org.apache.thrift.TException; @@ -1098,4 +1101,86 @@ public void setSkipDataNodes(Set skipDataNodes) { public void setFailedDataNodes(Set failedDataNodes) { this.failedDataNodes = failedDataNodes; } + + public TShowRepairDataPartitionTableProgressResp getProgress(final ConfigNodeProcedureEnv env) { + final DataPartitionTableIntegrityCheckProcedureState currentState = getCurrentState(); + final String state = currentState == null ? "UNKNOWN" : currentState.name(); + final double progress = + currentState == null ? 0.0 : calculateProgressByState(env, currentState) * 100; + + return new TShowRepairDataPartitionTableProgressResp( + RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS), state, progress) + .setMessage(String.format("DataPartitionTable integrity check progress: %.1f%%", progress)); + } + + private double calculateProgressByState( + final ConfigNodeProcedureEnv env, + final DataPartitionTableIntegrityCheckProcedureState currentState) { + switch (currentState) { + case COLLECT_EARLIEST_TIMESLOTS: + return 0.0; + case ANALYZE_MISSING_PARTITIONS: + return 0.05; + case REQUEST_PARTITION_TABLES: + return 0.1; + case REQUEST_PARTITION_TABLES_HEART_BEAT: + return 0.1 + 0.8 * calculateDataNodeGeneratorProgress(env); + case MERGE_PARTITION_TABLES: + return 0.95; + case WRITE_PARTITION_TABLE_TO_CONSENSUS: + return 0.99; + default: + return 0.0; + } + } + + private double calculateDataNodeGeneratorProgress(final ConfigNodeProcedureEnv env) { + final LoadManager currentLoadManager = + loadManager == null ? env.getConfigManager().getLoadManager() : loadManager; + + final Set targetDataNodes = new HashSet<>(allDataNodes); + targetDataNodes.removeAll(skipDataNodes); + if (targetDataNodes.isEmpty()) { + return dataPartitionTables.isEmpty() ? 0.0 : 1.0; + } + + double progressSum = 0.0; + for (TDataNodeConfiguration dataNode : targetDataNodes) { + final int dataNodeId = dataNode.getLocation().getDataNodeId(); + if (dataPartitionTables.containsKey(dataNodeId) + || failedDataNodes.contains(dataNode) + || !NodeStatus.Running.equals(currentLoadManager.getNodeStatus(dataNodeId))) { + progressSum += 1.0; + continue; + } + + try { + Object response = + SyncDataNodeClientPool.getInstance() + .sendSyncRequestToDataNodeWithGivenRetry( + dataNode.getLocation().getInternalEndPoint(), + null, + CnToDnSyncRequestType.GET_DATA_PARTITION_TABLE_GENERATOR_PROGRESS, + MAX_RETRY_COUNT); + if (response instanceof TGetDataPartitionTableGeneratorProgressResp) { + TGetDataPartitionTableGeneratorProgressResp resp = + (TGetDataPartitionTableGeneratorProgressResp) response; + DataPartitionTableGeneratorState state = + DataPartitionTableGeneratorState.getStateByCode(resp.getErrorCode()); + if (state == DataPartitionTableGeneratorState.SUCCESS) { + progressSum += 1.0; + } else if (state == DataPartitionTableGeneratorState.IN_PROGRESS) { + progressSum += Math.max(0.0, Math.min(1.0, resp.getProgress())); + } + } + } catch (Exception e) { + LOG.warn( + "[DataPartitionIntegrity] Failed to get DataPartitionTable generation progress from DataNode[id={}]: {}", + dataNodeId, + e.getMessage()); + } + } + + return progressSum / targetDataNodes.size(); + } } 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 4dac0ea8e34e..a34cdd45d4bc 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 @@ -209,6 +209,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TShowPipeResp; import org.apache.iotdb.confignode.rpc.thrift.TShowRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TShowRegionResp; +import org.apache.iotdb.confignode.rpc.thrift.TShowRepairDataPartitionTableProgressResp; import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionReq; import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionResp; import org.apache.iotdb.confignode.rpc.thrift.TShowTTLResp; @@ -631,6 +632,11 @@ public TSStatus dataPartitionTableIntegrityCheck() { return configManager.dataPartitionTableIntegrityCheck(); } + @Override + public TShowRepairDataPartitionTableProgressResp showRepairDataPartitionTableProgress() { + return configManager.showRepairDataPartitionTableProgress(); + } + @Override public TSStatus operatePermission(final TAuthorizerReq req) { ConfigPhysicalPlanType configPhysicalPlanType = 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 613fbcf5d95d..59c381f3feef 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 @@ -167,6 +167,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TShowPipeResp; import org.apache.iotdb.confignode.rpc.thrift.TShowRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TShowRegionResp; +import org.apache.iotdb.confignode.rpc.thrift.TShowRepairDataPartitionTableProgressResp; import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionReq; import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionResp; import org.apache.iotdb.confignode.rpc.thrift.TShowTTLResp; @@ -708,6 +709,14 @@ public TSStatus dataPartitionTableIntegrityCheck() throws TException { () -> client.dataPartitionTableIntegrityCheck(), status -> !updateConfigNodeLeader(status)); } + @Override + public TShowRepairDataPartitionTableProgressResp showRepairDataPartitionTableProgress() + throws TException { + return executeRemoteCallWithRetry( + () -> client.showRepairDataPartitionTableProgress(), + resp -> !updateConfigNodeLeader(resp.status)); + } + @Override public TSStatus operatePermission(TAuthorizerReq req) throws TException { return executeRemoteCallWithRetry( diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/DataNodeInternalRPCServiceImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/DataNodeInternalRPCServiceImpl.java index 436e78906df3..48f84fc26f44 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/DataNodeInternalRPCServiceImpl.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/thrift/impl/DataNodeInternalRPCServiceImpl.java @@ -274,6 +274,7 @@ import org.apache.iotdb.mpp.rpc.thrift.TGenerateDataPartitionTableHeartbeatResp; import org.apache.iotdb.mpp.rpc.thrift.TGenerateDataPartitionTableReq; import org.apache.iotdb.mpp.rpc.thrift.TGenerateDataPartitionTableResp; +import org.apache.iotdb.mpp.rpc.thrift.TGetDataPartitionTableGeneratorProgressResp; import org.apache.iotdb.mpp.rpc.thrift.TGetEarliestTimeslotsResp; import org.apache.iotdb.mpp.rpc.thrift.TInactiveTriggerInstanceReq; import org.apache.iotdb.mpp.rpc.thrift.TInvalidateCacheReq; @@ -3397,6 +3398,52 @@ public TGenerateDataPartitionTableHeartbeatResp generateDataPartitionTableHeartb return resp; } + @Override + public TGetDataPartitionTableGeneratorProgressResp getDataPartitionTableGeneratorProgress() { + TGetDataPartitionTableGeneratorProgressResp resp = + new TGetDataPartitionTableGeneratorProgressResp(); + + if (currentGenerator == null) { + resp.setErrorCode(DataPartitionTableGeneratorState.UNKNOWN.getCode()); + resp.setProgress(0.0); + resp.setMessage("No DataPartitionTable generation task found"); + resp.setStatus(RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS)); + return resp; + } + + switch (currentGenerator.getStatus()) { + case IN_PROGRESS: + resp.setErrorCode(DataPartitionTableGeneratorState.IN_PROGRESS.getCode()); + resp.setProgress(currentGenerator.getProgress()); + resp.setMessage( + String.format( + "DataPartitionTable generation in progress: %.1f%%", + currentGenerator.getProgress() * 100)); + resp.setStatus(RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS)); + break; + case COMPLETED: + resp.setErrorCode(DataPartitionTableGeneratorState.SUCCESS.getCode()); + resp.setProgress(1.0); + resp.setMessage("DataPartitionTable generation completed successfully"); + resp.setStatus(RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS)); + break; + case FAILED: + resp.setErrorCode(DataPartitionTableGeneratorState.FAILED.getCode()); + resp.setProgress(currentGenerator.getProgress()); + resp.setMessage( + "DataPartitionTable generation failed: " + currentGenerator.getErrorMessage()); + resp.setStatus(RpcUtils.getStatus(TSStatusCode.INTERNAL_SERVER_ERROR)); + break; + default: + resp.setErrorCode(DataPartitionTableGeneratorState.UNKNOWN.getCode()); + resp.setProgress(currentGenerator.getProgress()); + resp.setMessage("Unknown task status: " + currentGenerator.getStatus()); + resp.setStatus(RpcUtils.getStatus(TSStatusCode.INTERNAL_SERVER_ERROR)); + break; + } + return resp; + } + private void parseGenerationStatus(Object resp) { if (currentGenerator == null) { return; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/DatasetHeaderFactory.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/DatasetHeaderFactory.java index 18f15eea8f39..618158d74db2 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/DatasetHeaderFactory.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/DatasetHeaderFactory.java @@ -169,6 +169,11 @@ public static DatasetHeader getShowPipeHeader() { return new DatasetHeader(ColumnHeaderConstant.showPipeColumnHeaders, true); } + public static DatasetHeader getShowRepairDataPartitionTableProgressHeader() { + return new DatasetHeader( + ColumnHeaderConstant.showRepairDataPartitionTableProgressColumnHeaders, true); + } + public static DatasetHeader getShowTopicHeader() { return new DatasetHeader(ColumnHeaderConstant.showTopicColumnHeaders, true); } 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 de090b31f489..fb20494ac5b9 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 @@ -109,6 +109,7 @@ import org.apache.iotdb.db.queryengine.plan.execution.config.sys.SetConfigurationTask; import org.apache.iotdb.db.queryengine.plan.execution.config.sys.SetSystemStatusTask; import org.apache.iotdb.db.queryengine.plan.execution.config.sys.ShowConfigurationTask; +import org.apache.iotdb.db.queryengine.plan.execution.config.sys.ShowRepairDataPartitionTableProgressTask; import org.apache.iotdb.db.queryengine.plan.execution.config.sys.StartRepairDataTask; import org.apache.iotdb.db.queryengine.plan.execution.config.sys.StopRepairDataTask; import org.apache.iotdb.db.queryengine.plan.execution.config.sys.TestConnectionTask; @@ -221,6 +222,7 @@ import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowConfigurationStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowCurrentSqlDialectStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowCurrentUserStatement; +import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowRepairDataPartitionTableProgressStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.StartRepairDataStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.StopRepairDataStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.TestConnectionStatement; @@ -392,6 +394,13 @@ public IConfigTask visitRepairDataPartitionTable( return new RepairDataPartitionTableTask(); } + @Override + public IConfigTask visitShowRepairDataPartitionTableProgress( + ShowRepairDataPartitionTableProgressStatement showRepairDataPartitionTableProgressStatement, + MPPQueryContext context) { + return new ShowRepairDataPartitionTableProgressTask(); + } + @Override public IConfigTask visitStopRepairData( StopRepairDataStatement stopRepairDataStatement, 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 ab823966de8e..f10d5cc4ea78 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 @@ -164,6 +164,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TShowPipeReq; import org.apache.iotdb.confignode.rpc.thrift.TShowRegionReq; import org.apache.iotdb.confignode.rpc.thrift.TShowRegionResp; +import org.apache.iotdb.confignode.rpc.thrift.TShowRepairDataPartitionTableProgressResp; import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionReq; import org.apache.iotdb.confignode.rpc.thrift.TShowSubscriptionResp; import org.apache.iotdb.confignode.rpc.thrift.TShowTTLResp; @@ -245,6 +246,7 @@ import org.apache.iotdb.db.queryengine.plan.execution.config.session.ShowCurrentUserTask; import org.apache.iotdb.db.queryengine.plan.execution.config.session.ShowVersionTask; import org.apache.iotdb.db.queryengine.plan.execution.config.sys.ShowConfigurationTask; +import org.apache.iotdb.db.queryengine.plan.execution.config.sys.ShowRepairDataPartitionTableProgressTask; import org.apache.iotdb.db.queryengine.plan.execution.config.sys.TestConnectionTask; import org.apache.iotdb.db.queryengine.plan.execution.config.sys.pipe.ShowPipeTask; import org.apache.iotdb.db.queryengine.plan.execution.config.sys.quota.ShowSpaceQuotaTask; @@ -1471,6 +1473,26 @@ public SettableFuture repairDataPartitionTable() { return future; } + @Override + public SettableFuture showRepairDataPartitionTableProgress() { + SettableFuture future = SettableFuture.create(); + + try (ConfigNodeClient client = + CONFIG_NODE_CLIENT_MANAGER.borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) { + TShowRepairDataPartitionTableProgressResp resp = + client.showRepairDataPartitionTableProgress(); + if (resp.getStatus().getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) { + ShowRepairDataPartitionTableProgressTask.buildTsBlock(resp, future); + } else { + future.setException(new IoTDBException(resp.getStatus())); + } + } catch (ClientManagerException | TException e) { + future.setException(e); + } + + return future; + } + @Override public SettableFuture loadConfiguration(boolean onCluster) { SettableFuture future = SettableFuture.create(); 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 b4b928ba0b61..cdd00cc7c709 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 @@ -158,6 +158,8 @@ SettableFuture showPipePlugins( SettableFuture repairDataPartitionTable(); + SettableFuture showRepairDataPartitionTableProgress(); + SettableFuture flush(TFlushReq tFlushReq, boolean onCluster); SettableFuture clearCache(boolean onCluster, Set options); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/sys/ShowRepairDataPartitionTableProgressTask.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/sys/ShowRepairDataPartitionTableProgressTask.java new file mode 100644 index 000000000000..64b929be4a31 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/sys/ShowRepairDataPartitionTableProgressTask.java @@ -0,0 +1,71 @@ +/* + * 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.sys; + +import org.apache.iotdb.confignode.rpc.thrift.TShowRepairDataPartitionTableProgressResp; +import org.apache.iotdb.db.queryengine.common.header.DatasetHeaderFactory; +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.rpc.TSStatusCode; + +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.SettableFuture; +import org.apache.tsfile.common.conf.TSFileConfig; +import org.apache.tsfile.enums.TSDataType; +import org.apache.tsfile.read.common.block.TsBlockBuilder; +import org.apache.tsfile.utils.Binary; + +import java.util.Arrays; + +public class ShowRepairDataPartitionTableProgressTask implements IConfigTask { + + public ShowRepairDataPartitionTableProgressTask() { + // Empty constructor + } + + @Override + public ListenableFuture execute(IConfigTaskExecutor configTaskExecutor) + throws InterruptedException { + return configTaskExecutor.showRepairDataPartitionTableProgress(); + } + + public static void buildTsBlock( + TShowRepairDataPartitionTableProgressResp resp, SettableFuture future) { + TsBlockBuilder builder = + new TsBlockBuilder(Arrays.asList(TSDataType.TEXT, TSDataType.DOUBLE, TSDataType.TEXT)); + + builder.getTimeColumnBuilder().writeLong(0L); + builder + .getColumnBuilder(0) + .writeBinary(new Binary(resp.getState(), TSFileConfig.STRING_CHARSET)); + builder.getColumnBuilder(1).writeDouble(resp.getProgress()); + builder + .getColumnBuilder(2) + .writeBinary(new Binary(resp.getMessage(), TSFileConfig.STRING_CHARSET)); + builder.declarePosition(); + + future.set( + new ConfigTaskResult( + TSStatusCode.SUCCESS_STATUS, + builder.build(), + DatasetHeaderFactory.getShowRepairDataPartitionTableProgressHeader())); + } +} 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 28e935d5047a..553a7b3c6862 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 @@ -249,6 +249,7 @@ import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowCurrentUserStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowDiskUsageStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowQueriesStatement; +import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowRepairDataPartitionTableProgressStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowVersionStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.StartRepairDataStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.StopRepairDataStatement; @@ -3765,6 +3766,12 @@ public Statement visitRepairDataPartitionTable( return new RepairDataPartitionTable(); } + @Override + public Statement visitShowRepairDataPartitionTableProgress( + IoTDBSqlParser.ShowRepairDataPartitionTableProgressContext ctx) { + return new ShowRepairDataPartitionTableProgressStatement(); + } + // Stop Repair Data @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java index 7b4655c79a84..4c0966907dec 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/TreeAccessCheckVisitor.java @@ -156,6 +156,7 @@ import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowCurrentUserStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowDiskUsageStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowQueriesStatement; +import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowRepairDataPartitionTableProgressStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowVersionStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.StartRepairDataStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.StopRepairDataStatement; @@ -1692,6 +1693,16 @@ public TSStatus visitRepairDataPartitionTable( AuditEventType.INTEGRITY_CHECK); } + @Override + public TSStatus visitShowRepairDataPartitionTableProgress( + ShowRepairDataPartitionTableProgressStatement showRepairDataPartitionTableProgressStatement, + TreeAccessCheckContext context) { + return checkGlobalAuth( + context.setAuditLogOperation(AuditLogOperation.DDL), + PrivilegeType.SYSTEM, + AuditEventType.INTEGRITY_CHECK); + } + @Override public TSStatus visitStopRepairData( StopRepairDataStatement stopRepairDataStatement, TreeAccessCheckContext context) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/StatementType.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/StatementType.java index b40c6444816f..8003d2303097 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/StatementType.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/StatementType.java @@ -182,6 +182,7 @@ public enum StatementType { START_REPAIR_DATA, STOP_REPAIR_DATA, REPAIR_DATA_PARTITION_TABLE, + SHOW_REPAIR_DATA_PARTITION_TABLE_PROGRESS, CREATE_TOPIC, DROP_TOPIC, 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 847e850c5217..ada88e151e4a 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 @@ -147,6 +147,7 @@ import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowCurrentUserStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowDiskUsageStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowQueriesStatement; +import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowRepairDataPartitionTableProgressStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.ShowVersionStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.StartRepairDataStatement; import org.apache.iotdb.db.queryengine.plan.statement.sys.StopRepairDataStatement; @@ -526,6 +527,12 @@ public R visitRepairDataPartitionTable( return visitStatement(repairDataPartitionTable, context); } + public R visitShowRepairDataPartitionTableProgress( + ShowRepairDataPartitionTableProgressStatement showRepairDataPartitionTableProgressStatement, + C context) { + return visitStatement(showRepairDataPartitionTableProgressStatement, context); + } + public R visitLoadConfiguration( LoadConfigurationStatement loadConfigurationStatement, C context) { return visitStatement(loadConfigurationStatement, context); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/sys/ShowRepairDataPartitionTableProgressStatement.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/sys/ShowRepairDataPartitionTableProgressStatement.java new file mode 100644 index 000000000000..9de4d4ccca32 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/sys/ShowRepairDataPartitionTableProgressStatement.java @@ -0,0 +1,53 @@ +/* + * 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.sys; + +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.StatementType; +import org.apache.iotdb.db.queryengine.plan.statement.StatementVisitor; + +import java.util.Collections; +import java.util.List; + +public class ShowRepairDataPartitionTableProgressStatement extends Statement + implements IConfigStatement { + + public ShowRepairDataPartitionTableProgressStatement() { + this.statementType = StatementType.SHOW_REPAIR_DATA_PARTITION_TABLE_PROGRESS; + } + + @Override + public List getPaths() { + return Collections.emptyList(); + } + + @Override + public QueryType getQueryType() { + return QueryType.READ; + } + + @Override + public R accept(StatementVisitor visitor, C context) { + return visitor.visitShowRepairDataPartitionTableProgress(this, context); + } +} diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/parser/StatementGeneratorTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/parser/StatementGeneratorTest.java index b98f34a2484d..3aeb8c3fa4b2 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/parser/StatementGeneratorTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/parser/StatementGeneratorTest.java @@ -1040,6 +1040,14 @@ public void testCreateView() throws IllegalPathException { assertEquals(null, stmt.getQueryStatement()); } + @Test + public void testShowRepairDataPartitionTableProgress() { + Statement statement = + StatementGenerator.createStatement( + "SHOW REPAIR DATA PARTITION TABLE PROGRESS;", ZonedDateTime.now().getOffset()); + assertEquals(StatementType.SHOW_REPAIR_DATA_PARTITION_TABLE_PROGRESS, statement.getType()); + } + // TODO: add more tests private void checkQueryStatement( diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/column/ColumnHeaderConstant.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/column/ColumnHeaderConstant.java index 186f7daa6846..dad585e7c6d9 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/column/ColumnHeaderConstant.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/column/ColumnHeaderConstant.java @@ -197,6 +197,11 @@ private ColumnHeaderConstant() { public static final String REMAINING_EVENT_COUNT = "RemainingEventCount"; public static final String ESTIMATED_REMAINING_SECONDS = "EstimatedRemainingSeconds"; + // column names for show repair data partition table progress + public static final String REPAIR_DATA_PARTITION_TABLE_STATUS = "Status"; + public static final String REPAIR_DATA_PARTITION_TABLE_PROGRESS = "Progress(%)"; + public static final String REPAIR_DATA_PARTITION_TABLE_MESSAGE = "Message"; + // column names for select into public static final String SOURCE_DEVICE = "SourceDevice"; public static final String SOURCE_COLUMN = "SourceColumn"; @@ -606,6 +611,12 @@ private ColumnHeaderConstant() { new ColumnHeader(REMAINING_EVENT_COUNT, TSDataType.TEXT), new ColumnHeader(ESTIMATED_REMAINING_SECONDS, TSDataType.TEXT)); + public static final List showRepairDataPartitionTableProgressColumnHeaders = + ImmutableList.of( + new ColumnHeader(REPAIR_DATA_PARTITION_TABLE_STATUS, TSDataType.TEXT), + new ColumnHeader(REPAIR_DATA_PARTITION_TABLE_PROGRESS, TSDataType.DOUBLE), + new ColumnHeader(REPAIR_DATA_PARTITION_TABLE_MESSAGE, TSDataType.TEXT)); + public static final List showTopicColumnHeaders = ImmutableList.of( new ColumnHeader(TOPIC_NAME, TSDataType.TEXT), diff --git a/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift b/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift index 22529ffbb737..ab6e5523a892 100644 --- a/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift +++ b/iotdb-protocol/thrift-confignode/src/main/thrift/confignode.thrift @@ -274,6 +274,13 @@ struct TDataPartitionTableResp { 2: optional map>>> dataPartitionTable } +struct TShowRepairDataPartitionTableProgressResp { + 1: required common.TSStatus status + 2: required string state + 3: required double progress + 4: optional string message +} + struct TGetRegionIdReq { 1: required common.TConsensusGroupType type 2: optional string database @@ -1500,6 +1507,8 @@ service IConfigNodeRPCService { common.TSStatus dataPartitionTableIntegrityCheck() + TShowRepairDataPartitionTableProgressResp showRepairDataPartitionTableProgress() + // ====================================================== // Authorize // ====================================================== @@ -2071,4 +2080,3 @@ service IConfigNodeRPCService { common.TSStatus createTableView(TCreateTableViewReq req) } - diff --git a/iotdb-protocol/thrift-datanode/src/main/thrift/datanode.thrift b/iotdb-protocol/thrift-datanode/src/main/thrift/datanode.thrift index 92a7602b34de..8570478e6b0e 100644 --- a/iotdb-protocol/thrift-datanode/src/main/thrift/datanode.thrift +++ b/iotdb-protocol/thrift-datanode/src/main/thrift/datanode.thrift @@ -709,6 +709,13 @@ struct TGenerateDataPartitionTableHeartbeatResp { 4: optional list databaseScopedDataPartitionTables } +struct TGetDataPartitionTableGeneratorProgressResp { + 1: required common.TSStatus status + 2: required i32 errorCode + 3: required double progress + 4: optional string message +} + /** * END: Data Partition Table Integrity Check Structures **/ @@ -1343,6 +1350,11 @@ service IDataNodeRPCService { */ TGenerateDataPartitionTableHeartbeatResp generateDataPartitionTableHeartbeat(TGenerateDataPartitionTableReq req) + /** + * Get the progress of DataPartitionTable generation task without consuming the generated table. + */ + TGetDataPartitionTableGeneratorProgressResp getDataPartitionTableGeneratorProgress() + /** * END: Data Partition Table Integrity Check **/ @@ -1361,4 +1373,4 @@ service MPPDataExchangeService { /** Empty rpc, only for connection test */ common.TSStatus testConnectionEmptyRPC() -} \ No newline at end of file +}