HBASE-16716 OfflineMetaRepair leaves empty directory inside /hbase/WALs which remains forever (Pankaj Kumar)
This commit is contained in:
parent
d9f18c7f03
commit
4d09116695
|
@ -1388,10 +1388,11 @@ public class HBaseFsck extends Configured implements Closeable {
|
||||||
/**
|
/**
|
||||||
* This borrows code from MasterFileSystem.bootstrap(). Explicitly creates it's own WAL, so be
|
* This borrows code from MasterFileSystem.bootstrap(). Explicitly creates it's own WAL, so be
|
||||||
* sure to close it as well as the region when you're finished.
|
* sure to close it as well as the region when you're finished.
|
||||||
*
|
* @param walFactoryID A unique identifier for WAL factory. Filesystem implementations will use
|
||||||
|
* this ID to make a directory inside WAL directory path.
|
||||||
* @return an open hbase:meta HRegion
|
* @return an open hbase:meta HRegion
|
||||||
*/
|
*/
|
||||||
private HRegion createNewMeta() throws IOException {
|
private HRegion createNewMeta(String walFactoryID) throws IOException {
|
||||||
Path rootdir = FSUtils.getRootDir(getConf());
|
Path rootdir = FSUtils.getRootDir(getConf());
|
||||||
Configuration c = getConf();
|
Configuration c = getConf();
|
||||||
HRegionInfo metaHRI = new HRegionInfo(HRegionInfo.FIRST_META_REGIONINFO);
|
HRegionInfo metaHRI = new HRegionInfo(HRegionInfo.FIRST_META_REGIONINFO);
|
||||||
|
@ -1402,9 +1403,8 @@ public class HBaseFsck extends Configured implements Closeable {
|
||||||
Configuration confForWAL = new Configuration(c);
|
Configuration confForWAL = new Configuration(c);
|
||||||
confForWAL.set(HConstants.HBASE_DIR, rootdir.toString());
|
confForWAL.set(HConstants.HBASE_DIR, rootdir.toString());
|
||||||
WAL wal = (new WALFactory(confForWAL,
|
WAL wal = (new WALFactory(confForWAL,
|
||||||
Collections.<WALActionsListener>singletonList(new MetricsWAL()),
|
Collections.<WALActionsListener> singletonList(new MetricsWAL()), walFactoryID))
|
||||||
"hbck-meta-recovery-" + RandomStringUtils.randomNumeric(8))).
|
.getWAL(metaHRI.getEncodedNameAsBytes(), metaHRI.getTable().getNamespace());
|
||||||
getWAL(metaHRI.getEncodedNameAsBytes(), metaHRI.getTable().getNamespace());
|
|
||||||
HRegion meta = HRegion.createHRegion(metaHRI, rootdir, c, metaDescriptor, wal);
|
HRegion meta = HRegion.createHRegion(metaHRI, rootdir, c, metaDescriptor, wal);
|
||||||
MasterFileSystem.setInfoFamilyCachingForMeta(metaDescriptor, true);
|
MasterFileSystem.setInfoFamilyCachingForMeta(metaDescriptor, true);
|
||||||
return meta;
|
return meta;
|
||||||
|
@ -1513,7 +1513,8 @@ public class HBaseFsck extends Configured implements Closeable {
|
||||||
Path backupDir = sidelineOldMeta();
|
Path backupDir = sidelineOldMeta();
|
||||||
|
|
||||||
LOG.info("Creating new hbase:meta");
|
LOG.info("Creating new hbase:meta");
|
||||||
HRegion meta = createNewMeta();
|
String walFactoryId = "hbck-meta-recovery-" + RandomStringUtils.randomNumeric(8);
|
||||||
|
HRegion meta = createNewMeta(walFactoryId);
|
||||||
|
|
||||||
// populate meta
|
// populate meta
|
||||||
List<Put> puts = generatePuts(tablesInfo);
|
List<Put> puts = generatePuts(tablesInfo);
|
||||||
|
@ -1527,11 +1528,31 @@ public class HBaseFsck extends Configured implements Closeable {
|
||||||
if (meta.getWAL() != null) {
|
if (meta.getWAL() != null) {
|
||||||
meta.getWAL().close();
|
meta.getWAL().close();
|
||||||
}
|
}
|
||||||
|
// clean up the temporary hbck meta recovery WAL directory
|
||||||
|
removeHBCKMetaRecoveryWALDir(walFactoryId);
|
||||||
LOG.info("Success! hbase:meta table rebuilt.");
|
LOG.info("Success! hbase:meta table rebuilt.");
|
||||||
LOG.info("Old hbase:meta is moved into " + backupDir);
|
LOG.info("Old hbase:meta is moved into " + backupDir);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the empty Meta recovery WAL directory.
|
||||||
|
* @param walFactoryID A unique identifier for WAL factory which was used by Filesystem to make a
|
||||||
|
* Meta recovery WAL directory inside WAL directory path.
|
||||||
|
*/
|
||||||
|
private void removeHBCKMetaRecoveryWALDir(String walFactoryId) throws IOException {
|
||||||
|
Path rootdir = FSUtils.getRootDir(getConf());
|
||||||
|
Path walLogDir = new Path(new Path(rootdir, HConstants.HREGION_LOGDIR_NAME), walFactoryId);
|
||||||
|
FileSystem fs = FSUtils.getCurrentFileSystem(getConf());
|
||||||
|
FileStatus[] walFiles = FSUtils.listStatus(fs, walLogDir, null);
|
||||||
|
if (walFiles == null || walFiles.length == 0) {
|
||||||
|
LOG.info("HBCK meta recovery WAL directory is empty, removing it now.");
|
||||||
|
if (!FSUtils.deleteDirectory(fs, walLogDir)) {
|
||||||
|
LOG.warn("Couldn't clear the HBCK Meta recovery WAL directory " + walLogDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log an appropriate message about whether or not overlapping merges are computed in parallel.
|
* Log an appropriate message about whether or not overlapping merges are computed in parallel.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -23,10 +23,15 @@ import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.apache.hadoop.fs.FileStatus;
|
||||||
|
import org.apache.hadoop.fs.FileSystem;
|
||||||
|
import org.apache.hadoop.fs.Path;
|
||||||
|
import org.apache.hadoop.hbase.HConstants;
|
||||||
import org.apache.hadoop.hbase.HTableDescriptor;
|
import org.apache.hadoop.hbase.HTableDescriptor;
|
||||||
import org.apache.hadoop.hbase.TableName;
|
import org.apache.hadoop.hbase.TableName;
|
||||||
import org.apache.hadoop.hbase.client.Admin;
|
import org.apache.hadoop.hbase.client.Admin;
|
||||||
|
@ -34,6 +39,7 @@ import org.apache.hadoop.hbase.client.Connection;
|
||||||
import org.apache.hadoop.hbase.client.ConnectionFactory;
|
import org.apache.hadoop.hbase.client.ConnectionFactory;
|
||||||
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
import org.apache.hadoop.hbase.testclassification.MediumTests;
|
||||||
import org.apache.hadoop.hbase.testclassification.MiscTests;
|
import org.apache.hadoop.hbase.testclassification.MiscTests;
|
||||||
|
import org.apache.hadoop.hbase.util.FSUtils;
|
||||||
import org.apache.hadoop.hbase.util.HBaseFsck;
|
import org.apache.hadoop.hbase.util.HBaseFsck;
|
||||||
import org.apache.hadoop.hbase.util.HBaseFsck.ErrorReporter.ERROR_CODE;
|
import org.apache.hadoop.hbase.util.HBaseFsck.ErrorReporter.ERROR_CODE;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -68,6 +74,7 @@ public class TestOfflineMetaRebuildBase extends OfflineMetaRebuildTestCore {
|
||||||
// rebuild meta table from scratch
|
// rebuild meta table from scratch
|
||||||
HBaseFsck fsck = new HBaseFsck(conf);
|
HBaseFsck fsck = new HBaseFsck(conf);
|
||||||
assertTrue(fsck.rebuildMeta(false));
|
assertTrue(fsck.rebuildMeta(false));
|
||||||
|
assertTrue("HBCK meta recovery WAL directory exist.", validateHBCKMetaRecoveryWALDir());
|
||||||
|
|
||||||
// bring up the minicluster
|
// bring up the minicluster
|
||||||
TEST_UTIL.startMiniZKCluster();
|
TEST_UTIL.startMiniZKCluster();
|
||||||
|
@ -97,4 +104,22 @@ public class TestOfflineMetaRebuildBase extends OfflineMetaRebuildTestCore {
|
||||||
LOG.info("Table " + table + " has " + tableRowCount(conf, table) + " entries.");
|
LOG.info("Table " + table + " has " + tableRowCount(conf, table) + " entries.");
|
||||||
assertEquals(16, tableRowCount(conf, table));
|
assertEquals(16, tableRowCount(conf, table));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate whether Meta recovery empty WAL directory is removed.
|
||||||
|
* @return True if directory is removed otherwise false.
|
||||||
|
*/
|
||||||
|
private boolean validateHBCKMetaRecoveryWALDir() throws IOException {
|
||||||
|
Path rootdir = FSUtils.getRootDir(TEST_UTIL.getConfiguration());
|
||||||
|
Path walLogDir = new Path(rootdir, HConstants.HREGION_LOGDIR_NAME);
|
||||||
|
FileSystem fs = TEST_UTIL.getTestFileSystem();
|
||||||
|
FileStatus[] walFiles = FSUtils.listStatus(fs, walLogDir, null);
|
||||||
|
assertNotNull(walFiles);
|
||||||
|
for (FileStatus fsStat : walFiles) {
|
||||||
|
if (fsStat.isDirectory() && fsStat.getPath().getName().startsWith("hbck-meta-recovery-")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue