You are viewing a plain text version of this content. The canonical link for it is here.
Posted to hdfs-commits@hadoop.apache.org by ki...@apache.org on 2013/11/25 16:40:31 UTC
svn commit: r1545326 - in
/hadoop/common/branches/branch-0.23/hadoop-hdfs-project/hadoop-hdfs:
CHANGES.txt
src/main/java/org/apache/hadoop/hdfs/server/datanode/DataStorage.java
src/test/java/org/apache/hadoop/hdfs/TestDFSRollback.java
Author: kihwal
Date: Mon Nov 25 15:40:31 2013
New Revision: 1545326
URL: http://svn.apache.org/r1545326
Log:
svn merge -c 1545322 merging from trunk to branch-0.23 to fix HDFS-5266. Datanode cannot roll back to previous layout version.
Modified:
hadoop/common/branches/branch-0.23/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt
hadoop/common/branches/branch-0.23/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataStorage.java
hadoop/common/branches/branch-0.23/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSRollback.java
Modified: hadoop/common/branches/branch-0.23/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt?rev=1545326&r1=1545325&r2=1545326&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt (original)
+++ hadoop/common/branches/branch-0.23/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt Mon Nov 25 15:40:31 2013
@@ -60,6 +60,8 @@ Release 0.23.10 - UNRELEASED
HDFS-5438. Flaws in block report processing can cause data loss. (kihwal)
+ HDFS-5526. Datanode cannot roll back to previous layout version (kihwal)
+
Release 0.23.9 - 2013-07-08
INCOMPATIBLE CHANGES
Modified: hadoop/common/branches/branch-0.23/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataStorage.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataStorage.java?rev=1545326&r1=1545325&r2=1545326&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataStorage.java (original)
+++ hadoop/common/branches/branch-0.23/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataStorage.java Mon Nov 25 15:40:31 2013
@@ -303,7 +303,16 @@ public class DataStorage extends Storage
@Override
protected void setFieldsFromProperties(Properties props, StorageDirectory sd)
throws IOException {
- setLayoutVersion(props, sd);
+ setFieldsFromProperties(props, sd, false, 0);
+ }
+
+ private void setFieldsFromProperties(Properties props, StorageDirectory sd,
+ boolean overrideLayoutVersion, int toLayoutVersion) throws IOException {
+ if (overrideLayoutVersion) {
+ this.layoutVersion = toLayoutVersion;
+ } else {
+ setLayoutVersion(props, sd);
+ }
setcTime(props, sd);
setStorageType(props, sd);
setClusterId(props, layoutVersion, sd);
@@ -351,13 +360,20 @@ public class DataStorage extends Storage
return true;
}
+ /** Read VERSION file for rollback */
+ void readProperties(StorageDirectory sd, int rollbackLayoutVersion)
+ throws IOException {
+ Properties props = readPropertiesFile(sd.getVersionFile());
+ setFieldsFromProperties(props, sd, true, rollbackLayoutVersion);
+ }
+
/**
* Analize which and whether a transition of the fs state is required
* and perform it if necessary.
*
- * Rollback if previousLV >= LAYOUT_VERSION && prevCTime <= namenode.cTime
- * Upgrade if this.LV > LAYOUT_VERSION || this.cTime < namenode.cTime
- * Regular startup if this.LV = LAYOUT_VERSION && this.cTime = namenode.cTime
+ * Rollback if the rollback startup option was specified.
+ * Upgrade if this.LV > LAYOUT_VERSION
+ * Regular startup if this.LV = LAYOUT_VERSION
*
* @param datanode Datanode to which this storage belongs to
* @param sd storage directory
@@ -397,9 +413,11 @@ public class DataStorage extends Storage
+ nsInfo.getClusterID() + "; datanode clusterID = " + getClusterID());
}
- // regular start up
- if (this.layoutVersion == HdfsConstants.LAYOUT_VERSION
- && this.cTime == nsInfo.getCTime())
+ // After addition of the federation feature, ctime check is only
+ // meaningful at BlockPoolSliceStorage level.
+
+ // regular start up.
+ if (this.layoutVersion == HdfsConstants.LAYOUT_VERSION)
return; // regular startup
// verify necessity of a distributed upgrade
UpgradeManagerDatanode um =
@@ -407,19 +425,20 @@ public class DataStorage extends Storage
verifyDistributedUpgradeProgress(um, nsInfo);
// do upgrade
- if (this.layoutVersion > HdfsConstants.LAYOUT_VERSION
- || this.cTime < nsInfo.getCTime()) {
+ if (this.layoutVersion > HdfsConstants.LAYOUT_VERSION) {
doUpgrade(sd, nsInfo); // upgrade
return;
}
- // layoutVersion == LAYOUT_VERSION && this.cTime > nsInfo.cTime
- // must shutdown
- throw new IOException("Datanode state: LV = " + this.getLayoutVersion()
- + " CTime = " + this.getCTime()
- + " is newer than the namespace state: LV = "
- + nsInfo.getLayoutVersion()
- + " CTime = " + nsInfo.getCTime());
+ // layoutVersion < LAYOUT_VERSION. I.e. stored layout version is newer
+ // than the version supported by datanode. This should have been caught
+ // in readProperties(), even if rollback was not carried out or somehow
+ // failed.
+ throw new IOException("BUG: The stored LV = " + this.getLayoutVersion()
+ + " is newer than the supported LV = "
+ + HdfsConstants.LAYOUT_VERSION
+ + " or name node LV = "
+ + nsInfo.getLayoutVersion());
}
/**
@@ -445,8 +464,13 @@ public class DataStorage extends Storage
* @throws IOException on error
*/
void doUpgrade(StorageDirectory sd, NamespaceInfo nsInfo) throws IOException {
+ // If the existing on-disk layout version supportes federation, simply
+ // update its layout version.
if (LayoutVersion.supports(Feature.FEDERATION, layoutVersion)) {
- clusterID = nsInfo.getClusterID();
+ // The VERSION file is already read in. Override the layoutVersion
+ // field and overwrite the file.
+ LOG.info("Updating layout version from " + layoutVersion + " to "
+ + nsInfo.getLayoutVersion() + " for storage " + sd.getRoot());
layoutVersion = nsInfo.getLayoutVersion();
writeProperties(sd);
return;
@@ -531,15 +555,32 @@ public class DataStorage extends Storage
* <li> Remove removed.tmp </li>
* </ol>
*
- * Do nothing, if previous directory does not exist.
+ * If previous directory does not exist and the current version supports
+ * federation, perform a simple rollback of layout version. This does not
+ * involve saving/restoration of actual data.
*/
void doRollback( StorageDirectory sd,
NamespaceInfo nsInfo
) throws IOException {
File prevDir = sd.getPreviousDir();
- // regular startup if previous dir does not exist
- if (!prevDir.exists())
+ // This is a regular startup or a post-federation rollback
+ if (!prevDir.exists()) {
+ // The current datanode version supports federation and the layout
+ // version from namenode matches what the datanode supports. An invalid
+ // rollback may happen if namenode didn't rollback and datanode is
+ // running a wrong version. But this will be detected in block pool
+ // level and the invalid VERSION content will be overwritten when
+ // the error is corrected and rollback is retried.
+ if (LayoutVersion.supports(Feature.FEDERATION,
+ HdfsConstants.LAYOUT_VERSION) &&
+ HdfsConstants.LAYOUT_VERSION == nsInfo.getLayoutVersion()) {
+ readProperties(sd, nsInfo.getLayoutVersion());
+ writeProperties(sd);
+ LOG.info("Layout version rolled back to " +
+ nsInfo.getLayoutVersion() + " for storage " + sd.getRoot());
+ }
return;
+ }
DataStorage prevInfo = new DataStorage();
prevInfo.readPreviousVersionProperties(sd);
Modified: hadoop/common/branches/branch-0.23/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSRollback.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.23/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSRollback.java?rev=1545326&r1=1545325&r2=1545326&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.23/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSRollback.java (original)
+++ hadoop/common/branches/branch-0.23/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSRollback.java Mon Nov 25 15:40:31 2013
@@ -190,21 +190,25 @@ public class TestDFSRollback extends Tes
// Create a previous snapshot for the blockpool
UpgradeUtilities.createBlockPoolStorageDirs(dataNodeDirs, "previous",
UpgradeUtilities.getCurrentBlockPoolID(cluster));
- // Older LayoutVersion to make it rollback
+ // Put newer layout version in current.
storageInfo = new StorageInfo(
- UpgradeUtilities.getCurrentLayoutVersion()+1,
+ UpgradeUtilities.getCurrentLayoutVersion()-1,
UpgradeUtilities.getCurrentNamespaceID(cluster),
UpgradeUtilities.getCurrentClusterID(cluster),
UpgradeUtilities.getCurrentFsscTime(cluster));
- // Create old VERSION file for each data dir
+
+ // Overwrite VERSION file in the current directory of
+ // volume directories and block pool slice directories
+ // with a layout version from future.
+ File[] dataCurrentDirs = new File[dataNodeDirs.length];
for (int i=0; i<dataNodeDirs.length; i++) {
- Path bpPrevPath = new Path(dataNodeDirs[i] + "/current/"
- + UpgradeUtilities.getCurrentBlockPoolID(cluster));
- UpgradeUtilities.createBlockPoolVersionFile(
- new File(bpPrevPath.toString()),
- storageInfo,
- UpgradeUtilities.getCurrentBlockPoolID(cluster));
+ dataCurrentDirs[i] = new File((new Path(dataNodeDirs[i]
+ + "/current")).toString());
}
+ UpgradeUtilities.createDataNodeVersionFile(
+ dataCurrentDirs,
+ storageInfo,
+ UpgradeUtilities.getCurrentBlockPoolID(cluster));
cluster.startDataNodes(conf, 1, false, StartupOption.ROLLBACK, null);
assertTrue(cluster.isDataNodeUp());