Skip to content

Commit 0ccc115

Browse files
author
Huaxiang Sun
committed
HBASE-24705 MetaFixer#fixHoles() does not include the case for read replicas (i.e, replica regions are not created)
1 parent 3bd5421 commit 0ccc115

3 files changed

Lines changed: 61 additions & 19 deletions

File tree

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

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,13 @@
3232
import org.apache.hadoop.hbase.TableName;
3333
import org.apache.hadoop.hbase.client.RegionInfo;
3434
import org.apache.hadoop.hbase.client.RegionInfoBuilder;
35+
import org.apache.hadoop.hbase.client.RegionReplicaUtil;
36+
import org.apache.hadoop.hbase.client.TableDescriptor;
3537
import org.apache.hadoop.hbase.exceptions.MergeRegionException;
3638
import org.apache.hadoop.hbase.master.assignment.TransitRegionStateProcedure;
3739
import org.apache.hadoop.hbase.util.Bytes;
3840
import org.apache.hadoop.hbase.util.Pair;
41+
import org.apache.hadoop.hbase.util.ServerRegionReplicaUtil;
3942
import org.apache.yetus.audience.InterfaceAudience;
4043
import org.slf4j.Logger;
4144
import org.slf4j.LoggerFactory;
@@ -174,22 +177,35 @@ private static RegionInfo buildRegionInfo(TableName tn, byte [] start, byte [] e
174177
private static List<RegionInfo> createMetaEntries(final MasterServices masterServices,
175178
final List<RegionInfo> newRegionInfos) {
176179

177-
final List<Either<RegionInfo, IOException>> addMetaEntriesResults = newRegionInfos.stream()
180+
final List<Either<List<RegionInfo>, IOException>> addMetaEntriesResults = newRegionInfos.stream()
178181
.map(regionInfo -> {
179182
try {
180-
MetaTableAccessor.addRegionToMeta(masterServices.getConnection(), regionInfo);
181-
masterServices.getAssignmentManager()
182-
.getRegionStates()
183-
.updateRegionState(regionInfo, RegionState.State.CLOSED);
184-
return Either.<RegionInfo, IOException>ofLeft(regionInfo);
183+
TableDescriptor td = masterServices.getTableDescriptors().get(regionInfo.getTable());
184+
185+
// Add replicas if needed
186+
// we need to create regions with replicaIds starting from 1
187+
List<RegionInfo> newRegions = RegionReplicaUtil.addReplicas(td,
188+
Collections.singletonList(regionInfo), 1, td.getRegionReplication());
189+
190+
// Add regions to META
191+
MetaTableAccessor.addRegionsToMeta(masterServices.getConnection(), newRegions,
192+
td.getRegionReplication());
193+
194+
// Setup replication for region replicas if needed
195+
if (td.getRegionReplication() > 1) {
196+
ServerRegionReplicaUtil.setupRegionReplicaReplication(
197+
masterServices.getConfiguration());
198+
}
199+
return Either.<List<RegionInfo>, IOException>ofLeft(newRegions);
185200
} catch (IOException e) {
186-
return Either.<RegionInfo, IOException>ofRight(e);
201+
return Either.<List<RegionInfo>, IOException>ofRight(e);
187202
}
188203
})
189204
.collect(Collectors.toList());
190205
final List<RegionInfo> createMetaEntriesSuccesses = addMetaEntriesResults.stream()
191206
.filter(Either::hasLeft)
192207
.map(Either::getLeft)
208+
.flatMap(List::stream)
193209
.collect(Collectors.toList());
194210
final List<IOException> createMetaEntriesFailures = addMetaEntriesResults.stream()
195211
.filter(Either::hasRight)

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,6 +1530,19 @@ public Table createMultiRegionTable(TableName tableName, byte[][] families) thro
15301530
return createTable(tableName, families, KEYS_FOR_HBA_CREATE_TABLE);
15311531
}
15321532

1533+
/**
1534+
* Create a table with multiple regions.
1535+
* @param tableName
1536+
* @param replicaCount replica count.
1537+
* @param families
1538+
* @return A Table instance for the created table.
1539+
* @throws IOException
1540+
*/
1541+
public Table createMultiRegionTable(TableName tableName, int replicaCount, byte[][] families)
1542+
throws IOException {
1543+
return createTable(tableName, families, KEYS_FOR_HBA_CREATE_TABLE, replicaCount);
1544+
}
1545+
15331546
/**
15341547
* Create a table.
15351548
* @param tableName

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

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -83,23 +83,24 @@ private void deleteRegion(MasterServices services, RegionInfo ri) throws IOExcep
8383
services.getAssignmentManager().getRegionStates().deleteRegion(ri);
8484
}
8585

86-
@Test
87-
public void testPlugsHoles() throws Exception {
88-
TableName tn = TableName.valueOf(this.name.getMethodName());
89-
TEST_UTIL.createMultiRegionTable(tn, HConstants.CATALOG_FAMILY);
86+
private void testPlugsHolesWithReadReplicaInternal(final TableName tn, final int replicaCount)
87+
throws Exception {
88+
TEST_UTIL.createMultiRegionTable(tn, replicaCount, new byte[][] { HConstants.CATALOG_FAMILY });
9089
List<RegionInfo> ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);
9190
MasterServices services = TEST_UTIL.getHBaseCluster().getMaster();
9291
int initialSize = services.getAssignmentManager().getRegionStates().getRegionStates().size();
9392
services.getCatalogJanitor().scan();
9493
CatalogJanitor.Report report = services.getCatalogJanitor().getLastReport();
9594
assertTrue(report.isEmpty());
9695
int originalCount = ris.size();
97-
// Remove first, last and middle region. See if hole gets plugged. Table has 26 regions.
98-
deleteRegion(services, ris.get(ris.size() -1));
99-
deleteRegion(services, ris.get(3));
100-
deleteRegion(services, ris.get(0));
101-
assertEquals(initialSize - 3,
102-
services.getAssignmentManager().getRegionStates().getRegionStates().size());
96+
// Remove first, last and middle region. See if hole gets plugged. Table has 26 * replicaCount regions.
97+
for (int i = 0; i < replicaCount; i ++) {
98+
deleteRegion(services, ris.get(3 * replicaCount + i));
99+
deleteRegion(services, ris.get(i));
100+
deleteRegion(services, ris.get(ris.size() - 1 - i));
101+
}
102+
assertEquals(initialSize - 3 * replicaCount,
103+
services.getAssignmentManager().getRegionStates().getRegionStates().size());
103104
services.getCatalogJanitor().scan();
104105
report = services.getCatalogJanitor().getLastReport();
105106
assertEquals(report.toString(), 3, report.getHoles().size());
@@ -109,17 +110,29 @@ public void testPlugsHoles() throws Exception {
109110
report = services.getCatalogJanitor().getLastReport();
110111
assertTrue(report.toString(), report.isEmpty());
111112
assertEquals(initialSize,
112-
services.getAssignmentManager().getRegionStates().getRegionStates().size());
113+
services.getAssignmentManager().getRegionStates().getRegionStates().size());
113114

114115
// wait for RITs to settle -- those are the fixed regions being assigned -- or until the
115116
// watchdog TestRule terminates the test.
116117
HBaseTestingUtility.await(50,
117-
() -> isNotEmpty(services.getAssignmentManager().getRegionsInTransition()));
118+
() -> services.getMasterProcedureExecutor().getActiveProcIds().size() == 0);
118119

119120
ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);
120121
assertEquals(originalCount, ris.size());
121122
}
122123

124+
@Test
125+
public void testPlugsHoles() throws Exception {
126+
TableName tn = TableName.valueOf(this.name.getMethodName());
127+
testPlugsHolesWithReadReplicaInternal(tn, 1);
128+
}
129+
130+
@Test
131+
public void testPlugsHolesWithReadReplica() throws Exception {
132+
TableName tn = TableName.valueOf(this.name.getMethodName());
133+
testPlugsHolesWithReadReplicaInternal(tn, 3);
134+
}
135+
123136
/**
124137
* Just make sure running fixMeta does right thing for the case
125138
* of a single-region Table where the region gets dropped.

0 commit comments

Comments
 (0)