示例#1
0
 /// <exception cref="System.IO.IOException"/>
 internal virtual void CheckConsistentNamespace(NamespaceInfo nsInfo)
 {
     if (nsInfo.GetNamespaceID() != GetNamespaceID())
     {
         throw new IOException("Incompatible namespaceID for journal " + this.sd + ": NameNode has nsId "
                               + nsInfo.GetNamespaceID() + " but storage has nsId " + GetNamespaceID());
     }
     if (!nsInfo.GetClusterID().Equals(GetClusterID()))
     {
         throw new IOException("Incompatible clusterID for journal " + this.sd + ": NameNode has clusterId '"
                               + nsInfo.GetClusterID() + "' but storage has clusterId '" + GetClusterID() + "'"
                               );
     }
 }
        /// <summary>Upgrade to any release after 0.22 (0.22 included) release e.g.</summary>
        /// <remarks>
        /// Upgrade to any release after 0.22 (0.22 included) release e.g. 0.22 =&gt; 0.23
        /// Upgrade procedure is as follows:
        /// <ol>
        /// <li>If <SD>/current/<bpid>/previous exists then delete it</li>
        /// <li>Rename <SD>/current/<bpid>/current to
        /// <SD>/current/bpid/current/previous.tmp</li>
        /// <li>Create new <SD>current/<bpid>/current directory</li>
        /// <ol>
        /// <li>Hard links for block files are created from previous.tmp to current</li>
        /// <li>Save new version file in current directory</li>
        /// </ol>
        /// <li>Rename previous.tmp to previous</li> </ol>
        /// </remarks>
        /// <param name="bpSd">storage directory <SD>/current/<bpid></param>
        /// <param name="nsInfo">Namespace Info from the namenode</param>
        /// <exception cref="System.IO.IOException">on error</exception>
        internal virtual void DoUpgrade(DataNode datanode, Storage.StorageDirectory bpSd,
                                        NamespaceInfo nsInfo)
        {
            // Upgrading is applicable only to release with federation or after
            if (!DataNodeLayoutVersion.Supports(LayoutVersion.Feature.Federation, layoutVersion
                                                ))
            {
                return;
            }
            Log.Info("Upgrading block pool storage directory " + bpSd.GetRoot() + ".\n   old LV = "
                     + this.GetLayoutVersion() + "; old CTime = " + this.GetCTime() + ".\n   new LV = "
                     + HdfsConstants.DatanodeLayoutVersion + "; new CTime = " + nsInfo.GetCTime());
            // get <SD>/previous directory
            string dnRoot = GetDataNodeStorageRoot(bpSd.GetRoot().GetCanonicalPath());

            Storage.StorageDirectory dnSdStorage = new Storage.StorageDirectory(new FilePath(
                                                                                    dnRoot));
            FilePath dnPrevDir = dnSdStorage.GetPreviousDir();

            // If <SD>/previous directory exists delete it
            if (dnPrevDir.Exists())
            {
                DeleteDir(dnPrevDir);
            }
            FilePath bpCurDir  = bpSd.GetCurrentDir();
            FilePath bpPrevDir = bpSd.GetPreviousDir();

            System.Diagnostics.Debug.Assert(bpCurDir.Exists(), "BP level current directory must exist."
                                            );
            CleanupDetachDir(new FilePath(bpCurDir, DataStorage.StorageDirDetached));
            // 1. Delete <SD>/current/<bpid>/previous dir before upgrading
            if (bpPrevDir.Exists())
            {
                DeleteDir(bpPrevDir);
            }
            FilePath bpTmpDir = bpSd.GetPreviousTmp();

            System.Diagnostics.Debug.Assert(!bpTmpDir.Exists(), "previous.tmp directory must not exist."
                                            );
            // 2. Rename <SD>/current/<bpid>/current to
            //    <SD>/current/<bpid>/previous.tmp
            Rename(bpCurDir, bpTmpDir);
            // 3. Create new <SD>/current with block files hardlinks and VERSION
            LinkAllBlocks(datanode, bpTmpDir, bpCurDir);
            this.layoutVersion = HdfsConstants.DatanodeLayoutVersion;
            System.Diagnostics.Debug.Assert(this.namespaceID == nsInfo.GetNamespaceID(), "Data-node and name-node layout versions must be the same."
                                            );
            this.cTime = nsInfo.GetCTime();
            WriteProperties(bpSd);
            // 4.rename <SD>/current/<bpid>/previous.tmp to
            // <SD>/current/<bpid>/previous
            Rename(bpTmpDir, bpPrevDir);
            Log.Info("Upgrade of block pool " + blockpoolID + " at " + bpSd.GetRoot() + " is complete"
                     );
        }
 /// <summary>Format a block pool slice storage.</summary>
 /// <param name="bpSdir">the block pool storage</param>
 /// <param name="nsInfo">the name space info</param>
 /// <exception cref="System.IO.IOException">Signals that an I/O exception has occurred.
 ///     </exception>
 private void Format(Storage.StorageDirectory bpSdir, NamespaceInfo nsInfo)
 {
     Log.Info("Formatting block pool " + blockpoolID + " directory " + bpSdir.GetCurrentDir
                  ());
     bpSdir.ClearDirectory();
     // create directory
     this.layoutVersion = HdfsConstants.DatanodeLayoutVersion;
     this.cTime         = nsInfo.GetCTime();
     this.namespaceID   = nsInfo.GetNamespaceID();
     this.blockpoolID   = nsInfo.GetBlockPoolID();
     WriteProperties(bpSdir);
 }
示例#4
0
 /// <exception cref="System.IO.IOException"/>
 private void CheckEnv()
 {
     lock (this)
     {
         if (!initialized)
         {
             try
             {
                 Stat versionStat = zkc.Exists(versionPath, false);
                 if (versionStat == null)
                 {
                     throw new IOException("Environment not initialized. " + "Have you forgotten to format?"
                                           );
                 }
                 byte[] d = zkc.GetData(versionPath, false, versionStat);
                 BKJournalProtos.VersionProto.Builder builder = BKJournalProtos.VersionProto.NewBuilder
                                                                    ();
                 TextFormat.Merge(new string(d, Charsets.Utf8), builder);
                 if (!builder.IsInitialized())
                 {
                     throw new IOException("Invalid/Incomplete data in znode");
                 }
                 BKJournalProtos.VersionProto vp = ((BKJournalProtos.VersionProto)builder.Build());
                 // There's only one version at the moment
                 System.Diagnostics.Debug.Assert(vp.GetLayoutVersion() == BkjmLayoutVersion);
                 NamespaceInfo readns = PBHelper.Convert(vp.GetNamespaceInfo());
                 if (nsInfo.GetNamespaceID() != readns.GetNamespaceID() || !nsInfo.clusterID.Equals
                         (readns.GetClusterID()) || !nsInfo.GetBlockPoolID().Equals(readns.GetBlockPoolID
                                                                                        ()))
                 {
                     string err = string.Format("Environment mismatch. Running process %s" + ", stored in ZK %s"
                                                , nsInfo, readns);
                     Log.Error(err);
                     throw new IOException(err);
                 }
                 ci.Init();
                 initialized = true;
             }
             catch (KeeperException ke)
             {
                 throw new IOException("Cannot access ZooKeeper", ke);
             }
             catch (Exception ie)
             {
                 Sharpen.Thread.CurrentThread().Interrupt();
                 throw new IOException("Interrupted while checking environment", ie);
             }
         }
     }
 }
示例#5
0
 /// <summary>Called by the BPServiceActors when they handshake to a NN.</summary>
 /// <remarks>
 /// Called by the BPServiceActors when they handshake to a NN.
 /// If this is the first NN connection, this sets the namespace info
 /// for this BPOfferService. If it's a connection to a new NN, it
 /// verifies that this namespace matches (eg to prevent a misconfiguration
 /// where a StandbyNode from a different cluster is specified)
 /// </remarks>
 /// <exception cref="System.IO.IOException"/>
 internal virtual void VerifyAndSetNamespaceInfo(NamespaceInfo nsInfo)
 {
     WriteLock();
     try
     {
         if (this.bpNSInfo == null)
         {
             this.bpNSInfo = nsInfo;
             bool success = false;
             // Now that we know the namespace ID, etc, we can pass this to the DN.
             // The DN can now initialize its local storage if we are the
             // first BP to handshake, etc.
             try
             {
                 dn.InitBlockPool(this);
                 success = true;
             }
             finally
             {
                 if (!success)
                 {
                     // The datanode failed to initialize the BP. We need to reset
                     // the namespace info so that other BPService actors still have
                     // a chance to set it, and re-initialize the datanode.
                     this.bpNSInfo = null;
                 }
             }
         }
         else
         {
             CheckNSEquality(bpNSInfo.GetBlockPoolID(), nsInfo.GetBlockPoolID(), "Blockpool ID"
                             );
             CheckNSEquality(bpNSInfo.GetNamespaceID(), nsInfo.GetNamespaceID(), "Namespace ID"
                             );
             CheckNSEquality(bpNSInfo.GetClusterID(), nsInfo.GetClusterID(), "Cluster ID");
         }
     }
     finally
     {
         WriteUnlock();
     }
 }
 /// <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());
 }