private HRegionLocation selectRegionLocation(HRegionLocation oldLocation, HRegionLocation location, boolean checkForEquals, boolean force) { if (location == null) { return oldLocation == null ? null : oldLocation; } if (oldLocation == null) { return location; } if (force || isGreaterThan(location.getSeqNum(), oldLocation.getSeqNum(), checkForEquals)) { return location; } return oldLocation; }
static boolean canUpdateOnError(HRegionLocation loc, HRegionLocation oldLoc) { // Do not need to update if no such location, or the location is newer, or the location is not // the same with us return oldLoc != null && oldLoc.getSeqNum() <= loc.getSeqNum() && oldLoc.getServerName().equals(loc.getServerName()); }
private void addLocationToCache(HRegionLocation loc) { for (;;) { int replicaId = loc.getRegion().getReplicaId(); RegionLocations oldLocs = metaRegionLocations.get(); if (oldLocs == null) { RegionLocations newLocs = createRegionLocations(loc); if (metaRegionLocations.compareAndSet(null, newLocs)) { return; } } HRegionLocation oldLoc = oldLocs.getRegionLocation(replicaId); if (oldLoc != null && (oldLoc.getSeqNum() > loc.getSeqNum() || oldLoc.getServerName().equals(loc.getServerName()))) { return; } RegionLocations newLocs = replaceRegionLocation(oldLocs, loc); if (metaRegionLocations.compareAndSet(oldLocs, newLocs)) { return; } } }
private boolean isEqual(RegionLocations locs1, RegionLocations locs2) { HRegionLocation[] locArr1 = locs1.getRegionLocations(); HRegionLocation[] locArr2 = locs2.getRegionLocations(); if (locArr1.length != locArr2.length) { return false; } for (int i = 0; i < locArr1.length; i++) { // do not need to compare region info HRegionLocation loc1 = locArr1[i]; HRegionLocation loc2 = locArr2[i]; if (loc1 == null) { if (loc2 != null) { return false; } } else { if (loc2 == null) { return false; } if (loc1.getSeqNum() != loc2.getSeqNum()) { return false; } if (Objects.equal(loc1.getServerName(), loc2.getServerName())) { return false; } } } return true; }
private boolean canSchedule(MasterProcedureEnv env, HRegionLocation loc) { if (loc.getSeqNum() < 0) { return false; } RegionStateNode regionNode = env.getAssignmentManager().getRegionStates().getRegionStateNode(loc.getRegion()); // If the region node is null, then at least in the next round we can remove this region to make // progress. And the second condition is a normal one, if there are no TRSP with it then we can // schedule one to make progress. return regionNode == null || !regionNode.isInTransition(); }
private void visitMetaEntry(final RegionStateVisitor visitor, final Result result) throws IOException { final RegionLocations rl = MetaTableAccessor.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, replicaId); final ServerName lastHost = hrl.getServerName(); final ServerName regionLocation = getRegionServer(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 static HBaseProtos.RegionLocation toRegionLocation(HRegionLocation loc) { HBaseProtos.RegionLocation.Builder builder = HBaseProtos.RegionLocation.newBuilder(); builder.setRegionInfo(toRegionInfo(loc.getRegion())); if (loc.getServerName() != null) { builder.setServerName(toServerName(loc.getServerName())); } builder.setSeqNum(loc.getSeqNum()); return builder.build(); }
@Test public void testSplit() throws IOException, InterruptedException, ExecutionException, TimeoutException { try (Table table = createTable(false)) { table.put(new Put(Bytes.toBytes(0)).addColumn(CF, CQ, Bytes.toBytes(0))); table.put(new Put(Bytes.toBytes(1)).addColumn(CF, CQ, Bytes.toBytes(0))); } UTIL.flush(NAME); HRegionServer rs = UTIL.getRSForFirstRegionInTable(NAME); RegionInfo region = UTIL.getMiniHBaseCluster().getRegions(NAME).get(0).getRegionInfo(); UTIL.getAdmin().splitRegionAsync(region.getRegionName(), Bytes.toBytes(1)).get(1, TimeUnit.MINUTES); long maxSeqId = getMaxSeqId(rs, region); RegionLocator locator = UTIL.getConnection().getRegionLocator(NAME); HRegionLocation locA = locator.getRegionLocation(Bytes.toBytes(0), true); HRegionLocation locB = locator.getRegionLocation(Bytes.toBytes(1), true); assertEquals(maxSeqId + 1, locA.getSeqNum()); assertEquals(maxSeqId + 1, locB.getSeqNum()); }
@Test public void testMerge() throws IOException, InterruptedException, ExecutionException, TimeoutException { try (Table table = createTable(true)) { table.put(new Put(Bytes.toBytes(0)).addColumn(CF, CQ, Bytes.toBytes(0))); table.put(new Put(Bytes.toBytes(1)).addColumn(CF, CQ, Bytes.toBytes(0))); table.put(new Put(Bytes.toBytes(2)).addColumn(CF, CQ, Bytes.toBytes(0))); } UTIL.flush(NAME); MiniHBaseCluster cluster = UTIL.getMiniHBaseCluster(); List<HRegion> regions = cluster.getRegions(NAME); HRegion regionA = regions.get(0); HRegion regionB = regions.get(1); HRegionServer rsA = cluster.getRegionServer(cluster.getServerWith(regionA.getRegionInfo().getRegionName())); HRegionServer rsB = cluster.getRegionServer(cluster.getServerWith(regionB.getRegionInfo().getRegionName())); UTIL.getAdmin().mergeRegionsAsync(regionA.getRegionInfo().getRegionName(), regionB.getRegionInfo().getRegionName(), false).get(1, TimeUnit.MINUTES); long maxSeqIdA = getMaxSeqId(rsA, regionA.getRegionInfo()); long maxSeqIdB = getMaxSeqId(rsB, regionB.getRegionInfo()); HRegionLocation loc = UTIL.getConnection().getRegionLocator(NAME).getRegionLocation(Bytes.toBytes(0), true); assertEquals(Math.max(maxSeqIdA, maxSeqIdB) + 1, loc.getSeqNum()); } }
private HRegionLocation selectRegionLocation(HRegionLocation oldLocation, HRegionLocation location, boolean checkForEquals, boolean force) { if (location == null) { return oldLocation == null ? null : oldLocation; } if (oldLocation == null) { return location; } if (force || isGreaterThan(location.getSeqNum(), oldLocation.getSeqNum(), checkForEquals)) { return location; } return oldLocation; }
static boolean canUpdate(HRegionLocation loc, HRegionLocation oldLoc) { // Do not need to update if no such location, or the location is newer, or the location is not // same with us return oldLoc != null && oldLoc.getSeqNum() <= loc.getSeqNum() && oldLoc.getServerName().equals(loc.getServerName()); }
ServerName.valueOf("127.0.0.1", nextPort, 0), location.getSeqNum() - 1); location = conn.getCachedLocation(TABLE_NAME2, ROW).getRegionLocation(); Assert.assertEquals(nextPort, location.getPort()); ServerName.valueOf("127.0.0.1", nextPort, 0), location.getSeqNum() - 1); location = conn.getCachedLocation(TABLE_NAME2, ROW).getRegionLocation(); Assert.assertEquals(nextPort, location.getPort()); ServerName.valueOf("127.0.0.1", nextPort, 0), location.getSeqNum() + 1); location = conn.getCachedLocation(TABLE_NAME2, ROW).getRegionLocation(); Assert.assertEquals(nextPort, location.getPort()); ServerName.valueOf("127.0.0.1", nextPort, 0), location.getSeqNum() - 1); location = conn.getCachedLocation(TABLE_NAME2, ROW).getRegionLocation(); Assert.assertEquals(nextPort - 1, location.getPort());
void updateCachedLocation(HRegionLocation loc, Throwable exception) { AsyncRegionLocator.updateCachedLocation(loc, exception, l -> metaRegionLocation.get(), newLoc -> { for (;;) { HRegionLocation oldLoc = metaRegionLocation.get(); if (oldLoc != null && (oldLoc.getSeqNum() > newLoc.getSeqNum() || oldLoc.getServerName().equals(newLoc.getServerName()))) { return; } if (metaRegionLocation.compareAndSet(oldLoc, newLoc)) { return; } } }, l -> { for (;;) { HRegionLocation oldLoc = metaRegionLocation.get(); if (!canUpdate(l, oldLoc) || metaRegionLocation.compareAndSet(oldLoc, null)) { return; } } }); }
private boolean addToCache(TableCache tableCache, HRegionLocation loc) { if (LOG.isTraceEnabled()) { LOG.trace("Try adding " + loc + " to cache"); } byte[] startKey = loc.getRegion().getStartKey(); HRegionLocation oldLoc = tableCache.cache.putIfAbsent(startKey, loc); if (oldLoc == null) { return true; } if (oldLoc.getSeqNum() > loc.getSeqNum() || oldLoc.getServerName().equals(loc.getServerName())) { if (LOG.isTraceEnabled()) { LOG.trace("Will not add " + loc + " to cache because the old value " + oldLoc + " is newer than us or has the same server name"); } return false; } return loc == tableCache.cache.compute(startKey, (k, oldValue) -> { if (oldValue == null || oldValue.getSeqNum() <= loc.getSeqNum()) { return loc; } if (LOG.isTraceEnabled()) { LOG.trace("Will not add " + loc + " to cache because the old value " + oldValue + " is newer than us or has the same server name." + " Maybe it is updated before we replace it"); } return oldValue; }); }
private void removeFromCache(HRegionLocation loc) { TableCache tableCache = cache.get(loc.getRegion().getTable()); if (tableCache == null) { return; } tableCache.cache.computeIfPresent(loc.getRegion().getStartKey(), (k, oldLoc) -> { if (oldLoc.getSeqNum() > loc.getSeqNum() || !oldLoc.getServerName().equals(loc.getServerName())) { return oldLoc; } return null; }); }
/** * 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(HRegionInfo.FIRST_META_REGIONINFO, hsa1); HRegionLocation hrl2 = new HRegionLocation(HRegionInfo.FIRST_META_REGIONINFO, hsa1); assertEquals(hrl1.hashCode(), hrl2.hashCode()); assertTrue(hrl1.equals(hrl2)); HRegionLocation hrl3 = new HRegionLocation(HRegionInfo.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(HRegionInfo.FIRST_META_REGIONINFO, hsa2); // These have same HRI but different locations so should be different. assertFalse(hrl3.equals(hrl4)); HRegionLocation hrl5 = new HRegionLocation(hrl4.getRegionInfo(), hrl4.getServerName(), hrl4.getSeqNum() + 1); assertTrue(hrl4.equals(hrl5)); }
public static HBaseProtos.RegionLocation toRegionLocation(HRegionLocation loc) { HBaseProtos.RegionLocation.Builder builder = HBaseProtos.RegionLocation.newBuilder(); builder.setRegionInfo(toRegionInfo(loc.getRegion())); if (loc.getServerName() != null) { builder.setServerName(toServerName(loc.getServerName())); } builder.setSeqNum(loc.getSeqNum()); return builder.build(); }
static boolean canUpdate(HRegionLocation loc, HRegionLocation oldLoc) { // Do not need to update if no such location, or the location is newer, or the location is not // same with us return oldLoc != null && oldLoc.getSeqNum() <= loc.getSeqNum() && oldLoc.getServerName().equals(loc.getServerName()); }
private void removeFromCache(HRegionLocation loc) { TableCache tableCache = cache.get(loc.getRegion().getTable()); if (tableCache == null) { return; } tableCache.cache.computeIfPresent(loc.getRegion().getStartKey(), (k, oldLoc) -> { if (oldLoc.getSeqNum() > loc.getSeqNum() || !oldLoc.getServerName().equals(loc.getServerName())) { return oldLoc; } return null; }); }