HDFS-4462. 2NN will fail to checkpoint after an HDFS upgrade from a pre-federation version of HDFS. Contributed by Aaron T. Myers.
git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1442375 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
114e23f7bd
commit
a8e39feed2
@ -753,6 +753,9 @@ Release 2.0.3-alpha - Unreleased
|
|||||||
HDFS-4445. All BKJM ledgers are not checked while tailing, So failover will fail.
|
HDFS-4445. All BKJM ledgers are not checked while tailing, So failover will fail.
|
||||||
(Vinay via umamahesh)
|
(Vinay via umamahesh)
|
||||||
|
|
||||||
|
HDFS-4462. 2NN will fail to checkpoint after an HDFS upgrade from a
|
||||||
|
pre-federation version of HDFS. (atm)
|
||||||
|
|
||||||
BREAKDOWN OF HDFS-3077 SUBTASKS
|
BREAKDOWN OF HDFS-3077 SUBTASKS
|
||||||
|
|
||||||
HDFS-3077. Quorum-based protocol for reading and writing edit logs.
|
HDFS-3077. Quorum-based protocol for reading and writing edit logs.
|
||||||
|
@ -905,7 +905,7 @@ protected void setPropertiesFromFields(Properties props,
|
|||||||
props.setProperty("storageType", storageType.toString());
|
props.setProperty("storageType", storageType.toString());
|
||||||
props.setProperty("namespaceID", String.valueOf(namespaceID));
|
props.setProperty("namespaceID", String.valueOf(namespaceID));
|
||||||
// Set clusterID in version with federation support
|
// Set clusterID in version with federation support
|
||||||
if (LayoutVersion.supports(Feature.FEDERATION, layoutVersion)) {
|
if (versionSupportsFederation()) {
|
||||||
props.setProperty("clusterID", clusterID);
|
props.setProperty("clusterID", clusterID);
|
||||||
}
|
}
|
||||||
props.setProperty("cTime", String.valueOf(cTime));
|
props.setProperty("cTime", String.valueOf(cTime));
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
package org.apache.hadoop.hdfs.server.common;
|
package org.apache.hadoop.hdfs.server.common;
|
||||||
|
|
||||||
import org.apache.hadoop.classification.InterfaceAudience;
|
import org.apache.hadoop.classification.InterfaceAudience;
|
||||||
|
import org.apache.hadoop.hdfs.protocol.LayoutVersion;
|
||||||
|
import org.apache.hadoop.hdfs.protocol.LayoutVersion.Feature;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
|
|
||||||
@ -77,6 +79,10 @@ public void setStorageInfo(StorageInfo from) {
|
|||||||
namespaceID = from.namespaceID;
|
namespaceID = from.namespaceID;
|
||||||
cTime = from.cTime;
|
cTime = from.cTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean versionSupportsFederation() {
|
||||||
|
return LayoutVersion.supports(Feature.FEDERATION, layoutVersion);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -123,6 +123,10 @@ boolean isSameCluster(FSImage si) {
|
|||||||
blockpoolID.equals(si.getBlockPoolID());
|
blockpoolID.equals(si.getBlockPoolID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean namespaceIdMatches(FSImage si) {
|
||||||
|
return namespaceID == si.getStorage().namespaceID;
|
||||||
|
}
|
||||||
|
|
||||||
void validateStorageInfo(FSImage si) throws IOException {
|
void validateStorageInfo(FSImage si) throws IOException {
|
||||||
if (!isSameCluster(si)
|
if (!isSameCluster(si)
|
||||||
|| !storageVersionMatches(si.getStorage())) {
|
|| !storageVersionMatches(si.getStorage())) {
|
||||||
|
@ -587,7 +587,7 @@ protected void setFieldsFromProperties(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set Block pool ID in version with federation support
|
// Set Block pool ID in version with federation support
|
||||||
if (LayoutVersion.supports(Feature.FEDERATION, layoutVersion)) {
|
if (versionSupportsFederation()) {
|
||||||
String sbpid = props.getProperty("blockpoolID");
|
String sbpid = props.getProperty("blockpoolID");
|
||||||
setBlockPoolID(sd.getRoot(), sbpid);
|
setBlockPoolID(sd.getRoot(), sbpid);
|
||||||
}
|
}
|
||||||
@ -634,7 +634,7 @@ protected void setPropertiesFromFields(Properties props,
|
|||||||
) throws IOException {
|
) throws IOException {
|
||||||
super.setPropertiesFromFields(props, sd);
|
super.setPropertiesFromFields(props, sd);
|
||||||
// Set blockpoolID in version with federation support
|
// Set blockpoolID in version with federation support
|
||||||
if (LayoutVersion.supports(Feature.FEDERATION, layoutVersion)) {
|
if (versionSupportsFederation()) {
|
||||||
props.setProperty("blockpoolID", blockpoolID);
|
props.setProperty("blockpoolID", blockpoolID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -475,14 +475,20 @@ boolean doCheckpoint() throws IOException {
|
|||||||
// Returns a token that would be used to upload the merged image.
|
// Returns a token that would be used to upload the merged image.
|
||||||
CheckpointSignature sig = namenode.rollEditLog();
|
CheckpointSignature sig = namenode.rollEditLog();
|
||||||
|
|
||||||
if ((checkpointImage.getNamespaceID() == 0) ||
|
boolean loadImage = false;
|
||||||
(sig.isSameCluster(checkpointImage) &&
|
boolean isFreshCheckpointer = (checkpointImage.getNamespaceID() == 0);
|
||||||
|
boolean isSameCluster =
|
||||||
|
(dstStorage.versionSupportsFederation() && sig.isSameCluster(checkpointImage)) ||
|
||||||
|
(!dstStorage.versionSupportsFederation() && sig.namespaceIdMatches(checkpointImage));
|
||||||
|
if (isFreshCheckpointer ||
|
||||||
|
(isSameCluster &&
|
||||||
!sig.storageVersionMatches(checkpointImage.getStorage()))) {
|
!sig.storageVersionMatches(checkpointImage.getStorage()))) {
|
||||||
// if we're a fresh 2NN, or if we're on the same cluster and our storage
|
// if we're a fresh 2NN, or if we're on the same cluster and our storage
|
||||||
// needs an upgrade, just take the storage info from the server.
|
// needs an upgrade, just take the storage info from the server.
|
||||||
dstStorage.setStorageInfo(sig);
|
dstStorage.setStorageInfo(sig);
|
||||||
dstStorage.setClusterID(sig.getClusterID());
|
dstStorage.setClusterID(sig.getClusterID());
|
||||||
dstStorage.setBlockPoolID(sig.getBlockpoolID());
|
dstStorage.setBlockPoolID(sig.getBlockpoolID());
|
||||||
|
loadImage = true;
|
||||||
}
|
}
|
||||||
sig.validateStorageInfo(checkpointImage);
|
sig.validateStorageInfo(checkpointImage);
|
||||||
|
|
||||||
@ -492,7 +498,7 @@ boolean doCheckpoint() throws IOException {
|
|||||||
RemoteEditLogManifest manifest =
|
RemoteEditLogManifest manifest =
|
||||||
namenode.getEditLogManifest(sig.mostRecentCheckpointTxId + 1);
|
namenode.getEditLogManifest(sig.mostRecentCheckpointTxId + 1);
|
||||||
|
|
||||||
boolean loadImage = downloadCheckpointFiles(
|
loadImage |= downloadCheckpointFiles(
|
||||||
fsName, checkpointImage, sig, manifest); // Fetch fsimage and edits
|
fsName, checkpointImage, sig, manifest); // Fetch fsimage and edits
|
||||||
doMerge(sig, manifest, loadImage, checkpointImage, namesystem);
|
doMerge(sig, manifest, loadImage, checkpointImage, namesystem);
|
||||||
|
|
||||||
|
@ -506,7 +506,11 @@ public static void corruptVersionFile(File versionFile, String key, String value
|
|||||||
props.load(fis);
|
props.load(fis);
|
||||||
IOUtils.closeStream(fis);
|
IOUtils.closeStream(fis);
|
||||||
|
|
||||||
props.setProperty(key, value);
|
if (value == null || value.isEmpty()) {
|
||||||
|
props.remove(key);
|
||||||
|
} else {
|
||||||
|
props.setProperty(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
out = new FileOutputStream(versionFile);
|
out = new FileOutputStream(versionFile);
|
||||||
props.store(out, null);
|
props.store(out, null);
|
||||||
|
@ -17,9 +17,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.hadoop.hdfs.server.namenode;
|
package org.apache.hadoop.hdfs.server.namenode;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@ -51,7 +54,7 @@ public void cleanupCluster() throws IOException {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doIt(String param, String val) throws IOException {
|
private void doIt(Map<String, String> paramsToCorrupt) throws IOException {
|
||||||
MiniDFSCluster cluster = null;
|
MiniDFSCluster cluster = null;
|
||||||
FileSystem fs = null;
|
FileSystem fs = null;
|
||||||
SecondaryNameNode snn = null;
|
SecondaryNameNode snn = null;
|
||||||
@ -76,8 +79,12 @@ private void doIt(String param, String val) throws IOException {
|
|||||||
snn.shutdown();
|
snn.shutdown();
|
||||||
|
|
||||||
for (File versionFile : versionFiles) {
|
for (File versionFile : versionFiles) {
|
||||||
System.out.println("Changing '" + param + "' to '" + val + "' in " + versionFile);
|
for (Map.Entry<String, String> paramToCorrupt : paramsToCorrupt.entrySet()) {
|
||||||
FSImageTestUtil.corruptVersionFile(versionFile, param, val);
|
String param = paramToCorrupt.getKey();
|
||||||
|
String val = paramToCorrupt.getValue();
|
||||||
|
System.out.println("Changing '" + param + "' to '" + val + "' in " + versionFile);
|
||||||
|
FSImageTestUtil.corruptVersionFile(versionFile, param, val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
snn = new SecondaryNameNode(conf);
|
snn = new SecondaryNameNode(conf);
|
||||||
@ -94,13 +101,19 @@ private void doIt(String param, String val) throws IOException {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpgradeLayoutVersionSucceeds() throws IOException {
|
public void testUpgradeLayoutVersionSucceeds() throws IOException {
|
||||||
doIt("layoutVersion", "-39");
|
doIt(ImmutableMap.of("layoutVersion", "-39"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpgradePreFedSucceeds() throws IOException {
|
||||||
|
doIt(ImmutableMap.of("layoutVersion", "-19", "clusterID", "",
|
||||||
|
"blockpoolID", ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testChangeNsIDFails() throws IOException {
|
public void testChangeNsIDFails() throws IOException {
|
||||||
try {
|
try {
|
||||||
doIt("namespaceID", "2");
|
doIt(ImmutableMap.of("namespaceID", "2"));
|
||||||
Assert.fail("Should throw InconsistentFSStateException");
|
Assert.fail("Should throw InconsistentFSStateException");
|
||||||
} catch(IOException e) {
|
} catch(IOException e) {
|
||||||
GenericTestUtils.assertExceptionContains("Inconsistent checkpoint fields", e);
|
GenericTestUtils.assertExceptionContains("Inconsistent checkpoint fields", e);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user