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

zhangduo pushed a commit to branch branch-3
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-3 by this push:
     new 87ffda83826 HBASE-28151 Option to allow/disallow bypassing pre transit 
check for assing/unassign (#5493)
87ffda83826 is described below

commit 87ffda8382684a107a1c992e50c78ae48a951786
Author: Rahul Kumar <[email protected]>
AuthorDate: Sun Jan 28 00:51:49 2024 +0530

    HBASE-28151 Option to allow/disallow bypassing pre transit check for 
assing/unassign (#5493)
    
    Signed-off-by: Andrew Purtell <[email protected]>
    Signed-off-by: Viraj Jasani <[email protected]>
    Signed-off-by: Ravi Kishore Valeti <[email protected]>
    (cherry picked from commit 3b2e98192091368dc961eaef8e25c679f99aa8fd)
---
 .../org/apache/hadoop/hbase/client/HBaseHbck.java  |  9 +++--
 .../java/org/apache/hadoop/hbase/client/Hbck.java  | 43 +++++++++++++++-------
 .../hbase/shaded/protobuf/RequestConverter.java    |  8 ++--
 .../src/main/protobuf/server/master/Master.proto   |  2 +
 .../hadoop/hbase/master/MasterRpcServices.java     |  9 +++--
 .../hbase/master/assignment/AssignmentManager.java | 22 +++++++----
 .../master/procedure/TruncateRegionProcedure.java  |  4 +-
 .../org/apache/hadoop/hbase/client/TestHbck.java   | 19 +++++++++-
 .../hbase/master/assignment/TestRegionBypass.java  |  2 +-
 9 files changed, 81 insertions(+), 37 deletions(-)

diff --git 
a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseHbck.java 
b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseHbck.java
index 8df0504b2a9..83b53ccba3c 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseHbck.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseHbck.java
@@ -135,10 +135,11 @@ public class HBaseHbck implements Hbck {
   }
 
   @Override
-  public List<Long> assigns(List<String> encodedRegionNames, boolean override) 
throws IOException {
+  public List<Long> assigns(List<String> encodedRegionNames, boolean override, 
boolean force)
+    throws IOException {
     try {
       AssignsResponse response = 
this.hbck.assigns(rpcControllerFactory.newController(),
-        RequestConverter.toAssignRegionsRequest(encodedRegionNames, override));
+        RequestConverter.toAssignRegionsRequest(encodedRegionNames, override, 
force));
       return response.getPidList();
     } catch (ServiceException se) {
       LOG.debug(toCommaDelimitedString(encodedRegionNames), se);
@@ -147,11 +148,11 @@ public class HBaseHbck implements Hbck {
   }
 
   @Override
-  public List<Long> unassigns(List<String> encodedRegionNames, boolean 
override)
+  public List<Long> unassigns(List<String> encodedRegionNames, boolean 
override, boolean force)
     throws IOException {
     try {
       UnassignsResponse response = 
this.hbck.unassigns(rpcControllerFactory.newController(),
-        RequestConverter.toUnassignRegionsRequest(encodedRegionNames, 
override));
+        RequestConverter.toUnassignRegionsRequest(encodedRegionNames, 
override, force));
       return response.getPidList();
     } catch (ServiceException se) {
       LOG.debug(toCommaDelimitedString(encodedRegionNames), se);
diff --git 
a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Hbck.java 
b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Hbck.java
index b5ba2505883..6baa876f938 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Hbck.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Hbck.java
@@ -62,19 +62,26 @@ public interface Hbck extends Abortable, Closeable {
    * good if many Regions to online -- and it will schedule the assigns even 
in the case where
    * Master is initializing (as long as the ProcedureExecutor is up). Does NOT 
call Coprocessor
    * hooks.
-   * @param override           You need to add the override for case where a 
region has previously
-   *                           been bypassed. When a Procedure has been 
bypassed, a Procedure will
-   *                           have completed but no other Procedure will be 
able to make progress
-   *                           on the target entity (intentionally). This 
override flag will
-   *                           override this fencing mechanism.
+   * @param override           You need to add override for unset of the 
procedure from
+   *                           RegionStateNode without byPassing 
preTransitCheck
+   * @param force              You need to add force for case where a region 
has previously been
+   *                           bypassed. When a Procedure has been bypassed, a 
Procedure will have
+   *                           completed but no other Procedure will be able 
to make progress on the
+   *                           target entity (intentionally). Skips 
preTransitCheck only when
+   *                           selected along with override option
    * @param encodedRegionNames Region encoded names; e.g. 1588230740 is the 
hard-coded encoding for
    *                           hbase:meta region and 
de00010733901a05f5a2a3a382e27dd4 is an example
    *                           of what a random user-space encoded Region name 
looks like.
    */
-  List<Long> assigns(List<String> encodedRegionNames, boolean override) throws 
IOException;
+  List<Long> assigns(List<String> encodedRegionNames, boolean override, 
boolean force)
+    throws IOException;
+
+  default List<Long> assigns(List<String> encodedRegionNames, boolean 
override) throws IOException {
+    return assigns(encodedRegionNames, override, true);
+  }
 
   default List<Long> assigns(List<String> encodedRegionNames) throws 
IOException {
-    return assigns(encodedRegionNames, false);
+    return assigns(encodedRegionNames, false, false);
   }
 
   /**
@@ -82,19 +89,27 @@ public interface Hbck extends Abortable, Closeable {
    * at a time -- good if many Regions to offline -- and it will schedule the 
assigns even in the
    * case where Master is initializing (as long as the ProcedureExecutor is 
up). Does NOT call
    * Coprocessor hooks.
-   * @param override           You need to add the override for case where a 
region has previously
-   *                           been bypassed. When a Procedure has been 
bypassed, a Procedure will
-   *                           have completed but no other Procedure will be 
able to make progress
-   *                           on the target entity (intentionally). This 
override flag will
-   *                           override this fencing mechanism.
+   * @param override           You need to add override for unset of the 
procedure from
+   *                           RegionStateNode without byPassing 
preTransitCheck
+   * @param force              You need to add force for case where a region 
has previously been
+   *                           bypassed. When a Procedure has been bypassed, a 
Procedure will have
+   *                           completed but no other Procedure will be able 
to make progress on the
+   *                           target entity (intentionally). Skips 
preTransitCheck only when
+   *                           selected along with override option
    * @param encodedRegionNames Region encoded names; e.g. 1588230740 is the 
hard-coded encoding for
    *                           hbase:meta region and 
de00010733901a05f5a2a3a382e27dd4 is an example
    *                           of what a random user-space encoded Region name 
looks like.
    */
-  List<Long> unassigns(List<String> encodedRegionNames, boolean override) 
throws IOException;
+  List<Long> unassigns(List<String> encodedRegionNames, boolean override, 
boolean force)
+    throws IOException;
+
+  default List<Long> unassigns(List<String> encodedRegionNames, boolean 
override)
+    throws IOException {
+    return unassigns(encodedRegionNames, override, true);
+  }
 
   default List<Long> unassigns(List<String> encodedRegionNames) throws 
IOException {
-    return unassigns(encodedRegionNames, false);
+    return unassigns(encodedRegionNames, false, true);
   }
 
   /**
diff --git 
a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java
 
b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java
index 80def357f30..b98094ad92a 100644
--- 
a/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java
+++ 
b/hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java
@@ -1592,17 +1592,17 @@ public final class RequestConverter {
 
   // HBCK2
   public static MasterProtos.AssignsRequest 
toAssignRegionsRequest(List<String> encodedRegionNames,
-    boolean override) {
+    boolean override, boolean force) {
     MasterProtos.AssignsRequest.Builder b = 
MasterProtos.AssignsRequest.newBuilder();
     return 
b.addAllRegion(toEncodedRegionNameRegionSpecifiers(encodedRegionNames))
-      .setOverride(override).build();
+      .setOverride(override).setForce(force).build();
   }
 
   public static MasterProtos.UnassignsRequest
-    toUnassignRegionsRequest(List<String> encodedRegionNames, boolean 
override) {
+    toUnassignRegionsRequest(List<String> encodedRegionNames, boolean 
override, boolean force) {
     MasterProtos.UnassignsRequest.Builder b = 
MasterProtos.UnassignsRequest.newBuilder();
     return 
b.addAllRegion(toEncodedRegionNameRegionSpecifiers(encodedRegionNames))
-      .setOverride(override).build();
+      .setOverride(override).setForce(force).build();
   }
 
   public static MasterProtos.ScheduleServerCrashProcedureRequest
diff --git a/hbase-protocol-shaded/src/main/protobuf/server/master/Master.proto 
b/hbase-protocol-shaded/src/main/protobuf/server/master/Master.proto
index b1e750f4d92..a8adaa27453 100644
--- a/hbase-protocol-shaded/src/main/protobuf/server/master/Master.proto
+++ b/hbase-protocol-shaded/src/main/protobuf/server/master/Master.proto
@@ -1302,6 +1302,7 @@ message SetRegionStateInMetaResponse {
 message AssignsRequest {
   repeated RegionSpecifier region = 1;
   optional bool override = 2 [default = false];
+  optional bool force = 3 [default = false];
 }
 
 /** Like Admin's AssignRegionResponse except it can
@@ -1317,6 +1318,7 @@ message AssignsResponse {
 message UnassignsRequest {
   repeated RegionSpecifier region = 1;
   optional bool override = 2 [default = false];
+  optional bool force= 3 [default = false];
 }
 
 /** Like Admin's UnassignRegionResponse except it can
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
index dad3d55e116..faedc6dd628 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java
@@ -2742,6 +2742,7 @@ public class MasterRpcServices extends 
HBaseRpcServicesBase<HMaster>
     MasterProtos.AssignsResponse.Builder responseBuilder =
       MasterProtos.AssignsResponse.newBuilder();
     final boolean override = request.getOverride();
+    final boolean force = request.getForce();
     LOG.info("{} assigns, override={}", server.getClientIdAuditPrefix(), 
override);
     for (HBaseProtos.RegionSpecifier rs : request.getRegionList()) {
       final RegionInfo info = getRegionInfo(rs);
@@ -2749,7 +2750,7 @@ public class MasterRpcServices extends 
HBaseRpcServicesBase<HMaster>
         LOG.info("Unknown region {}", rs);
         continue;
       }
-      
responseBuilder.addPid(Optional.ofNullable(am.createOneAssignProcedure(info, 
override))
+      
responseBuilder.addPid(Optional.ofNullable(am.createOneAssignProcedure(info, 
override, force))
         .map(pe::submitProcedure).orElse(Procedure.NO_PROC_ID));
     }
     return responseBuilder.build();
@@ -2769,6 +2770,7 @@ public class MasterRpcServices extends 
HBaseRpcServicesBase<HMaster>
     MasterProtos.UnassignsResponse.Builder responseBuilder =
       MasterProtos.UnassignsResponse.newBuilder();
     final boolean override = request.getOverride();
+    final boolean force = request.getForce();
     LOG.info("{} unassigns, override={}", server.getClientIdAuditPrefix(), 
override);
     for (HBaseProtos.RegionSpecifier rs : request.getRegionList()) {
       final RegionInfo info = getRegionInfo(rs);
@@ -2776,8 +2778,9 @@ public class MasterRpcServices extends 
HBaseRpcServicesBase<HMaster>
         LOG.info("Unknown region {}", rs);
         continue;
       }
-      
responseBuilder.addPid(Optional.ofNullable(am.createOneUnassignProcedure(info, 
override))
-        .map(pe::submitProcedure).orElse(Procedure.NO_PROC_ID));
+      responseBuilder
+        .addPid(Optional.ofNullable(am.createOneUnassignProcedure(info, 
override, force))
+          .map(pe::submitProcedure).orElse(Procedure.NO_PROC_ID));
     }
     return responseBuilder.build();
   }
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java
index a3195f67212..d05b1f9d3d3 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java
@@ -767,11 +767,14 @@ public class AssignmentManager {
    * @param override If false, check RegionState is appropriate for assign; if 
not throw exception.
    */
   private TransitRegionStateProcedure createAssignProcedure(RegionInfo 
regionInfo, ServerName sn,
-    boolean override) throws IOException {
+    boolean override, boolean force) throws IOException {
     RegionStateNode regionNode = 
regionStates.getOrCreateRegionStateNode(regionInfo);
     regionNode.lock();
     try {
       if (override) {
+        if (!force) {
+          preTransitCheck(regionNode, STATES_EXPECTED_ON_ASSIGN);
+        }
         if (regionNode.getProcedure() != null) {
           regionNode.unsetProcedure(regionNode.getProcedure());
         }
@@ -789,7 +792,7 @@ public class AssignmentManager {
   /**
    * Create an assign TransitRegionStateProcedure. Does NO checking of 
RegionState. Presumes
    * appriopriate state ripe for assign.
-   * @see #createAssignProcedure(RegionInfo, ServerName, boolean)
+   * @see #createAssignProcedure(RegionInfo, ServerName, boolean, boolean)
    */
   private TransitRegionStateProcedure createAssignProcedure(RegionStateNode 
regionNode,
     ServerName targetServer) {
@@ -803,7 +806,7 @@ public class AssignmentManager {
   }
 
   public long assign(RegionInfo regionInfo, ServerName sn) throws IOException {
-    TransitRegionStateProcedure proc = createAssignProcedure(regionInfo, sn, 
false);
+    TransitRegionStateProcedure proc = createAssignProcedure(regionInfo, sn, 
false, false);
     
ProcedureSyncWait.submitAndWaitProcedure(master.getMasterProcedureExecutor(), 
proc);
     return proc.getProcId();
   }
@@ -819,7 +822,7 @@ public class AssignmentManager {
    */
   public Future<byte[]> assignAsync(RegionInfo regionInfo, ServerName sn) 
throws IOException {
     return 
ProcedureSyncWait.submitProcedure(master.getMasterProcedureExecutor(),
-      createAssignProcedure(regionInfo, sn, false));
+      createAssignProcedure(regionInfo, sn, false, false));
   }
 
   /**
@@ -963,10 +966,11 @@ public class AssignmentManager {
    * method is called from HBCK2.
    * @return an assign or null
    */
-  public TransitRegionStateProcedure createOneAssignProcedure(RegionInfo ri, 
boolean override) {
+  public TransitRegionStateProcedure createOneAssignProcedure(RegionInfo ri, 
boolean override,
+    boolean force) {
     TransitRegionStateProcedure trsp = null;
     try {
-      trsp = createAssignProcedure(ri, null, override);
+      trsp = createAssignProcedure(ri, null, override, force);
     } catch (IOException ioe) {
       LOG.info(
         "Failed {} assign, override={}"
@@ -980,12 +984,16 @@ public class AssignmentManager {
    * Create one TransitRegionStateProcedure to unassign a region. This method 
is called from HBCK2.
    * @return an unassign or null
    */
-  public TransitRegionStateProcedure createOneUnassignProcedure(RegionInfo ri, 
boolean override) {
+  public TransitRegionStateProcedure createOneUnassignProcedure(RegionInfo ri, 
boolean override,
+    boolean force) {
     RegionStateNode regionNode = regionStates.getOrCreateRegionStateNode(ri);
     TransitRegionStateProcedure trsp = null;
     regionNode.lock();
     try {
       if (override) {
+        if (!force) {
+          preTransitCheck(regionNode, STATES_EXPECTED_ON_UNASSIGN_OR_MOVE);
+        }
         if (regionNode.getProcedure() != null) {
           regionNode.unsetProcedure(regionNode.getProcedure());
         }
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/TruncateRegionProcedure.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/TruncateRegionProcedure.java
index 9730391baf2..83722d6c1dc 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/TruncateRegionProcedure.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/TruncateRegionProcedure.java
@@ -210,10 +210,10 @@ public class TruncateRegionProcedure
 
   private TransitRegionStateProcedure 
createUnAssignProcedures(MasterProcedureEnv env)
     throws IOException {
-    return env.getAssignmentManager().createOneUnassignProcedure(getRegion(), 
true);
+    return env.getAssignmentManager().createOneUnassignProcedure(getRegion(), 
true, true);
   }
 
   private TransitRegionStateProcedure 
createAssignProcedures(MasterProcedureEnv env) {
-    return env.getAssignmentManager().createOneAssignProcedure(getRegion(), 
true);
+    return env.getAssignmentManager().createOneAssignProcedure(getRegion(), 
true, true);
   }
 }
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHbck.java 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHbck.java
index 406b25fed4e..360641e64b7 100644
--- a/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHbck.java
+++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHbck.java
@@ -250,11 +250,20 @@ public class TestHbck {
       for (long pid : pids) {
         assertEquals(Procedure.NO_PROC_ID, pid);
       }
-      // If we pass override, then we should be able to unassign EVEN THOUGH 
Regions already
+      // Rerun the unassign with override. Should fail for all Regions since 
they already
+      // unassigned; failed
+      // unassign will manifest as all pids being -1 (ever since HBASE-24885).
+      pids = hbck.unassigns(
+        
regions.stream().map(RegionInfo::getEncodedName).collect(Collectors.toList()), 
true, false);
+      waitOnPids(pids);
+      for (long pid : pids) {
+        assertEquals(Procedure.NO_PROC_ID, pid);
+      }
+      // If we pass force, then we should be able to unassign EVEN THOUGH 
Regions already
       // unassigned.... makes for a mess but operator might want to do this at 
an extreme when
       // doing fixup of broke cluster.
       pids = hbck.unassigns(
-        
regions.stream().map(RegionInfo::getEncodedName).collect(Collectors.toList()), 
true);
+        
regions.stream().map(RegionInfo::getEncodedName).collect(Collectors.toList()), 
true, true);
       waitOnPids(pids);
       for (long pid : pids) {
         assertNotEquals(Procedure.NO_PROC_ID, pid);
@@ -283,6 +292,12 @@ public class TestHbck {
         LOG.info("RS: {}", rs.toString());
         assertTrue(rs.toString(), rs.isOpened());
       }
+      // Rerun the assign with override. Should fail for all Regions since 
they already assigned
+      pids = hbck.assigns(
+        
regions.stream().map(RegionInfo::getEncodedName).collect(Collectors.toList()), 
true, false);
+      for (long pid : pids) {
+        assertEquals(Procedure.NO_PROC_ID, pid);
+      }
       // What happens if crappy region list passed?
       pids = hbck.assigns(
         Arrays.stream(new String[] { "a", "some rubbish name" 
}).collect(Collectors.toList()));
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRegionBypass.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRegionBypass.java
index 61520873240..8295da82f49 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRegionBypass.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRegionBypass.java
@@ -125,7 +125,7 @@ public class TestRegionBypass {
       .getMasterProcedureExecutor().getActiveProcIds().isEmpty());
     // Now assign with the override flag.
     for (RegionInfo ri : regions) {
-      TEST_UTIL.getHbck().assigns(Arrays.<String> asList(ri.getEncodedName()), 
true);
+      TEST_UTIL.getHbck().assigns(Arrays.<String> asList(ri.getEncodedName()), 
true, true);
     }
     TEST_UTIL.waitFor(60000, () -> TEST_UTIL.getHBaseCluster().getMaster()
       .getMasterProcedureExecutor().getActiveProcIds().isEmpty());

Reply via email to