Skip to content

Commit 3b2e981

Browse files
authored
HBASE-28151 Option to allow/disallow bypassing pre transit check for assing/unassign (#5493)
Signed-off-by: Andrew Purtell <apurtell@apache.org> Signed-off-by: Viraj Jasani <vjasani@apache.org> Signed-off-by: Ravi Kishore Valeti <v.ravikishore@gmail.com>
1 parent d82a892 commit 3b2e981

File tree

9 files changed

+81
-37
lines changed

9 files changed

+81
-37
lines changed

hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseHbck.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,11 @@ public Map<String, RegionState.State> setRegionStateInMeta(
135135
}
136136

137137
@Override
138-
public List<Long> assigns(List<String> encodedRegionNames, boolean override) throws IOException {
138+
public List<Long> assigns(List<String> encodedRegionNames, boolean override, boolean force)
139+
throws IOException {
139140
try {
140141
AssignsResponse response = this.hbck.assigns(rpcControllerFactory.newController(),
141-
RequestConverter.toAssignRegionsRequest(encodedRegionNames, override));
142+
RequestConverter.toAssignRegionsRequest(encodedRegionNames, override, force));
142143
return response.getPidList();
143144
} catch (ServiceException se) {
144145
LOG.debug(toCommaDelimitedString(encodedRegionNames), se);
@@ -147,11 +148,11 @@ public List<Long> assigns(List<String> encodedRegionNames, boolean override) thr
147148
}
148149

149150
@Override
150-
public List<Long> unassigns(List<String> encodedRegionNames, boolean override)
151+
public List<Long> unassigns(List<String> encodedRegionNames, boolean override, boolean force)
151152
throws IOException {
152153
try {
153154
UnassignsResponse response = this.hbck.unassigns(rpcControllerFactory.newController(),
154-
RequestConverter.toUnassignRegionsRequest(encodedRegionNames, override));
155+
RequestConverter.toUnassignRegionsRequest(encodedRegionNames, override, force));
155156
return response.getPidList();
156157
} catch (ServiceException se) {
157158
LOG.debug(toCommaDelimitedString(encodedRegionNames), se);

hbase-client/src/main/java/org/apache/hadoop/hbase/client/Hbck.java

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,39 +62,54 @@ public interface Hbck extends Abortable, Closeable {
6262
* good if many Regions to online -- and it will schedule the assigns even in the case where
6363
* Master is initializing (as long as the ProcedureExecutor is up). Does NOT call Coprocessor
6464
* hooks.
65-
* @param override You need to add the override for case where a region has previously
66-
* been bypassed. When a Procedure has been bypassed, a Procedure will
67-
* have completed but no other Procedure will be able to make progress
68-
* on the target entity (intentionally). This override flag will
69-
* override this fencing mechanism.
65+
* @param override You need to add override for unset of the procedure from
66+
* RegionStateNode without byPassing preTransitCheck
67+
* @param force You need to add force for case where a region has previously been
68+
* bypassed. When a Procedure has been bypassed, a Procedure will have
69+
* completed but no other Procedure will be able to make progress on the
70+
* target entity (intentionally). Skips preTransitCheck only when
71+
* selected along with override option
7072
* @param encodedRegionNames Region encoded names; e.g. 1588230740 is the hard-coded encoding for
7173
* hbase:meta region and de00010733901a05f5a2a3a382e27dd4 is an example
7274
* of what a random user-space encoded Region name looks like.
7375
*/
74-
List<Long> assigns(List<String> encodedRegionNames, boolean override) throws IOException;
76+
List<Long> assigns(List<String> encodedRegionNames, boolean override, boolean force)
77+
throws IOException;
78+
79+
default List<Long> assigns(List<String> encodedRegionNames, boolean override) throws IOException {
80+
return assigns(encodedRegionNames, override, true);
81+
}
7582

7683
default List<Long> assigns(List<String> encodedRegionNames) throws IOException {
77-
return assigns(encodedRegionNames, false);
84+
return assigns(encodedRegionNames, false, false);
7885
}
7986

8087
/**
8188
* Like {@link Admin#unassign(byte[], boolean)} but 'raw' in that it can do more than one Region
8289
* at a time -- good if many Regions to offline -- and it will schedule the assigns even in the
8390
* case where Master is initializing (as long as the ProcedureExecutor is up). Does NOT call
8491
* Coprocessor hooks.
85-
* @param override You need to add the override for case where a region has previously
86-
* been bypassed. When a Procedure has been bypassed, a Procedure will
87-
* have completed but no other Procedure will be able to make progress
88-
* on the target entity (intentionally). This override flag will
89-
* override this fencing mechanism.
92+
* @param override You need to add override for unset of the procedure from
93+
* RegionStateNode without byPassing preTransitCheck
94+
* @param force You need to add force for case where a region has previously been
95+
* bypassed. When a Procedure has been bypassed, a Procedure will have
96+
* completed but no other Procedure will be able to make progress on the
97+
* target entity (intentionally). Skips preTransitCheck only when
98+
* selected along with override option
9099
* @param encodedRegionNames Region encoded names; e.g. 1588230740 is the hard-coded encoding for
91100
* hbase:meta region and de00010733901a05f5a2a3a382e27dd4 is an example
92101
* of what a random user-space encoded Region name looks like.
93102
*/
94-
List<Long> unassigns(List<String> encodedRegionNames, boolean override) throws IOException;
103+
List<Long> unassigns(List<String> encodedRegionNames, boolean override, boolean force)
104+
throws IOException;
105+
106+
default List<Long> unassigns(List<String> encodedRegionNames, boolean override)
107+
throws IOException {
108+
return unassigns(encodedRegionNames, override, true);
109+
}
95110

96111
default List<Long> unassigns(List<String> encodedRegionNames) throws IOException {
97-
return unassigns(encodedRegionNames, false);
112+
return unassigns(encodedRegionNames, false, true);
98113
}
99114

100115
/**

hbase-client/src/main/java/org/apache/hadoop/hbase/shaded/protobuf/RequestConverter.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1590,17 +1590,17 @@ private static List<HBaseProtos.ServerName> toProtoServerNames(List<ServerName>
15901590

15911591
// HBCK2
15921592
public static MasterProtos.AssignsRequest toAssignRegionsRequest(List<String> encodedRegionNames,
1593-
boolean override) {
1593+
boolean override, boolean force) {
15941594
MasterProtos.AssignsRequest.Builder b = MasterProtos.AssignsRequest.newBuilder();
15951595
return b.addAllRegion(toEncodedRegionNameRegionSpecifiers(encodedRegionNames))
1596-
.setOverride(override).build();
1596+
.setOverride(override).setForce(force).build();
15971597
}
15981598

15991599
public static MasterProtos.UnassignsRequest
1600-
toUnassignRegionsRequest(List<String> encodedRegionNames, boolean override) {
1600+
toUnassignRegionsRequest(List<String> encodedRegionNames, boolean override, boolean force) {
16011601
MasterProtos.UnassignsRequest.Builder b = MasterProtos.UnassignsRequest.newBuilder();
16021602
return b.addAllRegion(toEncodedRegionNameRegionSpecifiers(encodedRegionNames))
1603-
.setOverride(override).build();
1603+
.setOverride(override).setForce(force).build();
16041604
}
16051605

16061606
public static MasterProtos.ScheduleServerCrashProcedureRequest

hbase-protocol-shaded/src/main/protobuf/server/master/Master.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,7 @@ message SetRegionStateInMetaResponse {
13021302
message AssignsRequest {
13031303
repeated RegionSpecifier region = 1;
13041304
optional bool override = 2 [default = false];
1305+
optional bool force = 3 [default = false];
13051306
}
13061307

13071308
/** Like Admin's AssignRegionResponse except it can
@@ -1317,6 +1318,7 @@ message AssignsResponse {
13171318
message UnassignsRequest {
13181319
repeated RegionSpecifier region = 1;
13191320
optional bool override = 2 [default = false];
1321+
optional bool force= 3 [default = false];
13201322
}
13211323

13221324
/** Like Admin's UnassignRegionResponse except it can

hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRpcServices.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2714,14 +2714,15 @@ public MasterProtos.AssignsResponse assigns(RpcController controller,
27142714
MasterProtos.AssignsResponse.Builder responseBuilder =
27152715
MasterProtos.AssignsResponse.newBuilder();
27162716
final boolean override = request.getOverride();
2717+
final boolean force = request.getForce();
27172718
LOG.info("{} assigns, override={}", server.getClientIdAuditPrefix(), override);
27182719
for (HBaseProtos.RegionSpecifier rs : request.getRegionList()) {
27192720
final RegionInfo info = getRegionInfo(rs);
27202721
if (info == null) {
27212722
LOG.info("Unknown region {}", rs);
27222723
continue;
27232724
}
2724-
responseBuilder.addPid(Optional.ofNullable(am.createOneAssignProcedure(info, override))
2725+
responseBuilder.addPid(Optional.ofNullable(am.createOneAssignProcedure(info, override, force))
27252726
.map(pe::submitProcedure).orElse(Procedure.NO_PROC_ID));
27262727
}
27272728
return responseBuilder.build();
@@ -2741,15 +2742,17 @@ public MasterProtos.UnassignsResponse unassigns(RpcController controller,
27412742
MasterProtos.UnassignsResponse.Builder responseBuilder =
27422743
MasterProtos.UnassignsResponse.newBuilder();
27432744
final boolean override = request.getOverride();
2745+
final boolean force = request.getForce();
27442746
LOG.info("{} unassigns, override={}", server.getClientIdAuditPrefix(), override);
27452747
for (HBaseProtos.RegionSpecifier rs : request.getRegionList()) {
27462748
final RegionInfo info = getRegionInfo(rs);
27472749
if (info == null) {
27482750
LOG.info("Unknown region {}", rs);
27492751
continue;
27502752
}
2751-
responseBuilder.addPid(Optional.ofNullable(am.createOneUnassignProcedure(info, override))
2752-
.map(pe::submitProcedure).orElse(Procedure.NO_PROC_ID));
2753+
responseBuilder
2754+
.addPid(Optional.ofNullable(am.createOneUnassignProcedure(info, override, force))
2755+
.map(pe::submitProcedure).orElse(Procedure.NO_PROC_ID));
27532756
}
27542757
return responseBuilder.build();
27552758
}

hbase-server/src/main/java/org/apache/hadoop/hbase/master/assignment/AssignmentManager.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -765,11 +765,14 @@ private void preTransitCheck(RegionStateNode regionNode, RegionState.State[] exp
765765
* @param override If false, check RegionState is appropriate for assign; if not throw exception.
766766
*/
767767
private TransitRegionStateProcedure createAssignProcedure(RegionInfo regionInfo, ServerName sn,
768-
boolean override) throws IOException {
768+
boolean override, boolean force) throws IOException {
769769
RegionStateNode regionNode = regionStates.getOrCreateRegionStateNode(regionInfo);
770770
regionNode.lock();
771771
try {
772772
if (override) {
773+
if (!force) {
774+
preTransitCheck(regionNode, STATES_EXPECTED_ON_ASSIGN);
775+
}
773776
if (regionNode.getProcedure() != null) {
774777
regionNode.unsetProcedure(regionNode.getProcedure());
775778
}
@@ -787,7 +790,7 @@ private TransitRegionStateProcedure createAssignProcedure(RegionInfo regionInfo,
787790
/**
788791
* Create an assign TransitRegionStateProcedure. Does NO checking of RegionState. Presumes
789792
* appriopriate state ripe for assign.
790-
* @see #createAssignProcedure(RegionInfo, ServerName, boolean)
793+
* @see #createAssignProcedure(RegionInfo, ServerName, boolean, boolean)
791794
*/
792795
private TransitRegionStateProcedure createAssignProcedure(RegionStateNode regionNode,
793796
ServerName targetServer) {
@@ -801,7 +804,7 @@ private TransitRegionStateProcedure createAssignProcedure(RegionStateNode region
801804
}
802805

803806
public long assign(RegionInfo regionInfo, ServerName sn) throws IOException {
804-
TransitRegionStateProcedure proc = createAssignProcedure(regionInfo, sn, false);
807+
TransitRegionStateProcedure proc = createAssignProcedure(regionInfo, sn, false, false);
805808
ProcedureSyncWait.submitAndWaitProcedure(master.getMasterProcedureExecutor(), proc);
806809
return proc.getProcId();
807810
}
@@ -817,7 +820,7 @@ public long assign(RegionInfo regionInfo) throws IOException {
817820
*/
818821
public Future<byte[]> assignAsync(RegionInfo regionInfo, ServerName sn) throws IOException {
819822
return ProcedureSyncWait.submitProcedure(master.getMasterProcedureExecutor(),
820-
createAssignProcedure(regionInfo, sn, false));
823+
createAssignProcedure(regionInfo, sn, false, false));
821824
}
822825

823826
/**
@@ -961,10 +964,11 @@ static int compare(TransitRegionStateProcedure left, TransitRegionStateProcedure
961964
* method is called from HBCK2.
962965
* @return an assign or null
963966
*/
964-
public TransitRegionStateProcedure createOneAssignProcedure(RegionInfo ri, boolean override) {
967+
public TransitRegionStateProcedure createOneAssignProcedure(RegionInfo ri, boolean override,
968+
boolean force) {
965969
TransitRegionStateProcedure trsp = null;
966970
try {
967-
trsp = createAssignProcedure(ri, null, override);
971+
trsp = createAssignProcedure(ri, null, override, force);
968972
} catch (IOException ioe) {
969973
LOG.info(
970974
"Failed {} assign, override={}"
@@ -978,12 +982,16 @@ public TransitRegionStateProcedure createOneAssignProcedure(RegionInfo ri, boole
978982
* Create one TransitRegionStateProcedure to unassign a region. This method is called from HBCK2.
979983
* @return an unassign or null
980984
*/
981-
public TransitRegionStateProcedure createOneUnassignProcedure(RegionInfo ri, boolean override) {
985+
public TransitRegionStateProcedure createOneUnassignProcedure(RegionInfo ri, boolean override,
986+
boolean force) {
982987
RegionStateNode regionNode = regionStates.getOrCreateRegionStateNode(ri);
983988
TransitRegionStateProcedure trsp = null;
984989
regionNode.lock();
985990
try {
986991
if (override) {
992+
if (!force) {
993+
preTransitCheck(regionNode, STATES_EXPECTED_ON_UNASSIGN_OR_MOVE);
994+
}
987995
if (regionNode.getProcedure() != null) {
988996
regionNode.unsetProcedure(regionNode.getProcedure());
989997
}

hbase-server/src/main/java/org/apache/hadoop/hbase/master/procedure/TruncateRegionProcedure.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,10 @@ public TableOperationType getTableOperationType() {
210210

211211
private TransitRegionStateProcedure createUnAssignProcedures(MasterProcedureEnv env)
212212
throws IOException {
213-
return env.getAssignmentManager().createOneUnassignProcedure(getRegion(), true);
213+
return env.getAssignmentManager().createOneUnassignProcedure(getRegion(), true, true);
214214
}
215215

216216
private TransitRegionStateProcedure createAssignProcedures(MasterProcedureEnv env) {
217-
return env.getAssignmentManager().createOneAssignProcedure(getRegion(), true);
217+
return env.getAssignmentManager().createOneAssignProcedure(getRegion(), true, true);
218218
}
219219
}

hbase-server/src/test/java/org/apache/hadoop/hbase/client/TestHbck.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,20 @@ public void testAssigns() throws Exception {
250250
for (long pid : pids) {
251251
assertEquals(Procedure.NO_PROC_ID, pid);
252252
}
253-
// If we pass override, then we should be able to unassign EVEN THOUGH Regions already
253+
// Rerun the unassign with override. Should fail for all Regions since they already
254+
// unassigned; failed
255+
// unassign will manifest as all pids being -1 (ever since HBASE-24885).
256+
pids = hbck.unassigns(
257+
regions.stream().map(RegionInfo::getEncodedName).collect(Collectors.toList()), true, false);
258+
waitOnPids(pids);
259+
for (long pid : pids) {
260+
assertEquals(Procedure.NO_PROC_ID, pid);
261+
}
262+
// If we pass force, then we should be able to unassign EVEN THOUGH Regions already
254263
// unassigned.... makes for a mess but operator might want to do this at an extreme when
255264
// doing fixup of broke cluster.
256265
pids = hbck.unassigns(
257-
regions.stream().map(RegionInfo::getEncodedName).collect(Collectors.toList()), true);
266+
regions.stream().map(RegionInfo::getEncodedName).collect(Collectors.toList()), true, true);
258267
waitOnPids(pids);
259268
for (long pid : pids) {
260269
assertNotEquals(Procedure.NO_PROC_ID, pid);
@@ -283,6 +292,12 @@ public void testAssigns() throws Exception {
283292
LOG.info("RS: {}", rs.toString());
284293
assertTrue(rs.toString(), rs.isOpened());
285294
}
295+
// Rerun the assign with override. Should fail for all Regions since they already assigned
296+
pids = hbck.assigns(
297+
regions.stream().map(RegionInfo::getEncodedName).collect(Collectors.toList()), true, false);
298+
for (long pid : pids) {
299+
assertEquals(Procedure.NO_PROC_ID, pid);
300+
}
286301
// What happens if crappy region list passed?
287302
pids = hbck.assigns(
288303
Arrays.stream(new String[] { "a", "some rubbish name" }).collect(Collectors.toList()));

hbase-server/src/test/java/org/apache/hadoop/hbase/master/assignment/TestRegionBypass.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public void testBypass() throws IOException, InterruptedException {
125125
.getMasterProcedureExecutor().getActiveProcIds().isEmpty());
126126
// Now assign with the override flag.
127127
for (RegionInfo ri : regions) {
128-
TEST_UTIL.getHbck().assigns(Arrays.<String> asList(ri.getEncodedName()), true);
128+
TEST_UTIL.getHbck().assigns(Arrays.<String> asList(ri.getEncodedName()), true, true);
129129
}
130130
TEST_UTIL.waitFor(60000, () -> TEST_UTIL.getHBaseCluster().getMaster()
131131
.getMasterProcedureExecutor().getActiveProcIds().isEmpty());

0 commit comments

Comments
 (0)