예제 #1
0
 /**
  * Return a <code>BufferInfo</code> reflecting the state of a page containing the specified key.
  * The <code>volumeName</code> and <code>treeName</code> parameters specify a {@link Tree} in
  * which to seach for the key. The <code>level</code> parameter indicates whether the data page,
  * or one of the pages on the index path to that data page should be returned. Level 0 refers to
  * the data path, level 1 is the lowest index level, and level d-1 where d is the number of levels
  * in the the tree represents the three's root page.
  *
  * <p>Specify <code>treeName</code> as <code>null</code> to access the volume's directory tree.
  *
  * @param volumeName the name of the volume
  * @param treeName the name of the tree within the volume, or <code>null</code> for the directory
  *     tree
  * @param key a <code>KeyState</code> representing a key
  * @param level tree level: 0 for root, 1...d-1 for index pages of a tree having depth d.
  * @return a <code>BufferInfo</code> object reflecting the selected page, or <code>null</code> if
  *     the specified tree does not exist.
  * @throws RemoteException
  */
 @Override
 public BufferInfo getBufferInfo(
     final String volumeName, final String treeName, final KeyState key, final int level)
     throws RemoteException {
   try {
     Exchange exchange;
     final Volume volume = _persistit.getVolume(volumeName);
     if (volume == null) {
       return null;
     }
     if (treeName == null) {
       exchange = volume.getStructure().directoryExchange();
     } else {
       exchange = _persistit.getExchange(volume, treeName, false);
     }
     key.copyTo(exchange.getKey());
     final Buffer buffer = exchange.fetchBufferCopy(level);
     final BufferInfo info = new BufferInfo();
     buffer.populateInfo(info);
     return info;
   } catch (final TreeNotFoundException tnfe) {
     return null;
   } catch (final PersistitException pe) {
     throw new WrappedRemoteException(pe);
   }
 }
  @Test
  public void useOldVSpecInducesExpectedFailure() throws Exception {
    VolumeSpecification volumeSpec;
    final Configuration configuration = _persistit.getConfiguration();
    _persistit.close();
    int remainingJournalFiles = 0;
    configuration.setUseOldVSpec(true);

    for (int i = 5; --i >= 0; ) {
      final Persistit db = new Persistit(_config);
      try {
        volumeSpec =
            new VolumeSpecification(
                DATA_PATH + "/hwdemo" + i, null, 16384, 1, 1000, 1, true, false, false);
        db.loadVolume(volumeSpec);
        final Exchange dbex = db.getExchange("hwdemo" + i, "greetings", true);
        dbex.getKey().append("Hello");
        dbex.getValue().put("World");
        dbex.store();
        dbex.getKey().to(Key.BEFORE);
        db.releaseExchange(dbex);
      } finally {
        if (i == 0) {
          db.copyBackPages();
        }
        remainingJournalFiles = db.getJournalManager().getJournalFileCount();
        db.close();
      }
    }
    assertTrue("Should be only one remaining journal file", remainingJournalFiles > 1);
  }
  /**
   * Test for bug https://bugs.launchpad.net/akiban-persistit/+bug/1045983
   *
   * Truncating a dynamically created volume results in corrupted journal If
   * you dynamically load a volume, truncate it (without adding any trees),
   * and then close it, the next time the database is initialized a fatal
   * exception is thrown:
   *
   * <code><pre>
   *
   * [JOURNAL_COPIER] WARNING Missing volume truncated referenced at journal address 364
   * [main] WARNING Missing volume truncated referenced at journal address 17,004 (6 similar occurrences in 0 seconds)
   * Exception in thread "main" com.persistit.exception.InvalidPageAddressException: Page 1 out of bounds [0-1]
   *  at com.persistit.VolumeStorageV2.readPage(VolumeStorageV2.java:426)
   *  at com.persistit.Buffer.load(Buffer.java:456)
   *  at com.persistit.BufferPool.get(BufferPool.java:780)
   *  at com.persistit.Tree.setRootPageAddress(Tree.java:203)
   *  at com.persistit.VolumeStructure.init(VolumeStructure.java:70)
   *  at com.persistit.VolumeStorageV2.open(VolumeStorageV2.java:217)
   *  at com.persistit.Volume.open(Volume.java:442)
   *  at com.persistit.Persistit.loadVolume(Persistit.java:1066)
   *  at Truncate.main(Truncate.java:30)
   *
   * @throws Exception
   *
   *             </pre></code>
   *
   *             This test is currently disabled pending a fix.
   *
   */
  @Test
  @Ignore
  public void truncateDynamicVolumes() throws Exception {

    VolumeSpecification volumeSpec;
    _persistit.close();

    final Persistit db = new Persistit(_config);

    for (int i = 0; i < 2; i++) {
      try {
        volumeSpec =
            new VolumeSpecification(
                DATA_PATH + "/truncated", null, 16384, 1, 1000, 1, true, false, false);
        final Volume volume = db.loadVolume(volumeSpec);
        volume.truncate();
        // the following may be omitted, and the problem still exhibited
        final Exchange dbex = db.getExchange("truncated", "greetings", true);
        dbex.getKey().append("ave");
        dbex.getValue().put("mundus");
        dbex.store();
        dbex.getKey().to(Key.BEFORE);
        while (dbex.next()) {
          System.out.println(dbex.getKey().reset().decode() + " " + dbex.getValue().get());
        }
        db.releaseExchange(dbex);
        // the preceding may be omitted, and the problem still exhibited
      } finally {
        db.close();
      }
    }
  }
예제 #4
0
  @Override
  public LogicalRecord[] getLogicalRecordArray(
      final String volumeName,
      final String treeName,
      final String keyFilterString,
      final KeyState fromKey,
      final Key.Direction direction,
      final int maxCount,
      final int maxValueBytes,
      final boolean decodeStrings)
      throws RemoteException {
    LogicalRecord[] records = new LogicalRecord[maxCount];
    int count = 0;
    final boolean forward = direction == Key.GT || direction == Key.GTEQ;
    Exchange exchange = null;
    try {
      if (treeName.equals(VolumeStructure.DIRECTORY_TREE_NAME)) {
        exchange = _persistit.getVolume(volumeName).getStructure().directoryExchange();
      } else {
        exchange = _persistit.getExchange(volumeName, treeName, false);
      }
      exchange.ignoreMVCCFetch(true);
      KeyFilter filter = null;
      if (keyFilterString != null && keyFilterString.length() > 0) {
        filter = new KeyFilter(keyFilterString);
      }
      fromKey.copyTo(exchange.getKey());
      for (; count < maxCount; count++) {
        if (!exchange.traverse(direction, filter, maxValueBytes)) {
          break;
        } else {
          final LogicalRecord record = new LogicalRecord();
          record._key = new KeyState(exchange.getKey());
          record._value = new ValueState(exchange.getValue(), maxValueBytes);

          if (decodeStrings) {
            record._keyString = _displayFilter.toKeyDisplayString(exchange);
            record._valueString = _displayFilter.toValueDisplayString(exchange);
          }

          if (forward) {
            records[count] = record;
          } else {
            records[maxCount - count - 1] = record;
          }
        }
      }
    } catch (final Exception e) {
      throw new WrappedRemoteException(e);
    } finally {
      exchange.ignoreMVCCFetch(false);
    }
    if (count < maxCount) {
      final LogicalRecord[] trimmed = new LogicalRecord[count];
      System.arraycopy(records, forward ? 0 : maxCount - count, trimmed, 0, count);
      records = trimmed;
    }
    return records;
  }
예제 #5
0
 private Exchange getExchange() throws PersistitException {
   try {
     final Volume volume = _persistit.getSystemVolume();
     return _persistit.getExchange(volume, CLASS_INDEX_TREE_NAME, true);
   } catch (final PersistitException pe) {
     throw new ConversionException(pe);
   }
 }
예제 #6
0
  @Override
  public LogicalRecordCount getLogicalRecordCount(
      final String volumeName,
      final String treeName,
      final String keyFilterString,
      final KeyState fromKey,
      final Key.Direction direction,
      final int maxCount)
      throws RemoteException {
    int count = 0;
    Exchange exchange = null;
    KeyState endKeyState = null;

    try {
      exchange = _persistit.getExchange(volumeName, treeName, false);
      exchange.getAuxiliaryKey2().clear();
      KeyFilter filter = null;
      if (keyFilterString != null && keyFilterString.length() > 0) {
        filter = new KeyFilter(keyFilterString);
      }
      fromKey.copyTo(exchange.getKey());
      for (; count < maxCount; count++) {
        if (!exchange.traverse(direction, filter, 0)) {
          break;
        } else {
          exchange.getKey().copyTo(exchange.getAuxiliaryKey2());
        }
      }
      endKeyState = new KeyState(exchange.getAuxiliaryKey2());
    } catch (final Exception pe) {
      throw new WrappedRemoteException(pe);
    } finally {
      if (exchange != null) _persistit.releaseExchange(exchange);
    }
    return new LogicalRecordCount(endKeyState, count);
  }