下面列出了怎么用org.apache.hadoop.hbase.MetaTableAccessor的API类实例代码及写法,或者点击链接到github查看源代码。
private void offlineParentInMetaAndputMetaEntries(Connection conn,
HRegionInfo parent, HRegionInfo splitA, HRegionInfo splitB,
ServerName serverName, List<Mutation> metaEntries) throws IOException {
List<Mutation> mutations = metaEntries;
HRegionInfo copyOfParent = new HRegionInfo(parent);
copyOfParent.setOffline(true);
copyOfParent.setSplit(true);
//Put for parent
Put putParent = MetaTableAccessor.makePutFromRegionInfo(copyOfParent);
MetaTableAccessor.addDaughtersToPut(putParent, splitA, splitB);
mutations.add(putParent);
//Puts for daughters
Put putA = MetaTableAccessor.makePutFromRegionInfo(splitA);
Put putB = MetaTableAccessor.makePutFromRegionInfo(splitB);
addLocation(putA, serverName, 1); //these are new regions, openSeqNum = 1 is fine.
addLocation(putB, serverName, 1);
mutations.add(putA);
mutations.add(putB);
MetaTableAccessor.mutateMetaTable(conn, mutations);
}
/********************************* Master related hooks **********************************/
@Override
public void postStartMaster(ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException {
// Need to create the new system table for labels here
if (!MetaTableAccessor.tableExists(ctx.getEnvironment().getConnection(), LABELS_TABLE_NAME)) {
TableDescriptorBuilder.ModifyableTableDescriptor tableDescriptor =
new TableDescriptorBuilder.ModifyableTableDescriptor(LABELS_TABLE_NAME);
ColumnFamilyDescriptorBuilder.ModifyableColumnFamilyDescriptor familyDescriptor =
new ColumnFamilyDescriptorBuilder.ModifyableColumnFamilyDescriptor(LABELS_TABLE_FAMILY);
familyDescriptor.setBloomFilterType(BloomType.NONE);
// We will cache all the labels. No need of normal
// table block cache.
familyDescriptor.setBlockCacheEnabled(false);
tableDescriptor.setColumnFamily(familyDescriptor);
// Let the "labels" table having only one region always. We are not expecting too many labels in
// the system.
tableDescriptor.setValue(HTableDescriptor.SPLIT_POLICY,
DisabledRegionSplitPolicy.class.getName());
try (Admin admin = ctx.getEnvironment().getConnection().getAdmin()) {
admin.createTable(tableDescriptor);
}
}
}
/**
* Just make sure running fixMeta does right thing for the case
* of a single-region Table where the region gets dropped.
* There is nothing much we can do. We can't restore what
* we don't know about (at least from a read of hbase:meta).
*/
@Test
public void testOneRegionTable() throws IOException {
TableName tn = TableName.valueOf(this.name.getMethodName());
TEST_UTIL.createTable(tn, HConstants.CATALOG_FAMILY);
List<RegionInfo> ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);
MasterServices services = TEST_UTIL.getHBaseCluster().getMaster();
services.getCatalogJanitor().scan();
deleteRegion(services, ris.get(0));
services.getCatalogJanitor().scan();
CatalogJanitor.Report report = services.getCatalogJanitor().getLastReport();
ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);
assertTrue(ris.isEmpty());
MetaFixer fixer = new MetaFixer(services);
fixer.fixHoles(report);
report = services.getCatalogJanitor().getLastReport();
assertTrue(report.isEmpty());
ris = MetaTableAccessor.getTableRegions(TEST_UTIL.getConnection(), tn);
assertEquals(0, ris.size());
}
protected final void setLastPushedSequenceIdForTable(MasterProcedureEnv env, TableName tableName,
Map<String, Long> lastSeqIds) throws IOException, ReplicationException {
TableStateManager tsm = env.getMasterServices().getTableStateManager();
ReplicationQueueStorage queueStorage = env.getReplicationPeerManager().getQueueStorage();
Connection conn = env.getMasterServices().getConnection();
if (!needSetLastPushedSequenceId(tsm, tableName)) {
LOG.debug("Skip settting last pushed sequence id for {}", tableName);
return;
}
for (Pair<String, Long> name2Barrier : MetaTableAccessor
.getTableEncodedRegionNameAndLastBarrier(conn, tableName)) {
LOG.trace("Update last pushed sequence id for {}, {}", tableName, name2Barrier);
addToMap(lastSeqIds, name2Barrier.getFirst(), name2Barrier.getSecond().longValue() - 1,
queueStorage);
}
}
/**
* Return the region and current deployment for the region containing the given row. If the region
* cannot be found, returns null. If it is found, but not currently deployed, the second element
* of the pair may be null.
*/
private Pair<RegionInfo, ServerName> getTableRegionForRow(HMaster master, TableName tableName,
byte[] rowKey) throws IOException {
final AtomicReference<Pair<RegionInfo, ServerName>> result = new AtomicReference<>(null);
ClientMetaTableAccessor.Visitor visitor = new ClientMetaTableAccessor.Visitor() {
@Override
public boolean visit(Result data) throws IOException {
if (data == null || data.size() <= 0) {
return true;
}
Pair<RegionInfo, ServerName> pair = new Pair<>(CatalogFamilyFormat.getRegionInfo(data),
CatalogFamilyFormat.getServerName(data, 0));
if (!pair.getFirst().getTable().equals(tableName)) {
return false;
}
result.set(pair);
return true;
}
};
MetaTableAccessor.scanMeta(master.getConnection(), visitor, tableName, rowKey, 1);
return result.get();
}
/**
* For testing against a cluster.
* Doesn't have a MasterServices context so does not report on good vs bad servers.
*/
public static void main(String [] args) throws IOException {
checkLog4jProperties();
ReportMakingVisitor visitor = new ReportMakingVisitor(null);
Configuration configuration = HBaseConfiguration.create();
configuration.setBoolean("hbase.defaults.for.version.skip", true);
try (Connection connection = ConnectionFactory.createConnection(configuration)) {
/* Used to generate an overlap.
*/
Get g = new Get(Bytes.toBytes("t2,40,1564119846424.1db8c57d64e0733e0f027aaeae7a0bf0."));
g.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER);
try (Table t = connection.getTable(TableName.META_TABLE_NAME)) {
Result r = t.get(g);
byte [] row = g.getRow();
row[row.length - 2] <<= row[row.length - 2];
Put p = new Put(g.getRow());
p.addColumn(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER,
r.getValue(HConstants.CATALOG_FAMILY, HConstants.REGIONINFO_QUALIFIER));
t.put(p);
}
MetaTableAccessor.scanMetaForTableRegions(connection, visitor, null);
Report report = visitor.getReport();
LOG.info(report != null? report.toString(): "empty");
}
}
public void visitMeta(final RegionStateVisitor visitor) throws IOException {
MetaTableAccessor.fullScanRegions(master.getConnection(),
new ClientMetaTableAccessor.Visitor() {
final boolean isDebugEnabled = LOG.isDebugEnabled();
@Override
public boolean visit(final Result r) throws IOException {
if (r != null && !r.isEmpty()) {
long st = 0;
if (LOG.isTraceEnabled()) {
st = System.currentTimeMillis();
}
visitMetaEntry(visitor, r);
if (LOG.isTraceEnabled()) {
long et = System.currentTimeMillis();
LOG.trace("[T] LOAD META PERF " + StringUtils.humanTimeDiff(et - st));
}
} else if (isDebugEnabled) {
LOG.debug("NULL result from meta - ignoring but this is strange.");
}
return true;
}
});
}
private void waitAndVerifyRegionNum(HMaster master, TableName tablename,
int expectedRegionNum) throws Exception {
List<Pair<RegionInfo, ServerName>> tableRegionsInMeta;
List<RegionInfo> tableRegionsInMaster;
long timeout = System.currentTimeMillis() + waitTime;
while (System.currentTimeMillis() < timeout) {
tableRegionsInMeta =
MetaTableAccessor.getTableRegionsAndLocations(TEST_UTIL.getConnection(), tablename);
tableRegionsInMaster =
master.getAssignmentManager().getRegionStates().getRegionsOfTable(tablename);
LOG.info(Objects.toString(tableRegionsInMaster));
LOG.info(Objects.toString(tableRegionsInMeta));
int tableRegionsInMetaSize = tableRegionsInMeta.size();
int tableRegionsInMasterSize = tableRegionsInMaster.size();
if (tableRegionsInMetaSize == expectedRegionNum
&& tableRegionsInMasterSize == expectedRegionNum) {
break;
}
Thread.sleep(250);
}
tableRegionsInMeta = MetaTableAccessor.getTableRegionsAndLocations(
TEST_UTIL.getConnection(), tablename);
LOG.info("Regions after merge:" + Joiner.on(',').join(tableRegionsInMeta));
assertEquals(expectedRegionNum, tableRegionsInMeta.size());
}
/**
* Check hbase:namespace table is assigned. If not, startup will hang looking for the ns table
* <p/>
* This is for rolling upgrading, later we will migrate the data in ns table to the ns family of
* meta table. And if this is a new cluster, this method will return immediately as there will be
* no namespace table/region.
* @return True if namespace table is up/online.
*/
private boolean waitForNamespaceOnline() throws IOException {
TableState nsTableState =
MetaTableAccessor.getTableState(getConnection(), TableName.NAMESPACE_TABLE_NAME);
if (nsTableState == null || nsTableState.isDisabled()) {
// this means we have already migrated the data and disabled or deleted the namespace table,
// or this is a new deploy which does not have a namespace table from the beginning.
return true;
}
List<RegionInfo> ris =
this.assignmentManager.getRegionStates().getRegionsOfTable(TableName.NAMESPACE_TABLE_NAME);
if (ris.isEmpty()) {
// maybe this will not happen any more, but anyway, no harm to add a check here...
return true;
}
// Else there are namespace regions up in meta. Ensure they are assigned before we go on.
for (RegionInfo ri : ris) {
if (!isRegionOnline(ri)) {
return false;
}
}
return true;
}
/**
* There may be items for this table still up in hbase:meta in the case where the info:regioninfo
* column was empty because of some write error. Remove ALL rows from hbase:meta that have to do
* with this table. See HBASE-12980.
*/
private static void cleanRegionsInMeta(final MasterProcedureEnv env, final TableName tableName)
throws IOException {
Connection connection = env.getMasterServices().getConnection();
Scan tableScan = MetaTableAccessor.getScanForTableName(connection, tableName);
try (Table metaTable = connection.getTable(TableName.META_TABLE_NAME)) {
List<Delete> deletes = new ArrayList<>();
try (ResultScanner resScanner = metaTable.getScanner(tableScan)) {
for (Result result : resScanner) {
deletes.add(new Delete(result.getRow()));
}
}
if (!deletes.isEmpty()) {
LOG.warn("Deleting some vestigial " + deletes.size() + " rows of " + tableName + " from "
+ TableName.META_TABLE_NAME);
metaTable.delete(deletes);
}
}
}
protected RegionInfo createRegion(Configuration conf, final Table htbl,
byte[] startKey, byte[] endKey) throws IOException {
Table meta = TEST_UTIL.getConnection().getTable(TableName.META_TABLE_NAME);
RegionInfo hri = RegionInfoBuilder.newBuilder(htbl.getName())
.setStartKey(startKey)
.setEndKey(endKey)
.build();
LOG.info("manually adding regioninfo and hdfs data: " + hri.toString());
Path rootDir = CommonFSUtils.getRootDir(conf);
FileSystem fs = rootDir.getFileSystem(conf);
Path p = new Path(CommonFSUtils.getTableDir(rootDir, htbl.getName()),
hri.getEncodedName());
fs.mkdirs(p);
Path riPath = new Path(p, HRegionFileSystem.REGION_INFO_FILE);
FSDataOutputStream out = fs.create(riPath);
out.write(RegionInfo.toDelimitedByteArray(hri));
out.close();
// add to meta.
MetaTableAccessor.addRegionToMeta(TEST_UTIL.getConnection(), hri);
meta.close();
return hri;
}
@Test
public void testRegionNormalizationMerge() throws Exception {
final TableName tableName = TableName.valueOf(name.getMethodName());
try {
final int currentRegionCount = createTableBegsMerge(tableName);
assertFalse(admin.normalizerSwitch(true));
assertTrue(admin.normalize());
waitForTableMerge(tableName, currentRegionCount - 1);
assertEquals(
tableName + " should have merged.",
currentRegionCount - 1,
MetaTableAccessor.getRegionCount(TEST_UTIL.getConnection(), tableName));
} finally {
dropIfExists(tableName);
}
}
/**
* Return all tables in given states.
* @param states filter by states
* @return tables in given states
*/
Set<TableName> getTablesInStates(TableState.State... states) throws IOException {
// Only be called in region normalizer, will not use cache.
final Set<TableName> rv = Sets.newHashSet();
MetaTableAccessor.fullScanTables(master.getConnection(), new ClientMetaTableAccessor.Visitor() {
@Override
public boolean visit(Result r) throws IOException {
TableState tableState = CatalogFamilyFormat.getTableState(r);
if (tableState != null && tableState.inStates(states)) {
rv.add(tableState.getTableName());
}
return true;
}
});
return rv;
}
private void updateMetaState(TableName tableName, TableState.State newState) throws IOException {
if (tableName.equals(TableName.META_TABLE_NAME)) {
if (TableState.State.DISABLING.equals(newState) ||
TableState.State.DISABLED.equals(newState)) {
throw new IllegalArgumentIOException("Cannot disable meta table; " + newState);
}
// Otherwise, just return; no need to set ENABLED on meta -- it is always ENABLED.
return;
}
boolean succ = false;
try {
MetaTableAccessor.updateTableState(master.getConnection(), tableName, newState);
tableName2State.put(tableName, newState);
succ = true;
} finally {
if (!succ) {
this.tableName2State.remove(tableName);
}
}
metaStateUpdated(tableName, newState);
}
@Test
public void testCreateTableWithSingleReplica() throws Exception {
final int numRegions = 3;
final int numReplica = 1;
final TableName tableName = TableName.valueOf(name.getMethodName());
try {
TableDescriptor desc =
TableDescriptorBuilder.newBuilder(tableName).setRegionReplication(numReplica)
.setColumnFamily(ColumnFamilyDescriptorBuilder.of("family")).build();
ADMIN.createTable(desc, Bytes.toBytes("A"), Bytes.toBytes("Z"), numRegions);
TEST_UTIL.waitUntilAllRegionsAssigned(tableName);
TEST_UTIL.waitUntilNoRegionsInTransition();
validateNumberOfRowsInMeta(tableName, numRegions, ADMIN.getConnection());
List<RegionInfo> hris = MetaTableAccessor.getTableRegions(ADMIN.getConnection(), tableName);
assertEquals(numRegions * numReplica, hris.size());
} finally {
ADMIN.disableTable(tableName);
ADMIN.deleteTable(tableName);
}
}
/**
* Initialize namespace state cache by scanning meta table.
*/
private void initialize() throws IOException {
List<NamespaceDescriptor> namespaces = this.master.getClusterSchema().getNamespaces();
for (NamespaceDescriptor namespace : namespaces) {
addNamespace(namespace.getName());
List<TableName> tables = this.master.listTableNamesByNamespace(namespace.getName());
for (TableName table : tables) {
if (table.isSystemTable()) {
continue;
}
List<RegionInfo> regions =
MetaTableAccessor.getTableRegions(this.master.getConnection(), table, true);
addTable(table, regions.size());
}
}
LOG.info("Finished updating state of " + nsStateCache.size() + " namespaces. ");
initialized = true;
}
@Test
public void testSplitShouldNotHappenIfSplitIsDisabledForTable() throws Exception {
final TableName tableName = TableName.valueOf(name.getMethodName());
TableDescriptor htd = TableDescriptorBuilder.newBuilder(tableName)
.setRegionSplitPolicyClassName(DisabledRegionSplitPolicy.class.getName())
.setColumnFamily(ColumnFamilyDescriptorBuilder.of("f")).build();
Table table = TEST_UTIL.createTable(htd, null);
for (int i = 0; i < 10; i++) {
Put p = new Put(Bytes.toBytes("row" + i));
byte[] q1 = Bytes.toBytes("q1");
byte[] v1 = Bytes.toBytes("v1");
p.addColumn(Bytes.toBytes("f"), q1, v1);
table.put(p);
}
ADMIN.flush(tableName);
try {
ADMIN.split(tableName, Bytes.toBytes("row5"));
Threads.sleep(10000);
} catch (Exception e) {
// Nothing to do.
}
// Split should not happen.
List<RegionInfo> allRegions =
MetaTableAccessor.getTableRegions(ADMIN.getConnection(), tableName, true);
assertEquals(1, allRegions.size());
}
void testRegionNormalizationSplit(boolean limitedByQuota) throws Exception {
TableName tableName = null;
try {
tableName = limitedByQuota
? buildTableNameForQuotaTest(name.getMethodName())
: TableName.valueOf(name.getMethodName());
final int currentRegionCount = createTableBegsSplit(tableName, true, false);
final long existingSkippedSplitCount = master.getRegionNormalizer()
.getSkippedCount(PlanType.SPLIT);
assertFalse(admin.normalizerSwitch(true));
assertTrue(admin.normalize());
if (limitedByQuota) {
waitForSkippedSplits(master, existingSkippedSplitCount);
assertEquals(
tableName + " should not have split.",
currentRegionCount,
MetaTableAccessor.getRegionCount(TEST_UTIL.getConnection(), tableName));
} else {
waitForTableSplit(tableName, currentRegionCount + 1);
assertEquals(
tableName + " should have split.",
currentRegionCount + 1,
MetaTableAccessor.getRegionCount(TEST_UTIL.getConnection(), tableName));
}
} finally {
dropIfExists(tableName);
}
}
/**
* Update meta table with favored nodes info
* @param regionToFavoredNodes map of RegionInfo's to their favored nodes
* @param connection connection to be used
* @throws IOException
*/
public static void updateMetaWithFavoredNodesInfo(
Map<RegionInfo, List<ServerName>> regionToFavoredNodes,
Connection connection) throws IOException {
List<Put> puts = new ArrayList<>();
for (Map.Entry<RegionInfo, List<ServerName>> entry : regionToFavoredNodes.entrySet()) {
Put put = makePutFromRegionInfo(entry.getKey(), entry.getValue());
if (put != null) {
puts.add(put);
}
}
MetaTableAccessor.putsToMetaTable(connection, puts);
LOG.info("Added " + puts.size() + " regions in META");
}
private boolean isParentFinished(byte[] regionName) throws IOException {
long[] barriers = MetaTableAccessor.getReplicationBarrier(conn, regionName);
if (barriers.length == 0) {
return true;
}
return isRangeFinished(barriers[barriers.length - 1], RegionInfo.encodeRegionName(regionName));
}
/**
* Scan hbase:meta.
* @return Return generated {@link Report}
*/
Report scanForReport() throws IOException {
ReportMakingVisitor visitor = new ReportMakingVisitor(this.services);
// Null tablename means scan all of meta.
MetaTableAccessor.scanMetaForTableRegions(this.services.getConnection(), visitor, null);
return visitor.getReport();
}
/**
* Checks if the specified region has merge qualifiers, if so, try to clean them.
* @return true if no info:merge* columns; i.e. the specified region doesn't have
* any merge qualifiers.
*/
public boolean cleanMergeQualifier(final RegionInfo region) throws IOException {
// Get merge regions if it is a merged region and already has merge qualifier
List<RegionInfo> parents = MetaTableAccessor.getMergeRegions(this.services.getConnection(),
region.getRegionName());
if (parents == null || parents.isEmpty()) {
// It doesn't have merge qualifier, no need to clean
return true;
}
// If a parent region is a merged child region and GC has not kicked in/finish its work yet,
// return false in this case to avoid kicking in a merge, trying later.
cleanMergeRegion(region, parents);
return false;
}
private static void waitForTableSplit(final TableName tableName, final int targetRegionCount)
throws IOException {
TEST_UTIL.waitFor(TimeUnit.MINUTES.toMillis(5), new ExplainingPredicate<IOException>() {
@Override public String explainFailure() {
return "expected normalizer to split region.";
}
@Override public boolean evaluate() throws IOException {
final int currentRegionCount =
MetaTableAccessor.getRegionCount(TEST_UTIL.getConnection(), tableName);
return currentRegionCount >= targetRegionCount;
}
});
}
private static void waitForTableRegionCount(final TableName tableName,
final int targetRegionCount) throws IOException {
TEST_UTIL.waitFor(TimeUnit.MINUTES.toMillis(5), new ExplainingPredicate<IOException>() {
@Override
public String explainFailure() {
return "expected " + targetRegionCount + " number of regions for table " + tableName;
}
@Override
public boolean evaluate() throws IOException {
final int currentRegionCount =
MetaTableAccessor.getRegionCount(TEST_UTIL.getConnection(), tableName);
return currentRegionCount == targetRegionCount;
}
});
}
/**
* Queries META table for the passed region encoded name,
* delegating action upon results to the <code>RegionStateVisitor</code>
* passed as second parameter.
* @param regionEncodedName encoded name for the Region we want to query META for.
* @param visitor The <code>RegionStateVisitor</code> instance to react over the query results.
* @throws IOException If some error occurs while querying META or parsing results.
*/
public void visitMetaForRegion(final String regionEncodedName, final RegionStateVisitor visitor)
throws IOException {
Result result = MetaTableAccessor.
scanByRegionEncodedName(master.getConnection(), regionEncodedName);
if (result != null) {
visitMetaEntry(visitor, result);
}
}
private void visitMetaEntry(final RegionStateVisitor visitor, final Result result)
throws IOException {
final RegionLocations rl = CatalogFamilyFormat.getRegionLocations(result);
if (rl == null) return;
final HRegionLocation[] locations = rl.getRegionLocations();
if (locations == null) return;
for (int i = 0; i < locations.length; ++i) {
final HRegionLocation hrl = locations[i];
if (hrl == null) continue;
final RegionInfo regionInfo = hrl.getRegion();
if (regionInfo == null) continue;
final int replicaId = regionInfo.getReplicaId();
final State state = getRegionState(result, regionInfo);
final ServerName lastHost = hrl.getServerName();
ServerName regionLocation = MetaTableAccessor.getTargetServerName(result, replicaId);
final long openSeqNum = hrl.getSeqNum();
// TODO: move under trace, now is visible for debugging
LOG.info(
"Load hbase:meta entry region={}, regionState={}, lastHost={}, " +
"regionLocation={}, openSeqNum={}",
regionInfo.getEncodedName(), state, lastHost, regionLocation, openSeqNum);
visitor.visitRegionState(result, regionInfo, state, regionLocation, lastHost, openSeqNum);
}
}
public void splitRegion(RegionInfo parent, RegionInfo hriA, RegionInfo hriB,
ServerName serverName) throws IOException {
TableDescriptor htd = getDescriptor(parent.getTable());
long parentOpenSeqNum = HConstants.NO_SEQNUM;
if (htd.hasGlobalReplicationScope()) {
parentOpenSeqNum = getOpenSeqNumForParentRegion(parent);
}
MetaTableAccessor.splitRegion(master.getConnection(), parent, parentOpenSeqNum, hriA, hriB,
serverName, getRegionReplication(htd));
}
private static int countMetaRegions(final HMaster master, final TableName tableName)
throws IOException {
final AtomicInteger actualRegCount = new AtomicInteger(0);
final ClientMetaTableAccessor.Visitor visitor = new ClientMetaTableAccessor.Visitor() {
@Override
public boolean visit(Result rowResult) throws IOException {
RegionLocations list = CatalogFamilyFormat.getRegionLocations(rowResult);
if (list == null) {
LOG.warn("No serialized RegionInfo in " + rowResult);
return true;
}
HRegionLocation l = list.getRegionLocation();
if (l == null) {
return true;
}
if (!l.getRegion().getTable().equals(tableName)) {
return false;
}
if (l.getRegion().isOffline() || l.getRegion().isSplit()) {
return true;
}
HRegionLocation[] locations = list.getRegionLocations();
for (HRegionLocation location : locations) {
if (location == null) continue;
ServerName serverName = location.getServerName();
// Make sure that regions are assigned to server
if (serverName != null && serverName.getAddress() != null) {
actualRegCount.incrementAndGet();
}
}
return true;
}
};
MetaTableAccessor.scanMetaForTableRegions(master.getConnection(), visitor, tableName);
return actualRegCount.get();
}
/**
* create a table with 5 regions, having region sizes so as to provoke a split
* of the largest region.
* <ul>
* <li>total table size: 12</li>
* <li>average region size: 2.4</li>
* <li>split threshold: 2.4 * 2 = 4.8</li>
* </ul>
*/
private static int createTableBegsSplit(final TableName tableName,
final boolean normalizerEnabled, final boolean isMergeEnabled)
throws IOException {
final List<HRegion> generatedRegions = generateTestData(tableName, 1, 1, 2, 3, 5);
assertEquals(5, MetaTableAccessor.getRegionCount(TEST_UTIL.getConnection(), tableName));
admin.flush(tableName);
final TableDescriptor td = TableDescriptorBuilder.newBuilder(admin.getDescriptor(tableName))
.setNormalizationEnabled(normalizerEnabled)
.setMergeEnabled(isMergeEnabled)
.build();
admin.modifyTable(td);
// make sure relatively accurate region statistics are available for the test table. use
// the last/largest region as clue.
TEST_UTIL.waitFor(TimeUnit.MINUTES.toMillis(1), new ExplainingPredicate<IOException>() {
@Override public String explainFailure() {
return "expected largest region to be >= 4mb.";
}
@Override public boolean evaluate() {
return generatedRegions.stream()
.mapToDouble(val -> getRegionSizeMB(master, val.getRegionInfo()))
.allMatch(val -> val > 0)
&& getRegionSizeMB(master, generatedRegions.get(4).getRegionInfo()) >= 4.0;
}
});
return 5;
}
private RegionReplicaInfo(final Result result, final HRegionLocation location) {
this.row = result != null ? result.getRow() : null;
this.regionInfo = location != null ? location.getRegion() : null;
this.regionState = (result != null && regionInfo != null)
? RegionStateStore.getRegionState(result, regionInfo)
: null;
this.serverName = location != null ? location.getServerName() : null;
this.seqNum = (location != null) ? location.getSeqNum() : HConstants.NO_SEQNUM;
this.targetServerName = (result != null && regionInfo != null)
? MetaTableAccessor.getTargetServerName(result, regionInfo.getReplicaId())
: null;
this.mergeRegionInfo = (result != null)
? MetaTableAccessor.getMergeRegionsWithName(result.rawCells())
: null;
if (result != null) {
PairOfSameType<RegionInfo> daughterRegions = MetaTableAccessor.getDaughterRegions(result);
this.splitRegionInfo = new LinkedHashMap<>();
if (daughterRegions.getFirst() != null) {
splitRegionInfo.put(HConstants.SPLITA_QUALIFIER_STR, daughterRegions.getFirst());
}
if (daughterRegions.getSecond() != null) {
splitRegionInfo.put(HConstants.SPLITB_QUALIFIER_STR, daughterRegions.getSecond());
}
} else {
this.splitRegionInfo = null;
}
}