コード例 #1
0
  /**
   * Cases can occur where we create a segment but crash before we even have the chance to write the
   * START_SEGMENT op. If this occurs we should warn, but load as normal
   */
  @Test
  public void testEmptyInprogressLedger() throws Exception {
    URI uri = BKJMUtil.createJournalURI("/hdfsjournal-emptyInprogressLedger");
    NamespaceInfo nsi = newNSInfo();
    BookKeeperJournalManager bkjm = new BookKeeperJournalManager(conf, uri, nsi);
    bkjm.format(nsi);

    EditLogOutputStream out = bkjm.startLogSegment(1, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
    ;
    for (long i = 1; i <= 100; i++) {
      FSEditLogOp op = FSEditLogTestUtil.getNoOpInstance();
      op.setTransactionId(i);
      out.write(op);
    }
    out.close();
    bkjm.finalizeLogSegment(1, 100);

    out = bkjm.startLogSegment(101, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
    out.close();
    bkjm.close();

    bkjm = new BookKeeperJournalManager(conf, uri, nsi);
    bkjm.recoverUnfinalizedSegments();
    out = bkjm.startLogSegment(101, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
    for (long i = 1; i <= 100; i++) {
      FSEditLogOp op = FSEditLogTestUtil.getNoOpInstance();
      op.setTransactionId(i);
      out.write(op);
    }
    out.close();
    bkjm.finalizeLogSegment(101, 200);

    bkjm.close();
  }
コード例 #2
0
  /**
   * Create a bkjm namespace, write a journal from txid 1, close stream. Try to create a new journal
   * from txid 1. Should throw an exception.
   */
  @Test
  public void testWriteRestartFrom1() throws Exception {
    NamespaceInfo nsi = newNSInfo();
    BookKeeperJournalManager bkjm =
        new BookKeeperJournalManager(
            conf, BKJMUtil.createJournalURI("/hdfsjournal-restartFrom1"), nsi);
    bkjm.format(nsi);

    long txid = 1;
    long start = txid;
    EditLogOutputStream out =
        bkjm.startLogSegment(txid, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
    for (long j = 1; j <= DEFAULT_SEGMENT_SIZE; j++) {
      FSEditLogOp op = FSEditLogTestUtil.getNoOpInstance();
      op.setTransactionId(txid++);
      out.write(op);
    }
    out.close();
    bkjm.finalizeLogSegment(start, (txid - 1));

    txid = 1;
    try {
      out = bkjm.startLogSegment(txid, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
      fail("Shouldn't be able to start another journal from " + txid + " when one already exists");
    } catch (Exception ioe) {
      LOG.info("Caught exception as expected", ioe);
    }

    // test border case
    txid = DEFAULT_SEGMENT_SIZE;
    try {
      out = bkjm.startLogSegment(txid, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
      fail("Shouldn't be able to start another journal from " + txid + " when one already exists");
    } catch (IOException ioe) {
      LOG.info("Caught exception as expected", ioe);
    }

    // open journal continuing from before
    txid = DEFAULT_SEGMENT_SIZE + 1;
    start = txid;
    out = bkjm.startLogSegment(start, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
    assertNotNull(out);

    for (long j = 1; j <= DEFAULT_SEGMENT_SIZE; j++) {
      FSEditLogOp op = FSEditLogTestUtil.getNoOpInstance();
      op.setTransactionId(txid++);
      out.write(op);
    }
    out.close();
    bkjm.finalizeLogSegment(start, (txid - 1));

    // open journal arbitarily far in the future
    txid = DEFAULT_SEGMENT_SIZE * 4;
    out = bkjm.startLogSegment(txid, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
    assertNotNull(out);
  }
コード例 #3
0
  @Test
  public void testSimpleRecovery() throws Exception {
    NamespaceInfo nsi = newNSInfo();
    BookKeeperJournalManager bkjm =
        new BookKeeperJournalManager(
            conf, BKJMUtil.createJournalURI("/hdfsjournal-simplerecovery"), nsi);
    bkjm.format(nsi);

    EditLogOutputStream out = bkjm.startLogSegment(1, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
    ;
    for (long i = 1; i <= 100; i++) {
      FSEditLogOp op = FSEditLogTestUtil.getNoOpInstance();
      op.setTransactionId(i);
      out.write(op);
    }
    out.setReadyToFlush();
    out.flush();

    out.abort();
    out.close();

    assertNull(zkc.exists(bkjm.finalizedLedgerZNode(1, 100), false));
    assertNotNull(zkc.exists(bkjm.inprogressZNode(1), false));

    bkjm.recoverUnfinalizedSegments();

    assertNotNull(zkc.exists(bkjm.finalizedLedgerZNode(1, 100), false));
    assertNull(zkc.exists(bkjm.inprogressZNode(1), false));
  }
コード例 #4
0
  @Test
  public void testSimpleRead() throws Exception {
    NamespaceInfo nsi = newNSInfo();
    BookKeeperJournalManager bkjm =
        new BookKeeperJournalManager(
            conf, BKJMUtil.createJournalURI("/hdfsjournal-simpleread"), nsi);
    bkjm.format(nsi);

    final long numTransactions = 10000;
    EditLogOutputStream out = bkjm.startLogSegment(1, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
    ;
    for (long i = 1; i <= numTransactions; i++) {
      FSEditLogOp op = FSEditLogTestUtil.getNoOpInstance();
      op.setTransactionId(i);
      out.write(op);
    }
    out.close();
    bkjm.finalizeLogSegment(1, numTransactions);

    List<EditLogInputStream> in = new ArrayList<EditLogInputStream>();
    bkjm.selectInputStreams(in, 1, true);
    try {
      assertEquals(numTransactions, FSEditLogTestUtil.countTransactionsInStream(in.get(0)));
    } finally {
      in.get(0).close();
    }
  }
コード例 #5
0
  @Test
  public void testNumberOfTransactionsWithInprogressAtEnd() throws Exception {
    NamespaceInfo nsi = newNSInfo();
    BookKeeperJournalManager bkjm =
        new BookKeeperJournalManager(
            conf, BKJMUtil.createJournalURI("/hdfsjournal-inprogressAtEnd"), nsi);
    bkjm.format(nsi);

    long txid = 1;
    for (long i = 0; i < 3; i++) {
      long start = txid;
      EditLogOutputStream out =
          bkjm.startLogSegment(start, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
      for (long j = 1; j <= DEFAULT_SEGMENT_SIZE; j++) {
        FSEditLogOp op = FSEditLogTestUtil.getNoOpInstance();
        op.setTransactionId(txid++);
        out.write(op);
      }

      out.close();
      bkjm.finalizeLogSegment(start, (txid - 1));
      assertNotNull(zkc.exists(bkjm.finalizedLedgerZNode(start, (txid - 1)), false));
    }
    long start = txid;
    EditLogOutputStream out =
        bkjm.startLogSegment(start, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
    for (long j = 1; j <= DEFAULT_SEGMENT_SIZE / 2; j++) {
      FSEditLogOp op = FSEditLogTestUtil.getNoOpInstance();
      op.setTransactionId(txid++);
      out.write(op);
    }
    out.setReadyToFlush();
    out.flush();
    out.abort();
    out.close();

    long numTrans = bkjm.getNumberOfTransactions(1, true);
    assertEquals((txid - 1), numTrans);
  }
コード例 #6
0
 private String startAndFinalizeLogSegment(
     BookKeeperJournalManager bkjm, int startTxid, int endTxid)
     throws IOException, KeeperException, InterruptedException {
   EditLogOutputStream out =
       bkjm.startLogSegment(startTxid, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
   for (long i = startTxid; i <= endTxid; i++) {
     FSEditLogOp op = FSEditLogTestUtil.getNoOpInstance();
     op.setTransactionId(i);
     out.write(op);
   }
   out.close();
   // finalize the inprogress_1 log segment.
   bkjm.finalizeLogSegment(startTxid, endTxid);
   String zkpath1 = bkjm.finalizedLedgerZNode(startTxid, endTxid);
   assertNotNull(zkc.exists(zkpath1, false));
   assertNull(zkc.exists(bkjm.inprogressZNode(startTxid), false));
   return zkpath1;
 }
コード例 #7
0
  @Test
  public void testNumberOfTransactions() throws Exception {
    NamespaceInfo nsi = newNSInfo();

    BookKeeperJournalManager bkjm =
        new BookKeeperJournalManager(conf, BKJMUtil.createJournalURI("/hdfsjournal-txncount"), nsi);
    bkjm.format(nsi);

    EditLogOutputStream out = bkjm.startLogSegment(1, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
    for (long i = 1; i <= 100; i++) {
      FSEditLogOp op = FSEditLogTestUtil.getNoOpInstance();
      op.setTransactionId(i);
      out.write(op);
    }
    out.close();
    bkjm.finalizeLogSegment(1, 100);

    long numTrans = bkjm.getNumberOfTransactions(1, true);
    assertEquals(100, numTrans);
  }
コード例 #8
0
  /**
   * Test that if we fail between finalizing an inprogress and deleting the corresponding inprogress
   * znode.
   */
  @Test
  public void testRefinalizeAlreadyFinalizedInprogress() throws Exception {
    URI uri = BKJMUtil.createJournalURI("/hdfsjournal-refinalizeInprogressLedger");
    NamespaceInfo nsi = newNSInfo();
    BookKeeperJournalManager bkjm = new BookKeeperJournalManager(conf, uri, nsi);
    bkjm.format(nsi);

    EditLogOutputStream out = bkjm.startLogSegment(1, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
    ;
    for (long i = 1; i <= 100; i++) {
      FSEditLogOp op = FSEditLogTestUtil.getNoOpInstance();
      op.setTransactionId(i);
      out.write(op);
    }
    out.close();
    bkjm.close();

    String inprogressZNode = bkjm.inprogressZNode(1);
    String finalizedZNode = bkjm.finalizedLedgerZNode(1, 100);
    assertNotNull("inprogress znode doesn't exist", zkc.exists(inprogressZNode, null));
    assertNull("finalized znode exists", zkc.exists(finalizedZNode, null));

    byte[] inprogressData = zkc.getData(inprogressZNode, false, null);

    // finalize
    bkjm = new BookKeeperJournalManager(conf, uri, nsi);
    bkjm.recoverUnfinalizedSegments();
    bkjm.close();

    assertNull("inprogress znode exists", zkc.exists(inprogressZNode, null));
    assertNotNull("finalized znode doesn't exist", zkc.exists(finalizedZNode, null));

    zkc.create(inprogressZNode, inprogressData, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

    // should work fine
    bkjm = new BookKeeperJournalManager(conf, uri, nsi);
    bkjm.recoverUnfinalizedSegments();
    bkjm.close();
  }
コード例 #9
0
  /**
   * If a journal manager has an corrupt inprogress node, ensure that we throw an error, as this
   * should not be possible, and some third party has corrupted the zookeeper state
   */
  @Test
  public void testCorruptInprogressNode() throws Exception {
    URI uri = BKJMUtil.createJournalURI("/hdfsjournal-corruptInprogress");
    NamespaceInfo nsi = newNSInfo();
    BookKeeperJournalManager bkjm = new BookKeeperJournalManager(conf, uri, nsi);
    bkjm.format(nsi);

    EditLogOutputStream out = bkjm.startLogSegment(1, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
    ;
    for (long i = 1; i <= 100; i++) {
      FSEditLogOp op = FSEditLogTestUtil.getNoOpInstance();
      op.setTransactionId(i);
      out.write(op);
    }
    out.close();
    bkjm.finalizeLogSegment(1, 100);

    out = bkjm.startLogSegment(101, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
    out.close();
    bkjm.close();

    String inprogressZNode = bkjm.inprogressZNode(101);
    zkc.setData(inprogressZNode, "WholeLottaJunk".getBytes(), -1);

    bkjm = new BookKeeperJournalManager(conf, uri, nsi);
    try {
      bkjm.recoverUnfinalizedSegments();
      fail("Should have failed. There should be no way of creating" + " an empty inprogess znode");
    } catch (IOException e) {
      // correct behaviour
      assertTrue(
          "Exception different than expected", e.getMessage().contains("has no field named"));
    } finally {
      bkjm.close();
    }
  }
コード例 #10
0
  @Test
  public void testNumberOfTransactionsWithGaps() throws Exception {
    NamespaceInfo nsi = newNSInfo();
    BookKeeperJournalManager bkjm =
        new BookKeeperJournalManager(conf, BKJMUtil.createJournalURI("/hdfsjournal-gaps"), nsi);
    bkjm.format(nsi);

    long txid = 1;
    for (long i = 0; i < 3; i++) {
      long start = txid;
      EditLogOutputStream out =
          bkjm.startLogSegment(start, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
      for (long j = 1; j <= DEFAULT_SEGMENT_SIZE; j++) {
        FSEditLogOp op = FSEditLogTestUtil.getNoOpInstance();
        op.setTransactionId(txid++);
        out.write(op);
      }
      out.close();
      bkjm.finalizeLogSegment(start, txid - 1);
      assertNotNull(zkc.exists(bkjm.finalizedLedgerZNode(start, txid - 1), false));
    }
    zkc.delete(bkjm.finalizedLedgerZNode(DEFAULT_SEGMENT_SIZE + 1, DEFAULT_SEGMENT_SIZE * 2), -1);

    long numTrans = bkjm.getNumberOfTransactions(1, true);
    assertEquals(DEFAULT_SEGMENT_SIZE, numTrans);

    try {
      numTrans = bkjm.getNumberOfTransactions(DEFAULT_SEGMENT_SIZE + 1, true);
      fail("Should have thrown corruption exception by this point");
    } catch (JournalManager.CorruptionException ce) {
      // if we get here, everything is going good
    }

    numTrans = bkjm.getNumberOfTransactions((DEFAULT_SEGMENT_SIZE * 2) + 1, true);
    assertEquals(DEFAULT_SEGMENT_SIZE, numTrans);
  }
コード例 #11
0
  /**
   * Test that a BookKeeper JM can continue to work across the failure of a bookie. This should be
   * handled transparently by bookkeeper.
   */
  @Test
  public void testOneBookieFailure() throws Exception {
    BookieServer bookieToFail = bkutil.newBookie();
    BookieServer replacementBookie = null;

    try {
      int ensembleSize = numBookies + 1;
      assertEquals(
          "New bookie didn't start", ensembleSize, bkutil.checkBookiesUp(ensembleSize, 10));

      // ensure that the journal manager has to use all bookies,
      // so that a failure will fail the journal manager
      Configuration conf = new Configuration();
      conf.setInt(BookKeeperJournalManager.BKJM_BOOKKEEPER_ENSEMBLE_SIZE, ensembleSize);
      conf.setInt(BookKeeperJournalManager.BKJM_BOOKKEEPER_QUORUM_SIZE, ensembleSize);
      long txid = 1;

      NamespaceInfo nsi = newNSInfo();
      BookKeeperJournalManager bkjm =
          new BookKeeperJournalManager(
              conf, BKJMUtil.createJournalURI("/hdfsjournal-onebookiefailure"), nsi);
      bkjm.format(nsi);

      EditLogOutputStream out =
          bkjm.startLogSegment(txid, NameNodeLayoutVersion.CURRENT_LAYOUT_VERSION);
      for (long i = 1; i <= 3; i++) {
        FSEditLogOp op = FSEditLogTestUtil.getNoOpInstance();
        op.setTransactionId(txid++);
        out.write(op);
      }
      out.setReadyToFlush();
      out.flush();

      replacementBookie = bkutil.newBookie();
      assertEquals(
          "replacement bookie didn't start",
          ensembleSize + 1,
          bkutil.checkBookiesUp(ensembleSize + 1, 10));
      bookieToFail.shutdown();
      assertEquals("New bookie didn't die", ensembleSize, bkutil.checkBookiesUp(ensembleSize, 10));

      for (long i = 1; i <= 3; i++) {
        FSEditLogOp op = FSEditLogTestUtil.getNoOpInstance();
        op.setTransactionId(txid++);
        out.write(op);
      }
      out.setReadyToFlush();
      out.flush();
    } catch (Exception e) {
      LOG.error("Exception in test", e);
      throw e;
    } finally {
      if (replacementBookie != null) {
        replacementBookie.shutdown();
      }
      bookieToFail.shutdown();

      if (bkutil.checkBookiesUp(numBookies, 30) != numBookies) {
        LOG.warn("Not all bookies from this test shut down, expect errors");
      }
    }
  }