diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java index bf0c7904255..2a92104e7ec 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java @@ -185,6 +185,7 @@ import org.apache.hadoop.hbase.util.Addressing; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.CompressionTest; import org.apache.hadoop.hbase.util.EncryptionTest; +import org.apache.hadoop.hbase.util.HBaseFsck; import org.apache.hadoop.hbase.util.HFileArchiveUtil; import org.apache.hadoop.hbase.util.HasThread; import org.apache.hadoop.hbase.util.IdLock; @@ -864,7 +865,13 @@ public class HMaster extends HRegionServer implements MasterServices { ZKClusterId.setClusterId(this.zooKeeper, fileSystemManager.getClusterId()); this.clusterId = clusterId.toString(); - + // Precaution. Put in place the old hbck1 lock file to fence out old hbase1s running their + // hbck1s against an hbase2 cluster; it could do damage. To skip this behavior, set + // hbase.write.hbck1.lock.file to false. + if (this.conf.getBoolean("hbase.write.hbck1.lock.file", true)) { + HBaseFsck.checkAndMarkRunningHbck(this.conf, + HBaseFsck.createLockRetryCounterFactory(this.conf).create()); + } status.setStatus("Initialze ServerManager and schedule SCP for crash servers"); this.serverManager = createServerManager(this); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java index c479759fa72..992c9867e2c 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/HBaseFsck.java @@ -144,6 +144,7 @@ import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.util.ReflectionUtils; import org.apache.hadoop.util.Tool; import org.apache.hadoop.util.ToolRunner; +import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; import org.apache.hbase.thirdparty.com.google.common.collect.Sets; import org.apache.yetus.audience.InterfaceAudience; import org.apache.yetus.audience.InterfaceStability; @@ -164,7 +165,10 @@ import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.AdminServic /** * HBaseFsck (hbck) is a tool for checking and repairing region consistency and - * table integrity problems in a corrupted HBase. + * table integrity problems in a corrupted HBase. This tool was written for hbase-1.x. It does not + * work with hbase-2.x; it can read state but is not allowed to change state; i.e. effect 'repair'. + * See hbck2 (HBASE-19121) for a hbck tool for hbase2. + * *
* Region consistency checks verify that hbase:meta, region deployment on region
* servers and the state of data in HDFS (.regioninfo files) all are in
@@ -217,7 +221,12 @@ public class HBaseFsck extends Configured implements Closeable {
private static final int DEFAULT_OVERLAPS_TO_SIDELINE = 2;
private static final int DEFAULT_MAX_MERGE = 5;
private static final String TO_BE_LOADED = "to_be_loaded";
- private static final String HBCK_LOCK_FILE = "hbase-hbck.lock";
+ /**
+ * Here is where hbase-1.x used to default the lock for hbck1.
+ * It puts in place a lock when it goes to write/make changes.
+ */
+ @VisibleForTesting
+ public static final String HBCK_LOCK_FILE = "hbase-hbck.lock";
private static final int DEFAULT_MAX_LOCK_FILE_ATTEMPTS = 5;
private static final int DEFAULT_LOCK_FILE_ATTEMPT_SLEEP_INTERVAL = 200; // milliseconds
private static final int DEFAULT_LOCK_FILE_ATTEMPT_MAX_SLEEP_TIME = 5000; // milliseconds
@@ -369,40 +378,75 @@ public class HBaseFsck extends Configured implements Closeable {
super(conf);
errors = getErrorReporter(getConf());
this.executor = exec;
- lockFileRetryCounterFactory = new RetryCounterFactory(
- getConf().getInt("hbase.hbck.lockfile.attempts", DEFAULT_MAX_LOCK_FILE_ATTEMPTS),
- getConf().getInt(
- "hbase.hbck.lockfile.attempt.sleep.interval", DEFAULT_LOCK_FILE_ATTEMPT_SLEEP_INTERVAL),
- getConf().getInt(
- "hbase.hbck.lockfile.attempt.maxsleeptime", DEFAULT_LOCK_FILE_ATTEMPT_MAX_SLEEP_TIME));
- createZNodeRetryCounterFactory = new RetryCounterFactory(
- getConf().getInt("hbase.hbck.createznode.attempts", DEFAULT_MAX_CREATE_ZNODE_ATTEMPTS),
- getConf().getInt(
- "hbase.hbck.createznode.attempt.sleep.interval",
- DEFAULT_CREATE_ZNODE_ATTEMPT_SLEEP_INTERVAL),
- getConf().getInt(
- "hbase.hbck.createznode.attempt.maxsleeptime",
- DEFAULT_CREATE_ZNODE_ATTEMPT_MAX_SLEEP_TIME));
+ lockFileRetryCounterFactory = createLockRetryCounterFactory(getConf());
+ createZNodeRetryCounterFactory = createZnodeRetryCounterFactory(getConf());
zkw = createZooKeeperWatcher();
}
- private class FileLockCallable implements Callablenull
unless you call {@link #call()}
+ */
+ Path getHbckLockPath() {
+ return this.hbckLockPath;
+ }
+
@Override
public FSDataOutputStream call() throws IOException {
try {
- FileSystem fs = FSUtils.getCurrentFileSystem(getConf());
- FsPermission defaultPerms = FSUtils.getFilePermissions(fs, getConf(),
+ FileSystem fs = FSUtils.getCurrentFileSystem(this.conf);
+ FsPermission defaultPerms = FSUtils.getFilePermissions(fs, this.conf,
HConstants.DATA_FILE_UMASK_KEY);
- Path tmpDir = new Path(FSUtils.getRootDir(getConf()), HConstants.HBASE_TEMP_DIRECTORY);
+ Path tmpDir = getTmpDir(conf);
+ this.hbckLockPath = new Path(tmpDir, HBCK_LOCK_FILE);
fs.mkdirs(tmpDir);
- HBCK_LOCK_PATH = new Path(tmpDir, HBCK_LOCK_FILE);
- final FSDataOutputStream out = createFileWithRetries(fs, HBCK_LOCK_PATH, defaultPerms);
+ final FSDataOutputStream out = createFileWithRetries(fs, this.hbckLockPath, defaultPerms);
out.writeBytes(InetAddress.getLocalHost().toString());
+ // Add a note into the file we write on why hbase2 is writing out an hbck1 lock file.
+ out.writeBytes(" Written by an hbase-2.x Master to block an " +
+ "attempt by an hbase-1.x HBCK tool making modification to state. " +
+ "See 'HBCK must match HBase server version' in the hbase refguide.");
out.flush();
return out;
} catch(RemoteException e) {
@@ -417,7 +461,6 @@ public class HBaseFsck extends Configured implements Closeable {
private FSDataOutputStream createFileWithRetries(final FileSystem fs,
final Path hbckLockFilePath, final FsPermission defaultPerms)
throws IOException {
-
IOException exception = null;
do {
try {
@@ -449,13 +492,13 @@ public class HBaseFsck extends Configured implements Closeable {
* @return FSDataOutputStream object corresponding to the newly opened lock file
* @throws IOException if IO failure occurs
*/
- private FSDataOutputStream checkAndMarkRunningHbck() throws IOException {
- RetryCounter retryCounter = lockFileRetryCounterFactory.create();
- FileLockCallable callable = new FileLockCallable(retryCounter);
+ public static Pair