/*
         * Roll back to old snapshot at the block pool level
         * If previous directory exists:
         * <ol>
         * <li>Rename <SD>/current/<bpid>/current to removed.tmp</li>
         * <li>Rename * <SD>/current/<bpid>/previous to current</li>
         * <li>Remove removed.tmp</li>
         * </ol>
         *
         * Do nothing if previous directory does not exist.
         * @param bpSd Block pool storage directory at <SD>/current/<bpid>
         */
        /// <exception cref="System.IO.IOException"/>
        internal virtual void DoRollback(Storage.StorageDirectory bpSd, NamespaceInfo nsInfo
                                         )
        {
            FilePath prevDir = bpSd.GetPreviousDir();

            // regular startup if previous dir does not exist
            if (!prevDir.Exists())
            {
                return;
            }
            // read attributes out of the VERSION file of previous directory
            Org.Apache.Hadoop.Hdfs.Server.Datanode.BlockPoolSliceStorage prevInfo = new Org.Apache.Hadoop.Hdfs.Server.Datanode.BlockPoolSliceStorage
                                                                                        ();
            prevInfo.ReadPreviousVersionProperties(bpSd);
            // We allow rollback to a state, which is either consistent with
            // the namespace state or can be further upgraded to it.
            // In another word, we can only roll back when ( storedLV >= software LV)
            // && ( DN.previousCTime <= NN.ctime)
            if (!(prevInfo.GetLayoutVersion() >= HdfsConstants.DatanodeLayoutVersion && prevInfo
                  .GetCTime() <= nsInfo.GetCTime()))
            {
                // cannot rollback
                throw new InconsistentFSStateException(bpSd.GetRoot(), "Cannot rollback to a newer state.\nDatanode previous state: LV = "
                                                       + prevInfo.GetLayoutVersion() + " CTime = " + prevInfo.GetCTime() + " is newer than the namespace state: LV = "
                                                       + HdfsConstants.DatanodeLayoutVersion + " CTime = " + nsInfo.GetCTime());
            }
            Log.Info("Rolling back storage directory " + bpSd.GetRoot() + ".\n   target LV = "
                     + nsInfo.GetLayoutVersion() + "; target CTime = " + nsInfo.GetCTime());
            FilePath tmpDir = bpSd.GetRemovedTmp();

            System.Diagnostics.Debug.Assert(!tmpDir.Exists(), "removed.tmp directory must not exist."
                                            );
            // 1. rename current to tmp
            FilePath curDir = bpSd.GetCurrentDir();

            System.Diagnostics.Debug.Assert(curDir.Exists(), "Current directory must exist.");
            Rename(curDir, tmpDir);
            // 2. rename previous to current
            Rename(prevDir, curDir);
            // 3. delete removed.tmp dir
            DeleteDir(tmpDir);
            Log.Info("Rollback of " + bpSd.GetRoot() + " is complete");
        }
示例#2
0
 /// <exception cref="System.IO.IOException"/>
 private bool CheckLayoutVersion(NamespaceInfo nsInfo)
 {
     return(nsInfo.GetLayoutVersion() == HdfsConstants.NamenodeLayoutVersion);
 }
 /// <summary>
 /// Analyze whether a transition of the BP state is required and
 /// perform it if necessary.
 /// </summary>
 /// <remarks>
 /// Analyze whether a transition of the BP state is required and
 /// perform it if necessary.
 /// <br />
 /// Rollback if previousLV &gt;= LAYOUT_VERSION && prevCTime &lt;= namenode.cTime.
 /// Upgrade if this.LV &gt; LAYOUT_VERSION || this.cTime &lt; namenode.cTime Regular
 /// startup if this.LV = LAYOUT_VERSION && this.cTime = namenode.cTime
 /// </remarks>
 /// <param name="sd">storage directory <SD>/current/<bpid></param>
 /// <param name="nsInfo">namespace info</param>
 /// <param name="startOpt">startup option</param>
 /// <exception cref="System.IO.IOException"/>
 private void DoTransition(DataNode datanode, Storage.StorageDirectory sd, NamespaceInfo
                           nsInfo, HdfsServerConstants.StartupOption startOpt)
 {
     if (startOpt == HdfsServerConstants.StartupOption.Rollback && sd.GetPreviousDir()
         .Exists())
     {
         Preconditions.CheckState(!GetTrashRootDir(sd).Exists(), sd.GetPreviousDir() + " and "
                                  + GetTrashRootDir(sd) + " should not " + " both be present.");
         DoRollback(sd, nsInfo);
     }
     else
     {
         // rollback if applicable
         if (startOpt == HdfsServerConstants.StartupOption.Rollback && !sd.GetPreviousDir(
                 ).Exists())
         {
             // Restore all the files in the trash. The restored files are retained
             // during rolling upgrade rollback. They are deleted during rolling
             // upgrade downgrade.
             int restored = RestoreBlockFilesFromTrash(GetTrashRootDir(sd));
             Log.Info("Restored " + restored + " block files from trash.");
         }
     }
     ReadProperties(sd);
     CheckVersionUpgradable(this.layoutVersion);
     System.Diagnostics.Debug.Assert(this.layoutVersion >= HdfsConstants.DatanodeLayoutVersion
                                     , "Future version is not allowed");
     if (GetNamespaceID() != nsInfo.GetNamespaceID())
     {
         throw new IOException("Incompatible namespaceIDs in " + sd.GetRoot().GetCanonicalPath
                                   () + ": namenode namespaceID = " + nsInfo.GetNamespaceID() + "; datanode namespaceID = "
                               + GetNamespaceID());
     }
     if (!blockpoolID.Equals(nsInfo.GetBlockPoolID()))
     {
         throw new IOException("Incompatible blockpoolIDs in " + sd.GetRoot().GetCanonicalPath
                                   () + ": namenode blockpoolID = " + nsInfo.GetBlockPoolID() + "; datanode blockpoolID = "
                               + blockpoolID);
     }
     if (this.layoutVersion == HdfsConstants.DatanodeLayoutVersion && this.cTime == nsInfo
         .GetCTime())
     {
         return;
     }
     // regular startup
     if (this.layoutVersion > HdfsConstants.DatanodeLayoutVersion)
     {
         int restored = RestoreBlockFilesFromTrash(GetTrashRootDir(sd));
         Log.Info("Restored " + restored + " block files from trash " + "before the layout upgrade. These blocks will be moved to "
                  + "the previous directory during the upgrade");
     }
     if (this.layoutVersion > HdfsConstants.DatanodeLayoutVersion || this.cTime < nsInfo
         .GetCTime())
     {
         DoUpgrade(datanode, 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());
 }