You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by ja...@apache.org on 2023/02/09 00:39:41 UTC

[pinot] branch master updated: update an existing API to reset only segments with Error EV (#10239)

This is an automated email from the ASF dual-hosted git repository.

jackie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new a22fb68ffc update an existing API to reset only segments with Error EV (#10239)
a22fb68ffc is described below

commit a22fb68ffcfe1827efdba3055432c850647854fd
Author: Haitao Zhang <ha...@startree.ai>
AuthorDate: Wed Feb 8 16:39:35 2023 -0800

    update an existing API to reset only segments with Error EV (#10239)
---
 .../api/resources/PinotSegmentRestletResource.java | 19 ++++++++------
 .../helix/core/PinotHelixResourceManager.java      | 30 ++++++++++++++--------
 2 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotSegmentRestletResource.java b/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotSegmentRestletResource.java
index c467c3f816..750e133ddd 100644
--- a/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotSegmentRestletResource.java
+++ b/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotSegmentRestletResource.java
@@ -516,7 +516,7 @@ public class PinotSegmentRestletResource {
   @Produces(MediaType.APPLICATION_JSON)
   @ApiOperation(
       value = "Resets a segment by first disabling it, waiting for external view to stabilize, and finally enabling "
-          + "it again", notes = "Resets a segment by disabling and then enabling the segment")
+          + "it again", notes = "Resets a segment by disabling and then enabling it")
   public SuccessResponse resetSegment(
       @ApiParam(value = "Name of the table with type", required = true) @PathParam("tableNameWithType")
           String tableNameWithType,
@@ -542,7 +542,7 @@ public class PinotSegmentRestletResource {
   }
 
   /**
-   * Resets all segments of the given table
+   * Resets all segments or segments with Error state of the given table
    * This API will take segments to OFFLINE state, wait for External View to stabilize, and then back to
    * ONLINE/CONSUMING state,
    * thus effective in resetting segments or consumers in error states.
@@ -552,18 +552,21 @@ public class PinotSegmentRestletResource {
   @Produces(MediaType.APPLICATION_JSON)
   @Authenticate(AccessType.UPDATE)
   @ApiOperation(
-      value = "Resets all segments of the table, by first disabling them, waiting for external view to stabilize, and"
-          + " finally enabling the segments", notes = "Resets a segment by disabling and then enabling a segment")
-  public SuccessResponse resetAllSegments(
+      value = "Resets all segments (when errorSegmentsOnly = false) or segments with Error state (when "
+          + "errorSegmentsOnly = true) of the table, by first disabling them, waiting for external view to stabilize,"
+          + " and finally enabling them", notes = "Resets segments by disabling and then enabling them")
+  public SuccessResponse resetSegments(
       @ApiParam(value = "Name of the table with type", required = true) @PathParam("tableNameWithType")
           String tableNameWithType,
       @ApiParam(value = "Name of the target instance to reset") @QueryParam("targetInstance") @Nullable
-          String targetInstance) {
+          String targetInstance,
+      @ApiParam(value = "Whether to reset only segments with error state") @QueryParam("errorSegmentsOnly")
+      @DefaultValue("false") boolean errorSegmentsOnly) {
     TableType tableType = TableNameBuilder.getTableTypeFromTableName(tableNameWithType);
     try {
       Preconditions.checkState(tableType != null, "Must provide table name with type: %s", tableNameWithType);
-      _pinotHelixResourceManager.resetAllSegments(tableNameWithType, targetInstance);
-      return new SuccessResponse(String.format("Successfully reset all segments of table: %s", tableNameWithType));
+      _pinotHelixResourceManager.resetSegments(tableNameWithType, targetInstance, errorSegmentsOnly);
+      return new SuccessResponse(String.format("Successfully reset segments of table: %s", tableNameWithType));
     } catch (IllegalStateException e) {
       throw new ControllerApplicationException(LOGGER,
           String.format("Failed to reset segments in table: %s. %s", tableNameWithType, e.getMessage()),
diff --git a/pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/PinotHelixResourceManager.java b/pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/PinotHelixResourceManager.java
index dda6b1de23..c59c74fbb8 100644
--- a/pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/PinotHelixResourceManager.java
+++ b/pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/PinotHelixResourceManager.java
@@ -2410,8 +2410,7 @@ public class PinotHelixResourceManager {
   /**
    * Resets a segment. This operation invoke resetPartition via state transition message.
    */
-  public void resetSegment(String tableNameWithType, String segmentName, @Nullable String targetInstance)
-      throws InterruptedException, TimeoutException {
+  public void resetSegment(String tableNameWithType, String segmentName, @Nullable String targetInstance) {
     IdealState idealState = getTableIdealState(tableNameWithType);
     Preconditions.checkState(idealState != null, "Could not find ideal state for table: %s", tableNameWithType);
     ExternalView externalView = getTableExternalView(tableNameWithType);
@@ -2421,7 +2420,7 @@ public class PinotHelixResourceManager {
 
     for (String instance : instanceSet) {
       if (externalViewStateMap == null || SegmentStateModel.OFFLINE.equals(externalViewStateMap.get(instance))) {
-        LOGGER.info("Skipping reset for segment: {} of table: {} on instance: {}", segmentName, tableNameWithType,
+        LOGGER.info("Skipping resetting for segment: {} of table: {} on instance: {}", segmentName, tableNameWithType,
             instance);
       } else {
         LOGGER.info("Resetting segment: {} of table: {} on instance: {}", segmentName, tableNameWithType, instance);
@@ -2431,10 +2430,10 @@ public class PinotHelixResourceManager {
   }
 
   /**
-   * Resets all segments of a table. This operation invoke resetPartition via state transition message.
+   * Resets all segments or segments with Error state of a table. This operation invoke resetPartition via state
+   * transition message.
    */
-  public void resetAllSegments(String tableNameWithType, @Nullable String targetInstance)
-      throws InterruptedException, TimeoutException {
+  public void resetSegments(String tableNameWithType, @Nullable String targetInstance, boolean errorSegmentsOnly) {
     IdealState idealState = getTableIdealState(tableNameWithType);
     Preconditions.checkState(idealState != null, "Could not find ideal state for table: %s", tableNameWithType);
     ExternalView externalView = getTableExternalView(tableNameWithType);
@@ -2447,15 +2446,26 @@ public class PinotHelixResourceManager {
       Set<String> instanceSet = parseInstanceSet(idealState, segmentName, targetInstance);
       Map<String, String> externalViewStateMap = externalView.getStateMap(segmentName);
       for (String instance : instanceSet) {
-        if (externalViewStateMap == null || SegmentStateModel.OFFLINE.equals(externalViewStateMap.get(instance))) {
-          instanceToSkippedSegmentsMap.computeIfAbsent(instance, i -> new HashSet<>()).add(segmentName);
+        if (errorSegmentsOnly) {
+          if (externalViewStateMap != null && SegmentStateModel.ERROR.equals(externalViewStateMap.get(instance))) {
+            instanceToResetSegmentsMap.computeIfAbsent(instance, i -> new HashSet<>()).add(segmentName);
+          }
         } else {
-          instanceToResetSegmentsMap.computeIfAbsent(instance, i -> new HashSet<>()).add(segmentName);
+          if (externalViewStateMap == null || SegmentStateModel.OFFLINE.equals(externalViewStateMap.get(instance))) {
+            instanceToSkippedSegmentsMap.computeIfAbsent(instance, i -> new HashSet<>()).add(segmentName);
+          } else {
+            instanceToResetSegmentsMap.computeIfAbsent(instance, i -> new HashSet<>()).add(segmentName);
+          }
         }
       }
     }
 
-    LOGGER.info("Resetting all segments of table: {}", tableNameWithType);
+    if (instanceToResetSegmentsMap.isEmpty()) {
+      LOGGER.info("No segments to reset for table: {}", tableNameWithType);
+      return;
+    }
+
+    LOGGER.info("Resetting segments: {} of table: {}", instanceToResetSegmentsMap, tableNameWithType);
     for (Map.Entry<String, Set<String>> entry : instanceToResetSegmentsMap.entrySet()) {
       resetPartitionAllState(entry.getKey(), tableNameWithType, entry.getValue());
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org