private void offlineReferenceFileRepair()

in hbase-hbck2/src/main/java/org/apache/hbase/hbck1/HBaseFsck.java [1194:1242]


  private void offlineReferenceFileRepair() throws IOException, InterruptedException {
    clearState();
    Configuration conf = getConf();
    Path hbaseRoot = CommonFSUtils.getRootDir(conf);
    FileSystem fs = hbaseRoot.getFileSystem(conf);
    Map<String, Path> allFiles =
      getTableStoreFilePathMap(fs, hbaseRoot, new FSUtils.ReferenceFileFilter(fs), executor);
    for (Path path: allFiles.values()) {
      Path referredToFile = StoreFileInfo.getReferredToFile(path);
      if (fs.exists(referredToFile)) {
        continue;  // good, expected
      }

      // Found a lingering reference file
      errors.reportError(ErrorReporter.ERROR_CODE.LINGERING_REFERENCE_HFILE,
        "Found lingering reference file " + path);
      if (!shouldFixReferenceFiles()) {
        continue;
      }

      // Now, trying to fix it since requested
      boolean success = false;
      String pathStr = path.toString();

      // A reference file path should be like
      // ${hbase.rootdir}/data/namespace/table_name/region_id/family_name/referred_file.region_name
      // Up 5 directories to get the root folder.
      // So the file will be sidelined to a similar folder structure.
      int index = pathStr.lastIndexOf(Path.SEPARATOR_CHAR);
      for (int i = 0; index > 0 && i < 5; i++) {
        index = pathStr.lastIndexOf(Path.SEPARATOR_CHAR, index - 1);
      }
      if (index > 0) {
        Path rootDir = getSidelineDir();
        Path dst = new Path(rootDir, pathStr.substring(index + 1));
        fs.mkdirs(dst.getParent());
        LOG.info("Trying to sideline reference file "
          + path + " to " + dst);
        setShouldRerun();

        success = fs.rename(path, dst);
        debugLsr(dst);

      }
      if (!success) {
        LOG.error("Failed to sideline reference file " + path);
      }
    }
  }