示例#1
0
  /** This reader collects stats about the log entry. */
  @Override
  protected boolean processEntry(ByteBuffer entryBuffer) {
    byte currentType = currentEntryHeader.getType();
    int itemSize = currentEntryHeader.getItemSize();
    int headerSize = currentEntryHeader.getSize();

    /*
     * Record various stats based on the entry header, then move the buffer
     * forward to skip ahead.
     */
    LogEntryType lastEntryType = LogEntryType.findType(currentType);
    int nextEntryPosition = entryBuffer.position() + itemSize;

    /*
     * Get the info object for it, if this is the first time it's seen,
     * create an info object and insert it.
     */
    EntryInfo info = entryInfoMap.get(lastEntryType);
    if (info == null) {
      info = new EntryInfo();
      entryInfoMap.put(lastEntryType, info);
    }

    /* Update counts. */
    info.count++;
    totalCount++;
    if (currentEntryHeader.getProvisional() == Provisional.YES) {
      info.provisionalCount++;
    }
    int size = itemSize + headerSize;
    info.totalBytes += size;
    info.headerBytes += headerSize;
    totalLogBytes += size;

    if ((info.minBytes == 0) || (info.minBytes > size)) {
      info.minBytes = size;
    }
    if (info.maxBytes < size) {
      info.maxBytes = size;
    }

    if (verbose) {
      if (firstLsnRead == DbLsn.NULL_LSN) {
        firstLsnRead = getLastLsn();
      }

      if (currentType == LogEntryType.LOG_CKPT_END.getTypeNum()) {
        /* Start counting a new interval. */
        ckptCounter.endCkptLsn = getLastLsn();
        ckptCounter = new CheckpointCounter();
        ckptList.add(ckptCounter);
      } else {
        ckptCounter.increment(this, currentType);
      }
    }

    if (lastEntryType.isUserLNType()) {
      /* Read the entry into the ByteBuffer. */
      LNLogEntry<?> entry = (LNLogEntry<?>) lastEntryType.getSharedLogEntry();
      entry.readEntry(envImpl, currentEntryHeader, entryBuffer);

      /*
       * The getUnconvertedXxx methods are used because we don't have a
       * DatabaseImpl for calling LNLogEntry.postFetchInit, and we can
       * tolerate statistics that use the old duplicates format.
       */
      int keyLen = entry.getUnconvertedKeyLength();
      realTotalKeyBytes += keyLen;
      if (!entry.isDeleted()) {
        int dataLen = entry.getUnconvertedDataLength();
        realTotalDataBytes += dataLen;
      }
    }

    entryBuffer.position(nextEntryPosition);
    return true;
  }
  /**
   * This reader looks at all nodes for the max node id and database id. It only returns
   * non-provisional INs and IN delete entries.
   */
  protected boolean processEntry(ByteBuffer entryBuffer) throws DatabaseException {

    boolean useEntry = false;
    boolean entryLoaded = false;

    /* If this is a targetted entry, read the entire log entry. */
    if (targetLogEntry != null) {
      targetLogEntry.readEntry(entryBuffer, currentEntrySize, currentEntryTypeVersion, true);
      DatabaseId dbId = getDatabaseId();
      boolean isMapDb = dbId.equals(DbTree.ID_DB_ID);
      useEntry = (!mapDbOnly || isMapDb);
      entryLoaded = true;
    }

    /* Do a partial load during tracking if necessary. */
    if (trackIds) {

      /*
       * Do partial load of db and txn id tracking entries if necessary.
       * Note that these entries do not overlap with targetLogEntry.
       *
       * XXX We're doing a full load for now, since LNLogEntry does not
       * read the db and txn id in a partial load, only the node id.
       */
      LNLogEntry lnEntry = null;
      if (dbIdTrackingEntry != null) {
        /* This entry has a db id */
        lnEntry = dbIdTrackingEntry;
        lnEntry.readEntry(
            entryBuffer, currentEntrySize, currentEntryTypeVersion, true /* full load */);
        entryLoaded = true;
        MapLN mapLN = (MapLN) lnEntry.getMainItem();
        int dbId = mapLN.getDatabase().getId().getId();
        if (dbId > maxDbId) {
          maxDbId = dbId;
        }
      }
      if (txnIdTrackingEntry != null) {
        /* This entry has a txn id */
        if (lnEntry == null) {
          lnEntry = txnIdTrackingEntry;
          lnEntry.readEntry(
              entryBuffer, currentEntrySize, currentEntryTypeVersion, true /* full load */);
          entryLoaded = true;
        }
        long txnId = lnEntry.getTxnId().longValue();
        if (txnId > maxTxnId) {
          maxTxnId = txnId;
        }
      }

      /*
       * Perform utilization counting under trackIds to prevent
       * double-counting.
       */
      if (fsTrackingEntry != null) {

        /* Must do full load to get key from file summary LN. */
        if (!entryLoaded) {
          nodeTrackingEntry.readEntry(
              entryBuffer, currentEntrySize, currentEntryTypeVersion, true /* full load */);
          entryLoaded = true;
        }

        /*
         * When a FileSummaryLN is encountered, reset the tracked
         * summary for that file to replay what happens when a
         * FileSummaryLN log entry is written.
         */
        byte[] keyBytes = fsTrackingEntry.getKey();
        FileSummaryLN fsln = (FileSummaryLN) fsTrackingEntry.getMainItem();
        long fileNum = fsln.getFileNumber(keyBytes);
        TrackedFileSummary trackedLN = tracker.getTrackedFile(fileNum);
        if (trackedLN != null) {
          trackedLN.reset();
        }

        /* Save the LSN of the FileSummaryLN for use by undo/redo. */
        fileSummaryLsns.put(new Long(fileNum), new Long(getLastLsn()));

        /*
         * SR 10395: Do not cache the file summary in the
         * UtilizationProfile here, since it may be for a deleted log
         * file.
         */
      }

      /*
       * Do partial load of nodeTrackingEntry (and inTrackingEntry) if not
       * already loaded. We only need the node id.
       */
      if (nodeTrackingEntry != null) {
        if (!entryLoaded) {
          nodeTrackingEntry.readEntry(
              entryBuffer, currentEntrySize, currentEntryTypeVersion, false /* partial load */);
          entryLoaded = true;
        }
        /* Keep track of the largest node id seen. */
        long nodeId = nodeTrackingEntry.getNodeId();
        maxNodeId = (nodeId > maxNodeId) ? nodeId : maxNodeId;
      }

      if (inTrackingEntry != null) {
        assert entryLoaded : "All nodes should have been loaded";

        /*
         * Count the obsolete LSN of the previous version, if available
         * and if not already counted. Use inexact counting for two
         * reasons: 1) we don't always have the full LSN because earlier
         * log versions only had the file number, and 2) we can't
         * guarantee obsoleteness for provisional INs.
         */
        long oldLsn = inTrackingEntry.getObsoleteLsn();
        if (oldLsn != DbLsn.NULL_LSN) {
          long newLsn = getLastLsn();
          if (!isObsoleteLsnAlreadyCounted(oldLsn, newLsn)) {
            tracker.countObsoleteNodeInexact(oldLsn, fromLogType);
          }
        }

        /*
         * Count a provisional IN as obsolete if it follows
         * partialCkptStart. It cannot have been already counted,
         * because provisional INs are not normally counted as obsolete;
         * they are only considered obsolete when they are part of a
         * partial checkpoint.
         *
         * Depending on the exact point at which the checkpoint was
         * aborted, this technique is not always accurate; therefore
         * inexact counting must be used.
         */
        if (isProvisional && partialCkptStart != DbLsn.NULL_LSN) {
          oldLsn = getLastLsn();
          if (DbLsn.compareTo(partialCkptStart, oldLsn) < 0) {
            tracker.countObsoleteNodeInexact(oldLsn, fromLogType);
          }
        }
      }
    }

    /* Return true if this entry should be processed */
    return useEntry;
  }