Skip to content

Commit fe8a9b0

Browse files
committed
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
1 parent a4ac67d commit fe8a9b0

File tree

8 files changed

+48
-12
lines changed

8 files changed

+48
-12
lines changed

hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,9 @@ Release 2.0.3-alpha - Unreleased
753753
HDFS-4445. All BKJM ledgers are not checked while tailing, So failover will fail.
754754
(Vinay via umamahesh)
755755

756+
HDFS-4462. 2NN will fail to checkpoint after an HDFS upgrade from a
757+
pre-federation version of HDFS. (atm)
758+
756759
BREAKDOWN OF HDFS-3077 SUBTASKS
757760

758761
HDFS-3077. Quorum-based protocol for reading and writing edit logs.

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/Storage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ protected void setPropertiesFromFields(Properties props,
905905
props.setProperty("storageType", storageType.toString());
906906
props.setProperty("namespaceID", String.valueOf(namespaceID));
907907
// Set clusterID in version with federation support
908-
if (LayoutVersion.supports(Feature.FEDERATION, layoutVersion)) {
908+
if (versionSupportsFederation()) {
909909
props.setProperty("clusterID", clusterID);
910910
}
911911
props.setProperty("cTime", String.valueOf(cTime));

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/StorageInfo.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
package org.apache.hadoop.hdfs.server.common;
1919

2020
import org.apache.hadoop.classification.InterfaceAudience;
21+
import org.apache.hadoop.hdfs.protocol.LayoutVersion;
22+
import org.apache.hadoop.hdfs.protocol.LayoutVersion.Feature;
2123

2224
import com.google.common.base.Joiner;
2325

@@ -77,6 +79,10 @@ public void setStorageInfo(StorageInfo from) {
7779
namespaceID = from.namespaceID;
7880
cTime = from.cTime;
7981
}
82+
83+
public boolean versionSupportsFederation() {
84+
return LayoutVersion.supports(Feature.FEDERATION, layoutVersion);
85+
}
8086

8187
@Override
8288
public String toString() {

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/CheckpointSignature.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ boolean isSameCluster(FSImage si) {
123123
blockpoolID.equals(si.getBlockPoolID());
124124
}
125125

126+
boolean namespaceIdMatches(FSImage si) {
127+
return namespaceID == si.getStorage().namespaceID;
128+
}
129+
126130
void validateStorageInfo(FSImage si) throws IOException {
127131
if (!isSameCluster(si)
128132
|| !storageVersionMatches(si.getStorage())) {

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NNStorage.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ protected void setFieldsFromProperties(
587587
}
588588

589589
// Set Block pool ID in version with federation support
590-
if (LayoutVersion.supports(Feature.FEDERATION, layoutVersion)) {
590+
if (versionSupportsFederation()) {
591591
String sbpid = props.getProperty("blockpoolID");
592592
setBlockPoolID(sd.getRoot(), sbpid);
593593
}
@@ -634,7 +634,7 @@ protected void setPropertiesFromFields(Properties props,
634634
) throws IOException {
635635
super.setPropertiesFromFields(props, sd);
636636
// Set blockpoolID in version with federation support
637-
if (LayoutVersion.supports(Feature.FEDERATION, layoutVersion)) {
637+
if (versionSupportsFederation()) {
638638
props.setProperty("blockpoolID", blockpoolID);
639639
}
640640
}

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/SecondaryNameNode.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -475,14 +475,20 @@ boolean doCheckpoint() throws IOException {
475475
// Returns a token that would be used to upload the merged image.
476476
CheckpointSignature sig = namenode.rollEditLog();
477477

478-
if ((checkpointImage.getNamespaceID() == 0) ||
479-
(sig.isSameCluster(checkpointImage) &&
478+
boolean loadImage = false;
479+
boolean isFreshCheckpointer = (checkpointImage.getNamespaceID() == 0);
480+
boolean isSameCluster =
481+
(dstStorage.versionSupportsFederation() && sig.isSameCluster(checkpointImage)) ||
482+
(!dstStorage.versionSupportsFederation() && sig.namespaceIdMatches(checkpointImage));
483+
if (isFreshCheckpointer ||
484+
(isSameCluster &&
480485
!sig.storageVersionMatches(checkpointImage.getStorage()))) {
481486
// if we're a fresh 2NN, or if we're on the same cluster and our storage
482487
// needs an upgrade, just take the storage info from the server.
483488
dstStorage.setStorageInfo(sig);
484489
dstStorage.setClusterID(sig.getClusterID());
485490
dstStorage.setBlockPoolID(sig.getBlockpoolID());
491+
loadImage = true;
486492
}
487493
sig.validateStorageInfo(checkpointImage);
488494

@@ -492,7 +498,7 @@ boolean doCheckpoint() throws IOException {
492498
RemoteEditLogManifest manifest =
493499
namenode.getEditLogManifest(sig.mostRecentCheckpointTxId + 1);
494500

495-
boolean loadImage = downloadCheckpointFiles(
501+
loadImage |= downloadCheckpointFiles(
496502
fsName, checkpointImage, sig, manifest); // Fetch fsimage and edits
497503
doMerge(sig, manifest, loadImage, checkpointImage, namesystem);
498504

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/FSImageTestUtil.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,11 @@ public static void corruptVersionFile(File versionFile, String key, String value
506506
props.load(fis);
507507
IOUtils.closeStream(fis);
508508

509-
props.setProperty(key, value);
509+
if (value == null || value.isEmpty()) {
510+
props.remove(key);
511+
} else {
512+
props.setProperty(key, value);
513+
}
510514

511515
out = new FileOutputStream(versionFile);
512516
props.store(out, null);

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestSecondaryNameNodeUpgrade.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717
*/
1818
package org.apache.hadoop.hdfs.server.namenode;
1919

20+
import com.google.common.collect.ImmutableMap;
21+
2022
import java.io.File;
2123
import java.io.IOException;
2224
import java.util.List;
25+
import java.util.Map;
2326

2427
import org.junit.Test;
2528
import org.junit.Before;
@@ -51,7 +54,7 @@ public void cleanupCluster() throws IOException {
5154
}
5255
}
5356

54-
private void doIt(String param, String val) throws IOException {
57+
private void doIt(Map<String, String> paramsToCorrupt) throws IOException {
5558
MiniDFSCluster cluster = null;
5659
FileSystem fs = null;
5760
SecondaryNameNode snn = null;
@@ -76,8 +79,12 @@ private void doIt(String param, String val) throws IOException {
7679
snn.shutdown();
7780

7881
for (File versionFile : versionFiles) {
79-
System.out.println("Changing '" + param + "' to '" + val + "' in " + versionFile);
80-
FSImageTestUtil.corruptVersionFile(versionFile, param, val);
82+
for (Map.Entry<String, String> paramToCorrupt : paramsToCorrupt.entrySet()) {
83+
String param = paramToCorrupt.getKey();
84+
String val = paramToCorrupt.getValue();
85+
System.out.println("Changing '" + param + "' to '" + val + "' in " + versionFile);
86+
FSImageTestUtil.corruptVersionFile(versionFile, param, val);
87+
}
8188
}
8289

8390
snn = new SecondaryNameNode(conf);
@@ -94,13 +101,19 @@ private void doIt(String param, String val) throws IOException {
94101

95102
@Test
96103
public void testUpgradeLayoutVersionSucceeds() throws IOException {
97-
doIt("layoutVersion", "-39");
104+
doIt(ImmutableMap.of("layoutVersion", "-39"));
105+
}
106+
107+
@Test
108+
public void testUpgradePreFedSucceeds() throws IOException {
109+
doIt(ImmutableMap.of("layoutVersion", "-19", "clusterID", "",
110+
"blockpoolID", ""));
98111
}
99112

100113
@Test
101114
public void testChangeNsIDFails() throws IOException {
102115
try {
103-
doIt("namespaceID", "2");
116+
doIt(ImmutableMap.of("namespaceID", "2"));
104117
Assert.fail("Should throw InconsistentFSStateException");
105118
} catch(IOException e) {
106119
GenericTestUtils.assertExceptionContains("Inconsistent checkpoint fields", e);

0 commit comments

Comments
 (0)