예제 #1
0
  /**
   * Evict a single LN if allowed. The amount of memory freed is returned and must be subtracted
   * from the memory budget by the caller.
   */
  private long evictInternal(int index, Cleaner cleaner) throws DatabaseException {

    Node n = getTarget(index);

    if (n instanceof LN) {
      LN ln = (LN) n;

      /*
       * Don't evict MapLNs for open databases (LN.isEvictable) [#13415].
       * And don't strip LNs that the cleaner will be migrating
       * (Cleaner.isEvictable).
       */
      if (ln.isEvictable() && cleaner.isEvictable(this, index)) {

        boolean force = getDatabase().isDeferredWriteMode() && getLsn(index) == DbLsn.NULL_LSN;
        /* Log target if necessary. */
        logDirtyLN(index, (LN) n, force);

        /* Clear target. */
        setTarget(index, null);
        ln.releaseMemoryBudget();

        return n.getMemorySizeIncludedByParent();
      }
    }
    return 0;
  }
  public int invokeCleaner() throws DatabaseException {

    if (cleaner != null) {
      return cleaner.doClean(
          true, // cleanMultipleFiles
          false); // forceCleaning
    } else {
      return 0;
    }
  }
예제 #3
0
  /**
   * Note that the IN may or may not be latched when this method is called. Returning the wrong
   * answer is OK in that case (it will be called again later when latched), but an exception should
   * not occur.
   */
  @Override
  int getChildEvictionType() {

    Cleaner cleaner = getDatabase().getDbEnvironment().getCleaner();

    for (int i = 0; i < getNEntries(); i++) {
      Node node = getTarget(i);
      if (node != null) {
        if (node instanceof LN) {
          LN ln = (LN) node;

          /*
           * If the LN is not evictable, we may neither strip the LN
           * nor evict the node.  isEvictableInexact is used here as
           * a fast check, to avoid the overhead of acquiring a
           * handle lock while selecting an IN for eviction.   See
           * evictInternal which will call LN.isEvictable to acquire
           * an handle lock and guarantee that another thread cannot
           * open the MapLN.  [#13415]
           */
          if (!ln.isEvictableInexact()) {
            return MAY_NOT_EVICT;
          }

          /*
           * If the cleaner allows eviction, then this LN may be
           * stripped.
           */
          if (cleaner.isEvictable(this, i)) {
            return MAY_EVICT_LNS;
          }
        } else {
          return MAY_NOT_EVICT;
        }
      }
    }
    return MAY_EVICT_NODE;
  }
 /** Returns the UtilizationProfile. */
 public UtilizationProfile getUtilizationProfile() {
   return cleaner.getUtilizationProfile();
 }
 /** Returns the UtilizationTracker. */
 public UtilizationTracker getUtilizationTracker() {
   return cleaner.getUtilizationTracker();
 }
예제 #6
0
  /** Helper for doCheckpoint. Same args only this is called with the evictor locked out. */
  private synchronized void doCheckpointInternal(
      CheckpointConfig config,
      boolean allowDeltas,
      boolean flushAll,
      boolean deleteAllCleanedFiles,
      String invokingSource)
      throws DatabaseException {

    if (!isRunnable(config)) {
      return;
    }

    /*
     * If there are cleaned files to be deleted, flush an extra level to
     * write out the parents of cleaned nodes.  This ensures that the
     * no node will contain the LSN of a cleaned files.
     */
    boolean flushExtraLevel = false;
    Set cleanedFiles = null;
    Cleaner cleaner = envImpl.getCleaner();
    if (cleaner != null) {
      cleanedFiles = cleaner.getCleanedFiles(deleteAllCleanedFiles);
      if (cleanedFiles != null) {
        flushExtraLevel = true;
      }
    }

    lastCheckpointMillis = System.currentTimeMillis();
    resetPerRunCounters();
    LogManager logManager = envImpl.getLogManager();

    /* Get the next checkpoint id. */
    checkpointId++;
    nCheckpoints++;
    boolean success = false;
    boolean traced = false;
    try {
      /* Log the checkpoint start. */
      CheckpointStart startEntry = new CheckpointStart(checkpointId, invokingSource);
      DbLsn checkpointStart = logManager.log(startEntry);

      /*
       * Remember the first active lsn -- before this position in the
       * log, there are no active transactions at this point in time.
       */
      DbLsn firstActiveLsn = envImpl.getTxnManager().getFirstActiveLsn();

      if (firstActiveLsn != null && checkpointStart.compareTo(firstActiveLsn) < 0) {
        firstActiveLsn = checkpointStart;
      }

      /* Flush IN nodes. */
      flushDirtyNodes(flushAll, allowDeltas, flushExtraLevel);

      /*
       * Flush utilization info AFTER flushing IN nodes to reduce the
       * inaccuracies caused by the sequence FileSummaryLN-LN-BIN.
       */
      flushUtilizationInfo();

      /* Log the checkpoint end. */
      if (firstActiveLsn == null) {
        firstActiveLsn = checkpointStart;
      }
      CheckpointEnd endEntry =
          new CheckpointEnd(
              invokingSource,
              checkpointStart,
              envImpl.getRootLsn(),
              firstActiveLsn,
              Node.getLastId(),
              envImpl.getDbMapTree().getLastDbId(),
              envImpl.getTxnManager().getLastTxnId(),
              checkpointId);

      /*
       * Log checkpoint end and update state kept about the last
       * checkpoint location. Send a trace message *before* the
       * checkpoint end log entry. This is done  so that the  normal
       * trace  message doesn't affect the time-based isRunnable()
       * calculation, which only issues a checkpoint if a log record
       * has been written since the last checkpoint.
       */
      trace(envImpl, invokingSource, true);
      traced = true;

      /*
       * Always flush to ensure that cleaned files are not referenced,
       * and to ensure that this checkpoint is not wasted if we crash.
       */
      lastCheckpointEnd = logManager.logForceFlush(endEntry);
      lastFirstActiveLsn = firstActiveLsn;
      lastCheckpointStart = checkpointStart;

      success = true;

      if (cleaner != null && cleanedFiles != null) {
        cleaner.deleteCleanedFiles(cleanedFiles);
      }
    } catch (DatabaseException e) {
      Tracer.trace(envImpl, "Checkpointer", "doCheckpoint", "checkpointId=" + checkpointId, e);
      throw e;
    } finally {
      if (!traced) {
        trace(envImpl, invokingSource, success);
      }
    }
  }