private void testVerifyMetaRegionLocationWithException(Exception ex) throws IOException, InterruptedException, KeeperException, ServiceException { // Mock an ClientProtocol. final ClientProtos.ClientService.BlockingInterface implementation = Mockito.mock(ClientProtos.ClientService.BlockingInterface.class); HConnection connection = mockConnection(null, implementation); // If a 'get' is called on mocked interface, throw connection refused. Mockito.when(implementation.get((RpcController) Mockito.any(), (GetRequest) Mockito.any())). thenThrow(new ServiceException(ex)); // Now start up the catalogtracker with our doctored Connection. final CatalogTracker ct = constructAndStartCatalogTracker(connection); MetaRegionTracker.setMetaLocation(this.watcher, SN); long timeout = UTIL.getConfiguration(). getLong("hbase.catalog.verification.timeout", 1000); Assert.assertFalse(ct.verifyMetaRegionLocation(timeout)); }
/** * Test get of meta region fails properly if nothing to connect to. * @throws IOException * @throws InterruptedException * @throws KeeperException * @throws ServiceException */ @Test public void testVerifyMetaRegionLocationFails() throws IOException, InterruptedException, KeeperException, ServiceException { HConnection connection = Mockito.mock(HConnection.class); ServiceException connectException = new ServiceException(new ConnectException("Connection refused")); final AdminProtos.AdminService.BlockingInterface implementation = Mockito.mock(AdminProtos.AdminService.BlockingInterface.class); Mockito.when(implementation.getRegionInfo((RpcController)Mockito.any(), (GetRegionInfoRequest)Mockito.any())).thenThrow(connectException); Mockito.when(connection.getAdmin(Mockito.any(ServerName.class), Mockito.anyBoolean())). thenReturn(implementation); final CatalogTracker ct = constructAndStartCatalogTracker(connection); MetaRegionTracker.setMetaLocation(this.watcher, ServerName.valueOf("example.com", 1234, System.currentTimeMillis())); Assert.assertFalse(ct.verifyMetaRegionLocation(100)); }
@Override public HRegionLocation getMetaRegionLocation() throws IOException { ZooKeeperKeepAliveConnection zkw = hci.getKeepAliveZooKeeperWatcher(); try { if (LOG.isTraceEnabled()) { LOG.trace("Looking up meta region location in ZK," + " connection=" + this); } ServerName servername = MetaRegionTracker.blockUntilAvailable(zkw, hci.rpcTimeout); if (LOG.isTraceEnabled()) { LOG.trace("Looked up meta region location, connection=" + this + "; serverName=" + ((servername == null) ? "null" : servername)); } if (servername == null) return null; return new HRegionLocation(HRegionInfo.FIRST_META_REGIONINFO, servername, 0); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return null; } finally { zkw.close(); } }
@Test(timeout=180000) public void testFixAssignmentsWhenMETAinTransition() throws Exception { MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster(); HBaseAdmin admin = null; try { admin = new HBaseAdmin(TEST_UTIL.getConfiguration()); admin.closeRegion(cluster.getServerHoldingMeta(), HRegionInfo.FIRST_META_REGIONINFO); } finally { if (admin != null) { admin.close(); } } regionStates.regionOffline(HRegionInfo.FIRST_META_REGIONINFO); MetaRegionTracker.deleteMetaLocation(cluster.getMaster().getZooKeeper()); assertFalse(regionStates.isRegionOnline(HRegionInfo.FIRST_META_REGIONINFO)); HBaseFsck hbck = doFsck(conf, true); assertErrors(hbck, new ERROR_CODE[] { ERROR_CODE.UNKNOWN, ERROR_CODE.NO_META_REGION, ERROR_CODE.NULL_META_REGION }); assertNoErrors(doFsck(conf, false)); }
private ServerName getMetaRegionServerName() throws IOException, KeeperException { ZooKeeperWatcher zkw = createZooKeeperWatcher(); ServerName sn = null; try { sn = MetaRegionTracker.getMetaRegionLocation(zkw); } finally { zkw.close(); } return sn; }
@Override public void postOpenDeployTasks(final HRegion r, final CatalogTracker ct) throws KeeperException, IOException { checkOpen(); LOG.info("Post open deploy tasks for region=" + r.getRegionNameAsString()); // Do checks to see if we need to compact (references or too many files) for (Store s : r.getStores().values()) { if (s.hasReferences() || s.needsCompaction()) { this.compactSplitThread.requestSystemCompaction(r, s, "Opening Region"); } } long openSeqNum = r.getOpenSeqNum(); if (openSeqNum == HConstants.NO_SEQNUM) { // If we opened a region, we should have read some sequence number from it. LOG.error("No sequence number found when opening " + r.getRegionNameAsString()); openSeqNum = 0; } // Update flushed sequence id of a recovering region in ZK updateRecoveringRegionLastFlushedSequenceId(r); // Update ZK, or META if (r.getRegionInfo().isMetaRegion()) { MetaRegionTracker.setMetaLocation(getZooKeeper(), this.serverNameFromMasterPOV); } else { MetaEditor.updateRegionLocation(ct, r.getRegionInfo(), this.serverNameFromMasterPOV, openSeqNum); } LOG.info("Finished post open deploy task for " + r.getRegionNameAsString()); }
@After public void after() { try { // Clean out meta location or later tests will be confused... they presume // start fresh in zk. MetaRegionTracker.deleteMetaLocation(this.watcher); } catch (KeeperException e) { LOG.warn("Unable to delete hbase:meta location", e); } // Clear out our doctored connection or could mess up subsequent tests. HConnectionManager.deleteConnection(UTIL.getConfiguration()); this.watcher.close(); }
/** * Test that we get notification if hbase:meta moves. * @throws IOException * @throws InterruptedException * @throws KeeperException */ @Test public void testThatIfMETAMovesWeAreNotified() throws IOException, InterruptedException, KeeperException { HConnection connection = Mockito.mock(HConnection.class); constructAndStartCatalogTracker(connection); MetaRegionTracker.setMetaLocation(this.watcher, ServerName.valueOf("example.com", 1234, System.currentTimeMillis())); }
public CatalogTracker(final ZooKeeperWatcher zk, final Configuration conf, HConnection connection, Abortable abortable) throws IOException { this.connection = connection; if (abortable == null) { // A connection is abortable. this.abortable = this.connection; } Abortable throwableAborter = new Abortable() { @Override public void abort(String why, Throwable e) { throw new RuntimeException(why, e); } @Override public boolean isAborted() { return true; } }; if (zk == null) { // Create our own. Set flag so we tear it down on stop. this.zookeeper = new ZooKeeperWatcher(conf, "catalogtracker-on-" + connection.toString(), abortable); instantiatedzkw = true; } else { this.zookeeper = zk; } this.metaRegionTracker = new MetaRegionTracker(zookeeper, throwableAborter); }
@Override public void postOpenDeployTasks(final HRegion r, final CatalogTracker ct) throws KeeperException, IOException { rpcServices.checkOpen(); LOG.info("Post open deploy tasks for " + r.getRegionNameAsString()); // Do checks to see if we need to compact (references or too many files) for (Store s : r.getStores().values()) { if (s.hasReferences() || s.needsCompaction()) { this.compactSplitThread.requestSystemCompaction(r, s, "Opening Region"); } } long openSeqNum = r.getOpenSeqNum(); if (openSeqNum == HConstants.NO_SEQNUM) { // If we opened a region, we should have read some sequence number from it. LOG.error("No sequence number found when opening " + r.getRegionNameAsString()); openSeqNum = 0; } // Update flushed sequence id of a recovering region in ZK updateRecoveringRegionLastFlushedSequenceId(r); // Update ZK, or META if (r.getRegionInfo().isMetaRegion()) { MetaRegionTracker.setMetaLocation(getZooKeeper(), serverName); } else { MetaEditor.updateRegionLocation(ct, r.getRegionInfo(), this.serverName, openSeqNum); } LOG.debug("Finished post open deploy task for " + r.getRegionNameAsString()); }
@BeforeClass public static void before() throws Exception { HTU.startMiniCluster(NB_SERVERS); final byte[] tableName = Bytes.toBytes(TestRegionServerNoMaster.class.getSimpleName()); // Create table then get the single region for our new table. table = HTU.createTable(tableName, HConstants.CATALOG_FAMILY); Put p = new Put(row); p.add(HConstants.CATALOG_FAMILY, row, row); table.put(p); hri = table.getRegionLocation(row, false).getRegionInfo(); regionName = hri.getRegionName(); // No master HTU.getHBaseCluster().getMaster().stopMaster(); // Master is down, so is the meta. We need to assign it somewhere // so that regions can be assigned during the mocking phase. HRegionServer hrs = HTU.getHBaseCluster().getRegionServer(0); ZooKeeperWatcher zkw = hrs.getZooKeeper(); ZKAssign.createNodeOffline( zkw, HRegionInfo.FIRST_META_REGIONINFO, hrs.getServerName()); ProtobufUtil.openRegion(hrs.getRSRpcServices(), hrs.getServerName(), HRegionInfo.FIRST_META_REGIONINFO); while (true) { ServerName sn = MetaRegionTracker.getMetaRegionLocation(zkw); if (sn != null && sn.equals(hrs.getServerName())) { break; } Thread.sleep(100); } }
/** * Constructs the catalog tracker. Find current state of catalog tables. * Begin active tracking by executing {@link #start()} post construction. * Does not timeout. * @param zk If zk is null, we'll create an instance (and shut it down * when {@link #stop()} is called) else we'll use what is passed. * @param conf * @param abortable If fatal exception we'll call abort on this. May be null. * If it is we'll use the Connection associated with the passed * {@link Configuration} as our Abortable. * @throws IOException */ public CatalogTracker(final ZooKeeperWatcher zk, final Configuration conf, HConnection connection, Abortable abortable) throws IOException { this.connection = connection; if (abortable == null) { // A connection is abortable. this.abortable = this.connection; } else { this.abortable = abortable; } Abortable throwableAborter = new Abortable() { @Override public void abort(String why, Throwable e) { throw new RuntimeException(why, e); } @Override public boolean isAborted() { return true; } }; if (zk == null) { // Create our own. Set flag so we tear it down on stop. this.zookeeper = new ZooKeeperWatcher(conf, "catalogtracker-on-" + connection.toString(), abortable); instantiatedzkw = true; } else { this.zookeeper = zk; } this.metaRegionTracker = new MetaRegionTracker(zookeeper, throwableAborter); }
private ServerName setMetaLocation() throws KeeperException { MetaRegionTracker.setMetaLocation(this.watcher, SN); return SN; }
/** * Assigns the hbase:meta region. * <p> * Assumes that hbase:meta is currently closed and is not being actively served by * any RegionServer. * <p> * Forcibly unsets the current meta region location in ZooKeeper and assigns * hbase:meta to a random RegionServer. * @throws KeeperException */ public void assignMeta() throws KeeperException { MetaRegionTracker.deleteMetaLocation(this.watcher); assign(HRegionInfo.FIRST_META_REGIONINFO, true); }