@Override
    public void run() {
      try {
        Random random = ThreadLocalRandom.current();
        for (int i = 0; i < 5; i++) {
          List<RegionInfo> regions = MetaTableAccessor.getTableRegions(connection, tableName, true);
          if (regions.isEmpty()) {
            continue;
          }
          int regionIndex = random.nextInt(regions.size());

          // pick a random region and split it into two
          RegionInfo region = Iterators.get(regions.iterator(), regionIndex);

          // pick the mid split point
          int start = 0, end = Integer.MAX_VALUE;
          if (region.getStartKey().length > 0) {
            start = Bytes.toInt(region.getStartKey());
          }
          if (region.getEndKey().length > 0) {
            end = Bytes.toInt(region.getEndKey());
          }
          int mid = start + ((end - start) / 2);
          byte[] splitPoint = Bytes.toBytes(mid);

          // put some rows to the regions
          addData(start);
          addData(mid);

          flushAndBlockUntilDone(admin, rs, region.getRegionName());
          compactAndBlockUntilDone(admin, rs, region.getRegionName());

          log("Initiating region split for:" + region.getRegionNameAsString());
          try {
            admin.splitRegionAsync(region.getRegionName(), splitPoint).get();
            // wait until the split is complete
            blockUntilRegionSplit(CONF, 50000, region.getRegionName(), true);
          } catch (NotServingRegionException ex) {
            // ignore
          }
        }
      } catch (Throwable ex) {
        this.ex = ex;
      }
    }
Tests that the client sees meta table changes as atomic during splits
hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestEndToEndSplitTransaction.java