/** * Get the HRegionInfo from cache, if not there, from the hbase:meta table. Be careful. Does RPC. * Do not hold a lock or synchronize when you call this method. * * @param regionName * @return HRegionInfo for the region */ @SuppressWarnings("deprecation") protected HRegionInfo getRegionInfo(final byte[] regionName) { String encodedName = HRegionInfo.encodeRegionName(regionName); RegionState regionState = getRegionState(encodedName); if (regionState != null) { return regionState.getRegion(); } try { Pair<HRegionInfo, ServerName> p = MetaTableAccessor.getRegion(server.getConnection(), regionName); HRegionInfo hri = p == null ? null : p.getFirst(); if (hri != null) { createRegionState(hri); } return hri; } catch (IOException e) { server.abort( "Aborting because error occoured while reading " + Bytes.toStringBinary(regionName) + " from hbase:meta", e); return null; } }
/** * This method does an RPC to hbase:meta. Do not call this method with a lock/synchronize held. * * @param hris The hris to check if empty in hbase:meta and if so, clean them up. */ private void cleanIfNoMetaEntry(Set<HRegionInfo> hris) { if (hris.isEmpty()) return; for (HRegionInfo hri : hris) { try { // This is RPC to meta table. It is done while we have a synchronize on // regionstates. No progress will be made if meta is not available at this time. // This is a cleanup task. Not critical. if (MetaTableAccessor.getRegion(server.getConnection(), hri.getEncodedNameAsBytes()) == null) { regionOffline(hri); FSUtils.deleteRegionDir(server.getConfiguration(), hri); } } catch (IOException e) { LOG.warn("Got exception while deleting " + hri + " directories from file system.", e); } } }
@Test @SuppressWarnings("deprecation") public void testMasterOpsWhileSplitting() throws Exception { MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster(); HMaster m = cluster.getMaster(); try (Table ht = TEST_UTIL.createTable(TABLENAME, FAMILYNAME)) { assertTrue(m.getTableStateManager().isTableState(TABLENAME, TableState.State.ENABLED)); TEST_UTIL.loadTable(ht, FAMILYNAME, false); } List<Pair<HRegionInfo, ServerName>> tableRegions = MetaTableAccessor.getTableRegionsAndLocations(m.getConnection(), TABLENAME); LOG.info("Regions after load: " + Joiner.on(',').join(tableRegions)); assertEquals(1, tableRegions.size()); assertArrayEquals(HConstants.EMPTY_START_ROW, tableRegions.get(0).getFirst().getStartKey()); assertArrayEquals(HConstants.EMPTY_END_ROW, tableRegions.get(0).getFirst().getEndKey()); // Now trigger a split and stop when the split is in progress LOG.info("Splitting table"); TEST_UTIL.getAdmin().split(TABLENAME); LOG.info("Waiting for split result to be about to open"); RegionStates regionStates = m.getAssignmentManager().getRegionStates(); while (regionStates.getRegionsOfTable(TABLENAME).size() <= 1) { Thread.sleep(100); } LOG.info("Making sure we can call getTableRegions while opening"); tableRegions = MetaTableAccessor.getTableRegionsAndLocations(m.getConnection(), TABLENAME, false); LOG.info("Regions: " + Joiner.on(',').join(tableRegions)); // We have three regions because one is split-in-progress assertEquals(3, tableRegions.size()); LOG.info("Making sure we can call getTableRegionClosest while opening"); Pair<HRegionInfo, ServerName> pair = m.getTableRegionForRow(TABLENAME, Bytes.toBytes("cde")); LOG.info("Result is: " + pair); Pair<HRegionInfo, ServerName> tableRegionFromName = MetaTableAccessor.getRegion(m.getConnection(), pair.getFirst().getRegionName()); assertEquals(tableRegionFromName.getFirst(), pair.getFirst()); }