@Test
  public void testCleanMergeReference() throws Exception {
    LOG.info("Starting " + name.getMethodName());
    ADMIN.catalogJanitorSwitch(false);
    final TableName tableName = TableName.valueOf(name.getMethodName());
    try {
      // Create table and load data.
      Table table = createTableAndLoadData(MASTER, tableName);
      // Merge 1st and 2nd region
      mergeRegionsAndVerifyRegionNum(MASTER, tableName, 0, 1, INITIAL_REGION_NUM - 1);
      verifyRowCount(table, ROWSIZE);
      table.close();

      List<Pair<RegionInfo, ServerName>> tableRegions =
        MetaTableAccessor.getTableRegionsAndLocations(MASTER.getConnection(), tableName);
      RegionInfo mergedRegionInfo = tableRegions.get(0).getFirst();
      TableDescriptor tableDescriptor = MASTER.getTableDescriptors().get(tableName);
      Result mergedRegionResult =
        MetaTableAccessor.getRegionResult(MASTER.getConnection(), mergedRegionInfo);

      // contains merge reference in META
      assertTrue(CatalogFamilyFormat.hasMergeRegions(mergedRegionResult.rawCells()));

      // merging regions' directory are in the file system all the same
      List<RegionInfo> p = CatalogFamilyFormat.getMergeRegions(mergedRegionResult.rawCells());
      RegionInfo regionA = p.get(0);
      RegionInfo regionB = p.get(1);
      FileSystem fs = MASTER.getMasterFileSystem().getFileSystem();
      Path rootDir = MASTER.getMasterFileSystem().getRootDir();

      Path tabledir = CommonFSUtils.getTableDir(rootDir, mergedRegionInfo.getTable());
      Path regionAdir = new Path(tabledir, regionA.getEncodedName());
      Path regionBdir = new Path(tabledir, regionB.getEncodedName());
      assertTrue(fs.exists(regionAdir));
      assertTrue(fs.exists(regionBdir));

      ColumnFamilyDescriptor[] columnFamilies = tableDescriptor.getColumnFamilies();
      HRegionFileSystem hrfs =
        new HRegionFileSystem(TEST_UTIL.getConfiguration(), fs, tabledir, mergedRegionInfo);
      int count = 0;
      for (ColumnFamilyDescriptor colFamily : columnFamilies) {
        StoreFileTracker sft = StoreFileTrackerFactory.create(TEST_UTIL.getConfiguration(),
          tableDescriptor, colFamily, hrfs, false);
        count += sft.load().size();
      }
      ADMIN.compactRegion(mergedRegionInfo.getRegionName());
      // clean up the merged region store files
      // wait until merged region have reference file
      long timeout = EnvironmentEdgeManager.currentTime() + waitTime;
      int newcount = 0;
      while (EnvironmentEdgeManager.currentTime() < timeout) {
        for (ColumnFamilyDescriptor colFamily : columnFamilies) {
          StoreFileTracker sft = StoreFileTrackerFactory.create(TEST_UTIL.getConfiguration(),
            tableDescriptor, colFamily, hrfs, false);
          newcount += sft.load().size();
        }
        if (newcount > count) {
          break;
        }
        Thread.sleep(50);
      }
      assertTrue(newcount > count);
      List<RegionServerThread> regionServerThreads =
        TEST_UTIL.getHBaseCluster().getRegionServerThreads();
      for (RegionServerThread rs : regionServerThreads) {
        CompactedHFilesDischarger cleaner =
          new CompactedHFilesDischarger(100, null, rs.getRegionServer(), false);
        cleaner.chore();
        Thread.sleep(1000);
      }
      while (EnvironmentEdgeManager.currentTime() < timeout) {
        int newcount1 = 0;
        for (ColumnFamilyDescriptor colFamily : columnFamilies) {
          StoreFileTracker sft = StoreFileTrackerFactory.create(TEST_UTIL.getConfiguration(),
            tableDescriptor, colFamily, hrfs, false);
          newcount1 += sft.load().size();
        }
        if (newcount1 <= 1) {
          break;
        }
        Thread.sleep(50);
      }
      // run CatalogJanitor to clean merge references in hbase:meta and archive the
      // files of merging regions
      int cleaned = 0;
      while (cleaned == 0) {
        cleaned = ADMIN.runCatalogJanitor();
        LOG.debug("catalog janitor returned " + cleaned);
        Thread.sleep(50);
        // Cleanup is async so wait till all procedures are done running.
        ProcedureTestingUtility.waitNoProcedureRunning(
          TEST_UTIL.getMiniHBaseCluster().getMaster().getMasterProcedureExecutor());
      }
      // We used to check for existence of region in fs but sometimes the region dir was
      // cleaned up by the time we got here making the test sometimes flakey.
      assertTrue(cleaned > 0);

      // Wait around a bit to give stuff a chance to complete.
      while (true) {
        mergedRegionResult =
          MetaTableAccessor.getRegionResult(TEST_UTIL.getConnection(), mergedRegionInfo);
        if (CatalogFamilyFormat.hasMergeRegions(mergedRegionResult.rawCells())) {
          LOG.info("Waiting on cleanup of merge columns {}",
            Arrays.asList(mergedRegionResult.rawCells()).stream().map(c -> c.toString())
              .collect(Collectors.joining(",")));
          Threads.sleep(50);
        } else {
          break;
        }
      }
      assertFalse(CatalogFamilyFormat.hasMergeRegions(mergedRegionResult.rawCells()));
    } finally {
      ADMIN.catalogJanitorSwitch(true);
      TEST_UTIL.deleteTable(tableName);
    }
  }
Not really restarting the master. Simulate it by clear of new region state since it is not
persisted, will be lost after master restarts.
hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestRegionMergeTransactionOnCluster.java