in hbase-hbck2/src/main/java/org/apache/hbase/hbck1/HBaseFsck.java [1884:1940]
public boolean rebuildMeta() throws IOException, InterruptedException {
// TODO check to make sure hbase is offline. (or at least the table
// currently being worked on is off line)
// Determine what's on HDFS
loadHdfsRegionDirs(); // populating regioninfo table.
int errs = errors.getErrorList().size();
tablesInfo = loadHdfsRegionInfos(); // update tableInfos based on region info in fs.
checkHdfsIntegrity(false, false);
// make sure ok.
if (errors.getErrorList().size() != errs) {
// While in error state, iterate until no more fixes possible
while(true) {
fixes = 0;
suggestFixes(tablesInfo);
errors.clear();
loadHdfsRegionInfos(); // update tableInfos based on region info in fs.
checkHdfsIntegrity(shouldFixHdfsHoles(), shouldFixHdfsOverlaps());
int errCount = errors.getErrorList().size();
if (fixes == 0) {
if (errCount > 0) {
return false; // failed to fix problems.
} else {
break; // no fixes and no problems? drop out and fix stuff!
}
}
}
}
// we can rebuild, move old meta out of the way and start
LOG.info("HDFS regioninfo's seems good. Sidelining old hbase:meta");
Path backupDir = sidelineOldMeta();
HRegion meta = createNewMeta();
// Save off the waldir we're writing to so we can delete it when done.
Path waldir = ((AbstractFSWAL)meta.getWAL()).getCurrentFileName().getParent();
try {
// populate meta
List<Put> puts = generatePuts(tablesInfo);
if (puts == null) {
LOG.error("Problem encountered when creating new hbase:meta entries. " +
"You may need to restore the previously sidelined hbase:meta");
return false;
}
meta.batchMutate(puts.toArray(new Put[puts.size()]));
} finally {
HBaseTestingUtility.closeRegionAndWAL(meta);
// Clean out the WAL we created and used here.
boolean deleteWalDir = HBCKFsUtils.delete(waldir.getFileSystem(getConf()), waldir, true);
LOG.info("Deleting WAL directory {}, result={}", waldir, deleteWalDir);
}
LOG.info("Success! hbase:meta table rebuilt. Old hbase:meta moved into " + backupDir);
return true;
}