Skip to content

Commit 56fd3e9

Browse files
stotysaintstack
authored andcommitted
HBASE-22941 merge operation returns parent regions in random order (#556)
* HBASE-22941 merge operation returns parent regions in random order store and return the merge parent regions in ascending order remove left over check for exactly two merged regions add unit test * use SortedMap type to emphasise that the Map is sorted. * use regionCount consistently and checkstyle fixes * Delete tests that expect multiregion merges to fail. Signed-off-by: stack <stack@apache.org>
1 parent 83e7794 commit 56fd3e9

File tree

5 files changed

+52
-27
lines changed

5 files changed

+52
-27
lines changed

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -812,10 +812,6 @@ public MergeTableRegionsResponse mergeTableRegions(
812812

813813
RegionStates regionStates = master.getAssignmentManager().getRegionStates();
814814

815-
if (request.getRegionCount() != 2) {
816-
throw new ServiceException(new DoNotRetryIOException(
817-
"Only support merging 2 regions but " + request.getRegionCount() + " region passed"));
818-
}
819815
RegionInfo[] regionsToMerge = new RegionInfo[request.getRegionCount()];
820816
for (int i = 0; i < request.getRegionCount(); i++) {
821817
final byte[] encodedNameOfRegion = request.getRegion(i).getValue().toByteArray();

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919

2020
import java.io.IOException;
2121
import java.util.Collections;
22-
import java.util.HashMap;
2322
import java.util.List;
24-
import java.util.Map;
23+
import java.util.SortedMap;
24+
import java.util.TreeMap;
2525

2626
import org.apache.hadoop.hbase.Cell;
2727
import org.apache.hadoop.hbase.CellBuilderFactory;
@@ -263,7 +263,7 @@ public void mergeRegions(RegionInfo child, RegionInfo [] parents, ServerName ser
263263
throws IOException {
264264
TableDescriptor htd = getDescriptor(child.getTable());
265265
boolean globalScope = htd.hasGlobalReplicationScope();
266-
Map<RegionInfo, Long> parentSeqNums = new HashMap<>(parents.length);
266+
SortedMap<RegionInfo, Long> parentSeqNums = new TreeMap<>();
267267
for (RegionInfo ri: parents) {
268268
parentSeqNums.put(ri, globalScope? getOpenSeqNumForParentRegion(ri): -1);
269269
}

hbase-server/src/test/java/org/apache/hadoop/hbase/TestSplitMerge.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919

2020
import static org.junit.Assert.assertEquals;
2121
import static org.junit.Assert.assertNotNull;
22+
import static org.junit.Assert.assertTrue;
2223

24+
import java.util.List;
2325
import java.util.concurrent.TimeUnit;
2426
import org.apache.hadoop.hbase.Waiter.ExplainingPredicate;
2527
import org.apache.hadoop.hbase.client.AsyncConnection;
@@ -104,4 +106,51 @@ public String explainFailure() throws Exception {
104106
.getRegionLocation(Bytes.toBytes(1), true).get().getServerName());
105107
}
106108
}
109+
110+
@Test
111+
public void testMergeRegionOrder() throws Exception {
112+
113+
int regionCount= 20;
114+
115+
TableName tableName = TableName.valueOf("MergeRegionOrder");
116+
byte[] family = Bytes.toBytes("CF");
117+
TableDescriptor td = TableDescriptorBuilder.newBuilder(tableName)
118+
.setColumnFamily(ColumnFamilyDescriptorBuilder.of(family)).build();
119+
120+
byte[][] splitKeys = new byte[regionCount-1][];
121+
122+
for (int c = 0; c < regionCount-1; c++) {
123+
splitKeys[c] = Bytes.toBytes(c+1 * 1000);
124+
}
125+
126+
UTIL.getAdmin().createTable(td, splitKeys);
127+
UTIL.waitTableAvailable(tableName);
128+
129+
List<RegionInfo> regions = UTIL.getAdmin().getRegions(tableName);
130+
131+
byte[][] regionNames = new byte[regionCount][];
132+
for (int c = 0; c < regionCount; c++) {
133+
regionNames[c] = regions.get(c).getRegionName();
134+
}
135+
136+
UTIL.getAdmin().mergeRegionsAsync(regionNames, false).get(60, TimeUnit.SECONDS);
137+
138+
List<RegionInfo> mergedRegions =
139+
MetaTableAccessor.getTableRegions(UTIL.getConnection(), tableName);
140+
141+
assertEquals(1, mergedRegions.size());
142+
143+
RegionInfo mergedRegion = mergedRegions.get(0);
144+
145+
List<RegionInfo> mergeParentRegions = MetaTableAccessor.getMergeRegions(UTIL.getConnection(),
146+
mergedRegion.getEncodedNameAsBytes());
147+
148+
assertEquals(mergeParentRegions.size(), regionCount);
149+
150+
for (int c = 0; c < regionCount-1; c++) {
151+
assertTrue(Bytes.compareTo(
152+
mergeParentRegions.get(c).getStartKey(),
153+
mergeParentRegions.get(c+1).getStartKey()) < 0);
154+
}
155+
}
107156
}

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

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -588,15 +588,6 @@ public void testMergeRegionsInvalidRegionCount()
588588
} catch (IllegalArgumentException e) {
589589
// expected
590590
}
591-
// 3
592-
try {
593-
FutureUtils.get(ADMIN.mergeRegionsAsync(
594-
tableRegions.stream().map(RegionInfo::getEncodedNameAsBytes).toArray(byte[][]::new),
595-
false));
596-
fail();
597-
} catch (DoNotRetryIOException e) {
598-
// expected
599-
}
600591
} finally {
601592
ADMIN.disableTable(tableName);
602593
ADMIN.deleteTable(tableName);

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

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import java.util.concurrent.ExecutionException;
3333
import java.util.stream.Collectors;
3434
import org.apache.hadoop.hbase.AsyncMetaTableAccessor;
35-
import org.apache.hadoop.hbase.DoNotRetryIOException;
3635
import org.apache.hadoop.hbase.HBaseClassTestRule;
3736
import org.apache.hadoop.hbase.HConstants;
3837
import org.apache.hadoop.hbase.HRegionLocation;
@@ -205,16 +204,6 @@ public void testMergeRegionsInvalidRegionCount() throws Exception {
205204
// expected
206205
assertThat(e.getCause(), instanceOf(IllegalArgumentException.class));
207206
}
208-
// 3
209-
try {
210-
admin.mergeRegions(
211-
regions.stream().map(RegionInfo::getEncodedNameAsBytes).collect(Collectors.toList()), false)
212-
.get();
213-
fail();
214-
} catch (ExecutionException e) {
215-
// expected
216-
assertThat(e.getCause(), instanceOf(DoNotRetryIOException.class));
217-
}
218207
}
219208

220209
@Test

0 commit comments

Comments
 (0)