下面列出了怎么用org.apache.hadoop.hbase.client.RegionInfoBuilder的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void testListLocksRegion() throws Exception {
LockProcedure procedure = createExclusiveLockProcedure(3);
RegionInfo regionInfo =
RegionInfoBuilder.newBuilder(TableName.valueOf("ns3", "table3")).build();
queue.waitRegion(procedure, regionInfo);
List<LockedResource> resources = queue.getLocks();
assertEquals(3, resources.size());
LockedResource namespaceResource = resources.get(0);
assertLockResource(namespaceResource, LockedResourceType.NAMESPACE, "ns3");
assertSharedLock(namespaceResource, 1);
assertTrue(namespaceResource.getWaitingProcedures().isEmpty());
LockedResource tableResource = resources.get(1);
assertLockResource(tableResource, LockedResourceType.TABLE, "ns3:table3");
assertSharedLock(tableResource, 1);
assertTrue(tableResource.getWaitingProcedures().isEmpty());
LockedResource regionResource = resources.get(2);
assertLockResource(regionResource, LockedResourceType.REGION, regionInfo.getEncodedName());
assertExclusiveLock(regionResource, procedure);
assertTrue(regionResource.getWaitingProcedures().isEmpty());
}
@BeforeClass
public static void setUpBeforeClass() throws Exception {
TableDescriptorBuilder.ModifyableTableDescriptor tableDescriptor =
new TableDescriptorBuilder.ModifyableTableDescriptor(TABLE_NAME);
for (byte[] family : FAMILIES) {
ColumnFamilyDescriptorBuilder.ModifyableColumnFamilyDescriptor familyDescriptor =
new ColumnFamilyDescriptorBuilder.ModifyableColumnFamilyDescriptor(family);
tableDescriptor.setColumnFamily(familyDescriptor);
}
RegionInfo info = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build();
REGION = HBaseTestingUtility.createRegionAndWAL(info, TEST_UTIL.getDataTestDir(),
TEST_UTIL.getConfiguration(), tableDescriptor);
for(Put put:createPuts(ROWS, FAMILIES, QUALIFIERS, VALUE)){
REGION.put(put);
}
}
/**
* Callers must afterward call {@link HBaseTestingUtility#closeRegionAndWAL(HRegion)}
*/
private HRegion initHRegion(byte[] tableName, String callingMethod, Configuration conf,
String family, BlockCache blockCache) throws IOException {
TableDescriptorBuilder builder =
TableDescriptorBuilder.newBuilder(TableName.valueOf(tableName));
for (int i = 0; i < BLOOM_TYPE.length; i++) {
BloomType bloomType = BLOOM_TYPE[i];
builder.setColumnFamily(
ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(family + "_" + bloomType))
.setBlocksize(1).setBloomFilterType(bloomType).build());
}
RegionInfo info = RegionInfoBuilder.newBuilder(TableName.valueOf(tableName)).build();
Path path = new Path(DIR + callingMethod);
if (blockCache != null) {
return HBaseTestingUtility.createRegionAndWAL(info, path, conf, builder.build(), blockCache);
} else {
return HBaseTestingUtility.createRegionAndWAL(info, path, conf, builder.build());
}
}
@Test
public void testCustomParts() throws Exception {
Configuration conf = HBaseConfiguration.create();
conf.set(DefaultStoreEngine.DEFAULT_COMPACTOR_CLASS_KEY, DummyCompactor.class.getName());
conf.set(DefaultStoreEngine.DEFAULT_COMPACTION_POLICY_CLASS_KEY,
DummyCompactionPolicy.class.getName());
conf.set(DefaultStoreEngine.DEFAULT_STORE_FLUSHER_CLASS_KEY,
DummyStoreFlusher.class.getName());
HStore mockStore = Mockito.mock(HStore.class);
Mockito.when(mockStore.getRegionInfo()).thenReturn(RegionInfoBuilder.FIRST_META_REGIONINFO);
StoreEngine<?, ?, ?, ?> se = StoreEngine.create(mockStore, conf, CellComparatorImpl.COMPARATOR);
Assert.assertTrue(se instanceof DefaultStoreEngine);
Assert.assertTrue(se.getCompactionPolicy() instanceof DummyCompactionPolicy);
Assert.assertTrue(se.getStoreFlusher() instanceof DummyStoreFlusher);
Assert.assertTrue(se.getCompactor() instanceof DummyCompactor);
}
private static HRegion bootstrap(Configuration conf, TableDescriptor td, FileSystem fs,
Path rootDir, FileSystem walFs, Path walRootDir, WALFactory walFactory,
MasterRegionWALRoller walRoller, String serverName) throws IOException {
TableName tn = td.getTableName();
RegionInfo regionInfo = RegionInfoBuilder.newBuilder(tn).setRegionId(REGION_ID).build();
Path tmpTableDir = CommonFSUtils.getTableDir(rootDir,
TableName.valueOf(tn.getNamespaceAsString(), tn.getQualifierAsString() + "-tmp"));
if (fs.exists(tmpTableDir) && !fs.delete(tmpTableDir, true)) {
throw new IOException("Can not delete partial created proc region " + tmpTableDir);
}
HRegion.createHRegion(conf, regionInfo, fs, tmpTableDir, td).close();
Path tableDir = CommonFSUtils.getTableDir(rootDir, tn);
if (!fs.rename(tmpTableDir, tableDir)) {
throw new IOException("Can not rename " + tmpTableDir + " to " + tableDir);
}
WAL wal = createWAL(walFactory, walRoller, serverName, walFs, walRootDir, regionInfo);
return HRegion.openHRegionFromTableDir(conf, fs, tableDir, regionInfo, td, wal, null, null);
}
@Test
public void testRegionOpenProcedureIsNotHandledByDispatcher() throws Exception {
TableName tableName = TableName.valueOf("testRegionOpenProcedureIsNotHandledByDisPatcher");
RegionInfo hri = RegionInfoBuilder.newBuilder(tableName).setStartKey(Bytes.toBytes(1))
.setEndKey(Bytes.toBytes(2)).setSplit(false).setRegionId(0).build();
MasterProcedureEnv env = master.getMasterProcedureExecutor().getEnvironment();
env.getAssignmentManager().getRegionStates().getOrCreateRegionStateNode(hri);
TransitRegionStateProcedure proc = TransitRegionStateProcedure.assign(env, hri, null);
ServerName worker = master.getServerManager().getOnlineServersList().get(0);
OpenRegionProcedure openRegionProcedure = new OpenRegionProcedure(proc, hri, worker);
Future<byte[]> future = submitProcedure(openRegionProcedure);
Thread.sleep(2000);
rsDispatcher.removeNode(worker);
try {
future.get(2000, TimeUnit.MILLISECONDS);
fail();
} catch (TimeoutException e) {
LOG.info("timeout is expected");
}
Assert.assertFalse(openRegionProcedure.isFinished());
}
private static void writeFsLayout(Path rootDir, Configuration conf) throws IOException {
LOG.info("BOOTSTRAP: creating hbase:meta region");
FileSystem fs = rootDir.getFileSystem(conf);
Path tableDir = CommonFSUtils.getTableDir(rootDir, TableName.META_TABLE_NAME);
if (fs.exists(tableDir) && !fs.delete(tableDir, true)) {
LOG.warn("Can not delete partial created meta table, continue...");
}
// Bootstrapping, make sure blockcache is off. Else, one will be
// created here in bootstrap and it'll need to be cleaned up. Better to
// not make it in first place. Turn off block caching for bootstrap.
// Enable after.
FSTableDescriptors.tryUpdateMetaTableDescriptor(conf, fs, rootDir,
builder -> builder.setRegionReplication(
conf.getInt(HConstants.META_REPLICAS_NUM, HConstants.DEFAULT_META_REPLICA_NUM)));
TableDescriptor metaDescriptor = new FSTableDescriptors(conf).get(TableName.META_TABLE_NAME);
HRegion
.createHRegion(RegionInfoBuilder.FIRST_META_REGIONINFO, rootDir, conf, metaDescriptor, null)
.close();
}
/**
* There is a hole in the hdfs regions that violates the table integrity
* rules. Create a new empty region that patches the hole.
*/
@Override
public void handleHoleInRegionChain(byte[] holeStartKey, byte[] holeStopKey)
throws IOException {
errors.reportError(HbckErrorReporter.ERROR_CODE.HOLE_IN_REGION_CHAIN,
"There is a hole in the region chain between " + Bytes.toStringBinary(holeStartKey) +
" and " + Bytes.toStringBinary(holeStopKey) +
". Creating a new regioninfo and region " + "dir in hdfs to plug the hole.");
TableDescriptor htd = getTableInfo().getTableDescriptor();
RegionInfo newRegion =
RegionInfoBuilder.newBuilder(htd.getTableName()).setStartKey(holeStartKey)
.setEndKey(holeStopKey).build();
HRegion region = HBaseFsckRepair.createHDFSRegionDir(conf, newRegion, htd);
LOG.info("Plugged hole by creating new empty region: " + newRegion + " " + region);
hbck.fixes++;
}
/**
* Reset the split parent region info in meta table
*/
private void resetSplitParent(HbckRegionInfo hi) throws IOException {
RowMutations mutations = new RowMutations(hi.getMetaEntry().getRegionInfo().getRegionName());
Delete d = new Delete(hi.getMetaEntry().getRegionInfo().getRegionName());
d.addColumn(HConstants.CATALOG_FAMILY, HConstants.SPLITA_QUALIFIER);
d.addColumn(HConstants.CATALOG_FAMILY, HConstants.SPLITB_QUALIFIER);
mutations.add(d);
RegionInfo hri = RegionInfoBuilder.newBuilder(hi.getMetaEntry().getRegionInfo())
.setOffline(false).setSplit(false).build();
Put p = MetaTableAccessor.makePutFromRegionInfo(hri, EnvironmentEdgeManager.currentTime());
mutations.add(p);
meta.mutateRow(mutations);
LOG.info("Reset split parent " + hi.getMetaEntry().getRegionInfo().getRegionNameAsString() +
" in META");
}
@Before
public void setUp() throws IOException {
conf = HBaseConfiguration.create();
region = mock(HRegion.class);
HStore store = mock(HStore.class);
when(store.getStorefilesCount()).thenReturn(1);
when(region.getStores()).thenReturn(Collections.singletonList(store));
when(region.getRegionInfo())
.thenReturn(RegionInfoBuilder.newBuilder(TableName.valueOf("hbase:local")).build());
flushCalled = new AtomicInteger(0);
memstoreHeapSize = new AtomicLong(0);
memstoreOffHeapSize = new AtomicLong(0);
when(region.getMemStoreHeapSize()).thenAnswer(invocation -> memstoreHeapSize.get());
when(region.getMemStoreOffHeapSize()).thenAnswer(invocation -> memstoreOffHeapSize.get());
when(region.flush(anyBoolean())).thenAnswer(invocation -> {
assertTrue(invocation.getArgument(0));
memstoreHeapSize.set(0);
memstoreOffHeapSize.set(0);
flushCalled.incrementAndGet();
return null;
});
}
@Test
public void testReadAndWriteRegionInfoFile() throws IOException, InterruptedException {
RegionInfo ri = RegionInfoBuilder.FIRST_META_REGIONINFO;
// Create a region. That'll write the .regioninfo file.
FSTableDescriptors fsTableDescriptors = new FSTableDescriptors(FS, ROOT_DIR);
FSTableDescriptors.tryUpdateMetaTableDescriptor(CONF, FS, ROOT_DIR, null);
HRegion r = HBaseTestingUtility.createRegionAndWAL(ri, ROOT_DIR, CONF,
fsTableDescriptors.get(TableName.META_TABLE_NAME));
// Get modtime on the file.
long modtime = getModTime(r);
HBaseTestingUtility.closeRegionAndWAL(r);
Thread.sleep(1001);
r = HRegion.openHRegion(ROOT_DIR, ri, fsTableDescriptors.get(TableName.META_TABLE_NAME), null,
CONF);
// Ensure the file is not written for a second time.
long modtime2 = getModTime(r);
assertEquals(modtime, modtime2);
// Now load the file.
HRegionFileSystem.loadRegionInfoFileContent(r.getRegionFileSystem().getFileSystem(),
r.getRegionFileSystem().getRegionDir());
HBaseTestingUtility.closeRegionAndWAL(r);
}
@Test
public void testSystemTableWALEntryFilter() {
SystemTableWALEntryFilter filter = new SystemTableWALEntryFilter();
// meta
WALKeyImpl key1 =
new WALKeyImpl(RegionInfoBuilder.FIRST_META_REGIONINFO.getEncodedNameAsBytes(),
TableName.META_TABLE_NAME, System.currentTimeMillis());
Entry metaEntry = new Entry(key1, null);
assertNull(filter.filter(metaEntry));
// user table
WALKeyImpl key3 = new WALKeyImpl(new byte[0], TableName.valueOf("foo"),
System.currentTimeMillis());
Entry userEntry = new Entry(key3, null);
assertEquals(userEntry, filter.filter(userEntry));
}
private HRegion initHRegion(TableDescriptor htd, byte[] startKey, byte[] stopKey, int replicaId)
throws IOException {
Configuration conf = TEST_UTIL.getConfiguration();
conf.set("hbase.wal.provider", walProvider);
conf.setBoolean("hbase.hregion.mvcc.preassign", false);
Path tableDir = CommonFSUtils.getTableDir(testDir, htd.getTableName());
RegionInfo info = RegionInfoBuilder.newBuilder(htd.getTableName()).setStartKey(startKey)
.setEndKey(stopKey).setReplicaId(replicaId).setRegionId(0).build();
fileSystem = tableDir.getFileSystem(conf);
final Configuration walConf = new Configuration(conf);
CommonFSUtils.setRootDir(walConf, tableDir);
this.walConf = walConf;
wals = new WALFactory(walConf, "log_" + replicaId);
ChunkCreator.initialize(MemStoreLABImpl.CHUNK_SIZE_DEFAULT, false, 0, 0, 0, null);
HRegion region = HRegion.createHRegion(info, TEST_UTIL.getDefaultRootDirPath(), conf, htd,
wals.getWAL(info));
return region;
}
/**
* Write a file and then assert that we can read from top and bottom halves using two
* HalfMapFiles.
*/
@Test
public void testBasicHalfMapFile() throws Exception {
final RegionInfo hri =
RegionInfoBuilder.newBuilder(TableName.valueOf("testBasicHalfMapFileTb")).build();
HRegionFileSystem regionFs = HRegionFileSystem.createRegionOnFileSystem(conf, fs,
new Path(testDir, hri.getTable().getNameAsString()), hri);
HFileContext meta = new HFileContextBuilder().withBlockSize(2 * 1024).build();
StoreFileWriter writer = new StoreFileWriter.Builder(conf, cacheConf, this.fs)
.withFilePath(regionFs.createTempName()).withFileContext(meta).build();
writeStoreFile(writer);
Path sfPath = regionFs.commitStoreFile(TEST_FAMILY, writer.getPath());
HStoreFile sf = new HStoreFile(this.fs, sfPath, conf, cacheConf, BloomType.NONE, true);
checkHalfHFile(regionFs, sf);
}
@Test
public void testForSplitParent() throws Exception {
TableName tableName = TableName.valueOf("testForSplitParent");
RegionInfo hri = RegionInfoBuilder.newBuilder(tableName).setStartKey(Bytes.toBytes(0))
.setEndKey(Bytes.toBytes(1)).setSplit(true).setOffline(true).setRegionId(0).build();
String regionName = hri.getEncodedName();
rsDispatcher.setMockRsExecutor(new GoodRsExecutor());
Future<byte[]> future = submitProcedure(createAssignProcedure(hri));
waitOnFuture(future);
List<ServerName> serverNames = master.getServerManager().getOnlineServersList();
assertEquals(NSERVERS, serverNames.size());
hbckChore.choreForTesting();
Map<String, Pair<ServerName, List<ServerName>>> inconsistentRegions =
hbckChore.getInconsistentRegions();
assertFalse(inconsistentRegions.containsKey(regionName));
}
HRegion initHRegion(byte[] tableName, String callingMethod, Configuration conf,
byte[]... families) throws IOException {
TableDescriptorBuilder.ModifyableTableDescriptor tableDescriptor =
new TableDescriptorBuilder.ModifyableTableDescriptor(TableName.valueOf(tableName));
for (byte[] family : families) {
tableDescriptor.setColumnFamily(
new ColumnFamilyDescriptorBuilder.ModifyableColumnFamilyDescriptor(family));
}
ChunkCreator.initialize(MemStoreLABImpl.CHUNK_SIZE_DEFAULT, false, 0, 0, 0, null);
RegionInfo info = RegionInfoBuilder.newBuilder(tableDescriptor.getTableName()).build();
Path path = new Path(DIR + callingMethod);
WAL wal = HBaseTestingUtility.createWal(conf, path, info);
HRegion r = HRegion.createHRegion(info, path, conf, tableDescriptor, wal);
// this following piece is a hack. currently a coprocessorHost
// is secretly loaded at OpenRegionHandler. we don't really
// start a region server here, so just manually create cphost
// and set it to region.
RegionCoprocessorHost host = new RegionCoprocessorHost(r, null, conf);
r.setCoprocessorHost(host);
return r;
}
/**
* HRegionLocations are equal if they have the same 'location' -- i.e. host and port -- even if
* they are carrying different regions. Verify that is indeed the case.
*/
@Test
public void testHashAndEqualsCode() {
ServerName hsa1 = ServerName.valueOf("localhost", 1234, -1L);
HRegionLocation hrl1 = new HRegionLocation(RegionInfoBuilder.FIRST_META_REGIONINFO, hsa1);
HRegionLocation hrl2 = new HRegionLocation(RegionInfoBuilder.FIRST_META_REGIONINFO, hsa1);
assertEquals(hrl1.hashCode(), hrl2.hashCode());
assertTrue(hrl1.equals(hrl2));
HRegionLocation hrl3 = new HRegionLocation(RegionInfoBuilder.FIRST_META_REGIONINFO, hsa1);
assertNotSame(hrl1, hrl3);
// They are equal because they have same location even though they are
// carrying different regions or timestamp.
assertTrue(hrl1.equals(hrl3));
ServerName hsa2 = ServerName.valueOf("localhost", 12345, -1L);
HRegionLocation hrl4 = new HRegionLocation(RegionInfoBuilder.FIRST_META_REGIONINFO, hsa2);
// These have same HRI but different locations so should be different.
assertFalse(hrl3.equals(hrl4));
HRegionLocation hrl5 =
new HRegionLocation(hrl4.getRegion(), hrl4.getServerName(), hrl4.getSeqNum() + 1);
assertTrue(hrl4.equals(hrl5));
}
@Test
public void testReadFailuresOnly() throws IOException {
CanaryTool.RegionStdOutSink regionStdOutSink = new CanaryTool.RegionStdOutSink();
ServerName serverName1 = ServerName.valueOf("staging-st04.server:22600",
1584180761635L);
TableName fakeTableName1 = TableName.valueOf("fakeTableName1");
RegionInfo regionInfo1 = RegionInfoBuilder.newBuilder(fakeTableName1).build();
regionStdOutSink.publishReadFailure(serverName1, regionInfo1, new IOException());
CanaryStatusTmpl tmpl = new CanaryStatusTmpl();
StringWriter renderResultWriter = new StringWriter();
tmpl.render(renderResultWriter, regionStdOutSink);
String renderResult = renderResultWriter.toString();
Assert.assertTrue(renderResult.contains("staging-st04.server,22600"));
Assert.assertTrue(renderResult.contains("fakeTableName1"));
}
@Before
public void setUp() throws Exception {
TableDescriptor htd = TableDescriptorBuilder
.newBuilder(TableName.valueOf("TestQualifierFilter"))
.setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(FAMILY).build()).build();
RegionInfo info = RegionInfoBuilder.newBuilder(htd.getTableName()).build();
this.region = HBaseTestingUtility
.createRegionAndWAL(info, TEST_UTIL.getDataTestDir(), TEST_UTIL.getConfiguration(), htd);
// Insert data
for (byte[] ROW : ROWS) {
Put p = new Put(ROW);
p.setDurability(Durability.SKIP_WAL);
for (byte[] QUALIFIER : QUALIFIERS) {
p.addColumn(FAMILY, QUALIFIER, VALUE);
}
this.region.put(p);
}
// Flush
this.region.flush(true);
}
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;
}
private HRegion initHRegion(TableDescriptor htd, byte[] startKey, byte[] stopKey, int replicaId)
throws IOException {
Configuration conf = TEST_UTIL.getConfiguration();
Path tableDir = CommonFSUtils.getTableDir(testDir, htd.getTableName());
RegionInfo info = RegionInfoBuilder.newBuilder(htd.getTableName()).setStartKey(startKey)
.setEndKey(stopKey).setRegionId(0L).setReplicaId(replicaId).build();
HRegionFileSystem fs =
new FailingHRegionFileSystem(conf, tableDir.getFileSystem(conf), tableDir, info);
final Configuration walConf = new Configuration(conf);
CommonFSUtils.setRootDir(walConf, tableDir);
final WALFactory wals = new WALFactory(walConf, "log_" + replicaId);
ChunkCreator.initialize(MemStoreLABImpl.CHUNK_SIZE_DEFAULT, false, 0, 0, 0, null);
HRegion region =
new HRegion(fs, wals.getWAL(info),
conf, htd, null);
region.initialize();
return region;
}
/**
* It is possible that when AM send assign meta request to a RS successfully, but RS can not send
* back any response, which cause master startup hangs forever
*/
@Test
public void testAssignMetaAndCrashBeforeResponse() throws Exception {
tearDown();
// See setUp(), start HBase until set up meta
util = new HBaseTestingUtility();
this.executor = Executors.newSingleThreadScheduledExecutor();
setupConfiguration(util.getConfiguration());
master = new MockMasterServices(util.getConfiguration(), this.regionsToRegionServers);
rsDispatcher = new MockRSProcedureDispatcher(master);
master.start(NSERVERS, rsDispatcher);
am = master.getAssignmentManager();
// Assign meta
rsDispatcher.setMockRsExecutor(new HangThenRSRestartExecutor());
am.assign(RegionInfoBuilder.FIRST_META_REGIONINFO);
assertEquals(true, am.isMetaAssigned());
// set it back as default, see setUpMeta()
am.wakeMetaLoadedEvent();
}
@Test
public void testMetaLocationForRegionReplicasIsAddedAtTableCreation() throws IOException {
long regionId = System.currentTimeMillis();
RegionInfo primary = RegionInfoBuilder.newBuilder(TableName.valueOf(name.getMethodName()))
.setStartKey(HConstants.EMPTY_START_ROW).setEndKey(HConstants.EMPTY_END_ROW).setSplit(false)
.setRegionId(regionId).setReplicaId(0).build();
Table meta = MetaTableAccessor.getMetaHTable(connection);
try {
List<RegionInfo> regionInfos = Lists.newArrayList(primary);
MetaTableAccessor.addRegionsToMeta(connection, regionInfos, 3);
assertEmptyMetaLocation(meta, primary.getRegionName(), 1);
assertEmptyMetaLocation(meta, primary.getRegionName(), 2);
} finally {
meta.close();
}
}
private RegionInfo createRegionInfo(String table){
long regionTS = System.currentTimeMillis();
RegionInfo info = RegionInfoBuilder.newBuilder(TableName.valueOf(table))
.setRegionId(regionTS)
.build();
return info;
}
/**
* Create merged region info by looking at passed in <code>regionsToMerge</code>
* to figure what extremes for start and end keys to use; merged region needs
* to have an extent sufficient to cover all regions-to-merge.
*/
private static RegionInfo createMergedRegionInfo(final RegionInfo[] regionsToMerge) {
byte [] lowestStartKey = null;
byte [] highestEndKey = null;
// Region Id is a timestamp. Merged region's id can't be less than that of
// merging regions else will insert at wrong location in hbase:meta (See HBASE-710).
long highestRegionId = -1;
for (RegionInfo ri: regionsToMerge) {
if (lowestStartKey == null) {
lowestStartKey = ri.getStartKey();
} else if (Bytes.compareTo(ri.getStartKey(), lowestStartKey) < 0) {
lowestStartKey = ri.getStartKey();
}
if (highestEndKey == null) {
highestEndKey = ri.getEndKey();
} else if (ri.isLast() || Bytes.compareTo(ri.getEndKey(), highestEndKey) > 0) {
highestEndKey = ri.getEndKey();
}
highestRegionId = ri.getRegionId() > highestRegionId? ri.getRegionId(): highestRegionId;
}
// Merged region is sorted between two merging regions in META
return RegionInfoBuilder.newBuilder(regionsToMerge[0].getTable()).
setStartKey(lowestStartKey).
setEndKey(highestEndKey).
setSplit(false).
setRegionId(highestRegionId + 1/*Add one so new merged region is highest*/).
build();
}
public SplitTableRegionProcedure(final MasterProcedureEnv env,
final RegionInfo regionToSplit, final byte[] splitRow) throws IOException {
super(env, regionToSplit);
preflightChecks(env, true);
// When procedure goes to run in its prepare step, it also does these checkOnline checks. Here
// we fail-fast on construction. There it skips the split with just a warning.
checkOnline(env, regionToSplit);
this.bestSplitRow = splitRow;
checkSplittable(env, regionToSplit, bestSplitRow);
final TableName table = regionToSplit.getTable();
final long rid = getDaughterRegionIdTimestamp(regionToSplit);
this.daughterOneRI = RegionInfoBuilder.newBuilder(table)
.setStartKey(regionToSplit.getStartKey())
.setEndKey(bestSplitRow)
.setSplit(false)
.setRegionId(rid)
.build();
this.daughterTwoRI = RegionInfoBuilder.newBuilder(table)
.setStartKey(bestSplitRow)
.setEndKey(regionToSplit.getEndKey())
.setSplit(false)
.setRegionId(rid)
.build();
TableDescriptor htd = env.getMasterServices().getTableDescriptors().get(getTableName());
if(htd.getRegionSplitPolicyClassName() != null) {
// Since we don't have region reference here, creating the split policy instance without it.
// This can be used to invoke methods which don't require Region reference. This instantiation
// of a class on Master-side though it only makes sense on the RegionServer-side is
// for Phoenix Local Indexing. Refer HBASE-12583 for more information.
Class<? extends RegionSplitPolicy> clazz =
RegionSplitPolicy.getSplitPolicyClass(htd, env.getMasterConfiguration());
this.splitPolicy = ReflectionUtils.newInstance(clazz, env.getMasterConfiguration());
}
}
@Test
public void testOpenRegionFailedMemoryLeak() throws Exception {
final ServerName serverName = ServerName.valueOf("testOpenRegionFailed", 100, 42);
final RegionServerServices rss = spy(TEST_UTIL.createMockRegionServerService(serverName));
TableDescriptor htd =
TableDescriptorBuilder.newBuilder(TableName.valueOf("testOpenRegionFailed"))
.setColumnFamily(ColumnFamilyDescriptorBuilder.of(fam1))
.setValue("COPROCESSOR$1", "hdfs://test/test.jar|test||").build();
RegionInfo hri = RegionInfoBuilder.newBuilder(htd.getTableName()).build();
ScheduledExecutorService executor =
CompatibilitySingletonFactory.getInstance(MetricsExecutor.class).getExecutor();
for (int i = 0; i < 20; i++) {
try {
HRegion.openHRegion(hri, htd, rss.getWAL(hri), TEST_UTIL.getConfiguration(), rss, null);
fail("Should fail otherwise the test will be useless");
} catch (Throwable t) {
LOG.info("Expected exception, continue", t);
}
}
TimeUnit.SECONDS.sleep(MetricsRegionWrapperImpl.PERIOD);
Field[] fields = ThreadPoolExecutor.class.getDeclaredFields();
boolean found = false;
for (Field field : fields) {
if (field.getName().equals("workQueue")) {
field.setAccessible(true);
BlockingQueue<Runnable> workQueue = (BlockingQueue<Runnable>) field.get(executor);
// there are still two task not cancel, can not cause to memory lack
Assert.assertTrue("ScheduledExecutor#workQueue should equals 2, now is " +
workQueue.size() + ", please check region is close", 2 == workQueue.size());
found = true;
}
}
Assert.assertTrue("can not find workQueue, test failed", found);
}
@Test
public void testContainsRange() {
TableDescriptor tableDesc =
TableDescriptorBuilder.newBuilder(TableName.valueOf(name.getMethodName())).build();
RegionInfo hri = RegionInfoBuilder.newBuilder(tableDesc.getTableName())
.setStartKey(Bytes.toBytes("a")).setEndKey(Bytes.toBytes("g")).build();
// Single row range at start of region
assertTrue(hri.containsRange(Bytes.toBytes("a"), Bytes.toBytes("a")));
// Fully contained range
assertTrue(hri.containsRange(Bytes.toBytes("b"), Bytes.toBytes("c")));
// Range overlapping start of region
assertTrue(hri.containsRange(Bytes.toBytes("a"), Bytes.toBytes("c")));
// Fully contained single-row range
assertTrue(hri.containsRange(Bytes.toBytes("c"), Bytes.toBytes("c")));
// Range that overlaps end key and hence doesn't fit
assertFalse(hri.containsRange(Bytes.toBytes("a"), Bytes.toBytes("g")));
// Single row range on end key
assertFalse(hri.containsRange(Bytes.toBytes("g"), Bytes.toBytes("g")));
// Single row range entirely outside
assertFalse(hri.containsRange(Bytes.toBytes("z"), Bytes.toBytes("z")));
// Degenerate range
try {
hri.containsRange(Bytes.toBytes("z"), Bytes.toBytes("a"));
fail("Invalid range did not throw IAE");
} catch (IllegalArgumentException iae) {
}
}
/**
* Add a bunch of dummy data and roll the logs every two insert. We
* should end up with 10 rolled files (plus the roll called in
* the constructor). Also test adding a listener while it's running.
*/
@Test
public void testActionListener() throws Exception {
DummyWALActionsListener observer = new DummyWALActionsListener();
final WALFactory wals = new WALFactory(conf, "testActionListener");
wals.getWALProvider().addWALActionsListener(observer);
DummyWALActionsListener laterobserver = new DummyWALActionsListener();
RegionInfo hri = RegionInfoBuilder.newBuilder(TableName.valueOf(SOME_BYTES))
.setStartKey(SOME_BYTES).setEndKey(SOME_BYTES).build();
final WAL wal = wals.getWAL(hri);
MultiVersionConcurrencyControl mvcc = new MultiVersionConcurrencyControl();
for (int i = 0; i < 20; i++) {
byte[] b = Bytes.toBytes(i + "");
KeyValue kv = new KeyValue(b, b, b);
WALEdit edit = new WALEdit();
edit.add(kv);
NavigableMap<byte[], Integer> scopes = new TreeMap<>(Bytes.BYTES_COMPARATOR);
scopes.put(b, 0);
long txid = wal.appendData(hri,
new WALKeyImpl(hri.getEncodedNameAsBytes(), TableName.valueOf(b), 0, mvcc, scopes), edit);
wal.sync(txid);
if (i == 10) {
wal.registerWALActionsListener(laterobserver);
}
if (i % 2 == 0) {
wal.rollWriter();
}
}
wal.close();
assertEquals(11, observer.preLogRollCounter);
assertEquals(11, observer.postLogRollCounter);
assertEquals(5, laterobserver.preLogRollCounter);
assertEquals(5, laterobserver.postLogRollCounter);
assertEquals(1, observer.closedCount);
}
@Test
public void testIsStart() {
assertTrue(RegionInfoBuilder.FIRST_META_REGIONINFO.isFirst());
org.apache.hadoop.hbase.client.RegionInfo ri =
org.apache.hadoop.hbase.client.RegionInfoBuilder.newBuilder(TableName.META_TABLE_NAME).
setStartKey(Bytes.toBytes("not_start")).build();
assertFalse(ri.isFirst());
}