Skip to content

Commit 047aad1

Browse files
stotysaintstack
authored andcommitted
HBASE-22941 merge operation returns parent regions in random order (apache#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 84cc511 commit 047aad1

File tree

5 files changed

+52
-28
lines changed

5 files changed

+52
-28
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
@@ -805,10 +805,6 @@ public MergeTableRegionsResponse mergeTableRegions(
805805

806806
RegionStates regionStates = master.getAssignmentManager().getRegionStates();
807807

808-
if (request.getRegionCount() != 2) {
809-
throw new ServiceException(new DoNotRetryIOException(
810-
"Only support merging 2 regions but " + request.getRegionCount() + " region passed"));
811-
}
812808
RegionInfo[] regionsToMerge = new RegionInfo[request.getRegionCount()];
813809
for (int i = 0; i < request.getRegionCount(); i++) {
814810
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;
@@ -246,7 +246,7 @@ public void mergeRegions(RegionInfo child, RegionInfo [] parents, ServerName ser
246246
throws IOException {
247247
TableDescriptor htd = getTableDescriptor(child.getTable());
248248
boolean globalScope = htd.hasGlobalReplicationScope();
249-
Map<RegionInfo, Long> parentSeqNums = new HashMap<>(parents.length);
249+
SortedMap<RegionInfo, Long> parentSeqNums = new TreeMap<>();
250250
for (RegionInfo ri: parents) {
251251
parentSeqNums.put(ri, globalScope? getOpenSeqNumForParentRegion(ri): -1);
252252
}

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 & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import java.util.concurrent.ExecutionException;
3333
import java.util.concurrent.TimeUnit;
3434
import java.util.concurrent.atomic.AtomicInteger;
35-
import org.apache.hadoop.hbase.DoNotRetryIOException;
3635
import org.apache.hadoop.hbase.HBaseClassTestRule;
3736
import org.apache.hadoop.hbase.HBaseTestingUtility;
3837
import org.apache.hadoop.hbase.HColumnDescriptor;
@@ -1467,15 +1466,6 @@ public void testMergeRegionsInvalidRegionCount()
14671466
} catch (IllegalArgumentException e) {
14681467
// expected
14691468
}
1470-
// 3
1471-
try {
1472-
admin.mergeRegionsAsync(
1473-
tableRegions.stream().map(RegionInfo::getEncodedNameAsBytes).toArray(byte[][]::new),
1474-
false).get();
1475-
fail();
1476-
} catch (DoNotRetryIOException e) {
1477-
// expected
1478-
}
14791469
} finally {
14801470
admin.disableTable(tableName);
14811471
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)