示例#1
0
        /// <summary>
        /// Find the id of the last edit log transaction writen to a edit log
        /// ledger.
        /// </summary>
        /// <exception cref="System.IO.IOException"/>
        /// <exception cref="Org.Apache.Hadoop.Contrib.Bkjournal.BookKeeperJournalManager.SegmentEmptyException
        ///     "/>
        private long RecoverLastTxId(EditLogLedgerMetadata l, bool fence)
        {
            LedgerHandle lh = null;

            try
            {
                if (fence)
                {
                    lh = bkc.OpenLedger(l.GetLedgerId(), BookKeeper.DigestType.Mac, Sharpen.Runtime.GetBytesForString
                                            (digestpw, Charsets.Utf8));
                }
                else
                {
                    lh = bkc.OpenLedgerNoRecovery(l.GetLedgerId(), BookKeeper.DigestType.Mac, Sharpen.Runtime.GetBytesForString
                                                      (digestpw, Charsets.Utf8));
                }
            }
            catch (BKException bke)
            {
                throw new IOException("Exception opening ledger for " + l, bke);
            }
            catch (Exception ie)
            {
                Sharpen.Thread.CurrentThread().Interrupt();
                throw new IOException("Interrupted opening ledger for " + l, ie);
            }
            BookKeeperEditLogInputStream @in = null;

            try
            {
                long lastAddConfirmed = lh.GetLastAddConfirmed();
                if (lastAddConfirmed == -1)
                {
                    throw new BookKeeperJournalManager.SegmentEmptyException();
                }
                @in = new BookKeeperEditLogInputStream(lh, l, lastAddConfirmed);
                long        endTxId = HdfsConstants.InvalidTxid;
                FSEditLogOp op      = @in.ReadOp();
                while (op != null)
                {
                    if (endTxId == HdfsConstants.InvalidTxid || op.GetTransactionId() == endTxId + 1)
                    {
                        endTxId = op.GetTransactionId();
                    }
                    op = @in.ReadOp();
                }
                return(endTxId);
            }
            finally
            {
                if (@in != null)
                {
                    @in.Close();
                }
            }
        }
示例#2
0
        /// <summary>Finalize a log segment.</summary>
        /// <remarks>
        /// Finalize a log segment. If the journal manager is currently
        /// writing to a ledger, ensure that this is the ledger of the log segment
        /// being finalized.
        /// Otherwise this is the recovery case. In the recovery case, ensure that
        /// the firstTxId of the ledger matches firstTxId for the segment we are
        /// trying to finalize.
        /// </remarks>
        /// <exception cref="System.IO.IOException"/>
        public override void FinalizeLogSegment(long firstTxId, long lastTxId)
        {
            CheckEnv();
            string inprogressPath = InprogressZNode(firstTxId);

            try
            {
                Stat inprogressStat = zkc.Exists(inprogressPath, false);
                if (inprogressStat == null)
                {
                    throw new IOException("Inprogress znode " + inprogressPath + " doesn't exist");
                }
                EditLogLedgerMetadata l = EditLogLedgerMetadata.Read(zkc, inprogressPath);
                if (currentLedger != null)
                {
                    // normal, non-recovery case
                    if (l.GetLedgerId() == currentLedger.GetId())
                    {
                        try
                        {
                            currentLedger.Close();
                        }
                        catch (BKException bke)
                        {
                            Log.Error("Error closing current ledger", bke);
                        }
                        currentLedger = null;
                    }
                    else
                    {
                        throw new IOException("Active ledger has different ID to inprogress. " + l.GetLedgerId
                                                  () + " found, " + currentLedger.GetId() + " expected");
                    }
                }
                if (l.GetFirstTxId() != firstTxId)
                {
                    throw new IOException("Transaction id not as expected, " + l.GetFirstTxId() + " found, "
                                          + firstTxId + " expected");
                }
                l.FinalizeLedger(lastTxId);
                string finalisedPath = FinalizedLedgerZNode(firstTxId, lastTxId);
                try
                {
                    l.Write(zkc, finalisedPath);
                }
                catch (KeeperException.NodeExistsException)
                {
                    if (!l.Verify(zkc, finalisedPath))
                    {
                        throw new IOException("Node " + finalisedPath + " already exists" + " but data doesn't match"
                                              );
                    }
                }
                maxTxId.Store(lastTxId);
                zkc.Delete(inprogressPath, inprogressStat.GetVersion());
                string inprogressPathFromCI = ci.Read();
                if (inprogressPath.Equals(inprogressPathFromCI))
                {
                    ci.Clear();
                }
            }
            catch (KeeperException e)
            {
                throw new IOException("Error finalising ledger", e);
            }
            catch (Exception ie)
            {
                Sharpen.Thread.CurrentThread().Interrupt();
                throw new IOException("Error finalising ledger", ie);
            }
        }