Package com.sleepycat.je.dbi

Examples of com.sleepycat.je.dbi.DatabaseImpl


        /*
         * Do not call releaseDb after this getDb, since the entire dbCache
         * will be released later.
         */
        DatabaseImpl db = env.getDbTree().getDb
            (info.getDbId(), cleaner.lockTimeout, dbCache);

        /* Status variables are used to generate debug tracing info. */
        boolean processedHere = true; // The LN was cleaned here.
        boolean obsolete = false;     // The LN is no longer in use.
        boolean completed = false;    // This method completed.

        BIN bin = null;
        try {
            Tree tree = db.getTree();
            assert tree != null;

            /* Find parent of this LN. */
            boolean parentFound = tree.getParentBINForChildLN
                (location, key, false /*splitsAllowed*/,
 
View Full Code Here


        throws DatabaseException {

        LN lnFromLog = info.getLN();
        byte[] key = info.getKey();

        DatabaseImpl db = bin.getDatabase();
        boolean isTemporary = db.isTemporary();

        /* Status variables are used to generate debug tracing info. */
        boolean obsolete = false// The LN is no longer in use.
        boolean migrated = false// The LN was in use and is migrated.
        boolean lockDenied = false;// The LN lock was denied.
        boolean completed = false; // This method completed.

        BasicLocker locker = null;
        try {
            Tree tree = db.getTree();
            assert tree != null;

            /*
             * If the tree and log LSNs are equal, then we can be fairly
             * certain that the log entry is current; in that case, it is
             * wasteful to lock the LN here if we will perform lazy migration
             * -- it is better to lock only once during lazy migration.  But if
             * the tree and log LSNs differ, it is likely that another thread
             * has updated or deleted the LN and the log LSN is now obsolete;
             * in this case we can avoid dirtying the BIN by checking for
             * obsoleteness here, which requires locking.  The latter case can
             * occur frequently if trackDetail is false.
             *
             * 1. If the LSN in the tree and in the log are the same, we will
             * attempt to migrate it.
             *
             * 2. If the LSN in the tree is < the LSN in the log, the log entry
             * is obsolete, because this LN has been rolled back to a previous
             * version by a txn that aborted.
             *
             * 3. If the LSN in the tree is > the LSN in the log, the log entry
             * is obsolete, because the LN was advanced forward by some
             * now-committed txn.
             *
             * 4. If the LSN in the tree is a null LSN, the log entry is
             * obsolete. A slot can only have a null LSN if the record has
             * never been written to disk in a deferred write database, and
             * in that case the log entry must be for a past, deleted version
             * of that record.
             */
            if (lnFromLog.isDeleted() &&
                (treeLsn == logLsn) &&
                fileLogVersion <= 2) {

                /*
                 * SR 14583: After JE 2.0, deleted LNs are never found in the
                 * tree, since we can assume they're obsolete and correctly
                 * marked as such in the obsolete offset tracking. JE 1.7.1 and
                 * earlier did not use the pending deleted bit, so deleted LNs
                 * may still be reachable through their BIN parents.
                 */
                obsolete = true;
                nLNsDeadThisRun++;
                bin.setPendingDeleted(index);
            } else if (treeLsn == DbLsn.NULL_LSN) {

                /*
                 * Case 4: The LN in the tree is a never-written LN for a
                 * deferred-write db, so the LN in the file is obsolete.
                 */
                obsolete = true;
            } else if (treeLsn != logLsn && isTemporary) {

                /*
                 * Temporary databases are always non-transactional.  If the
                 * tree and log LSNs are different then we know that the logLsn
                 * is obsolete.  Even if the LN is locked, the tree cannot be
                 * restored to the logLsn because no abort is possible without
                 * a transaction.  We should consider a similar optimization in
                 * the future for non-transactional durable databases.
                 */
                nLNsDeadThisRun++;
                obsolete = true;
            } else if ((treeLsn != logLsn || !cleaner.lazyMigration) &&
                       !isTemporary) {

                /*
                 * Get a lock on the LN if the treeLsn and logLsn are different
                 * to determine definitively whether the logLsn is obsolete.
                 * We must also get a lock if we will migrate the LN now
                 * (lazyMigration is false and isTemporary is false).
                 *
                 * We can hold the latch on the BIN since we always attempt to
                 * acquire a non-blocking read lock.
                 */
                locker = BasicLocker.createBasicLocker(env, false /*noWait*/);
                /* Don't allow this short-lived lock to be preempted/stolen. */
                locker.setPreemptable(false);
                LockResult lockRet = locker.nonBlockingLock
                    (treeLsn, LockType.READ, false /*jumpAheadOfWaiters*/, db);
                if (lockRet.getLockGrant() == LockGrantType.DENIED) {

                    /*
                     * LN is currently locked by another Locker, so we can't
                     * assume anything about the value of the LSN in the bin.
                     */
                    nLNsLockedThisRun++;
                    lockDenied = true;
                } else if (treeLsn != logLsn) {
                    /* The LN is obsolete and can be purged. */
                    nLNsDeadThisRun++;
                    obsolete = true;
                }
            }

            /*
             * At this point either obsolete==true, lockDenied==true, or
             * treeLsn==logLsn.
             */
            if (!obsolete && !lockDenied) {
                assert treeLsn == logLsn;

                /*
                 * If lazyMigration is true, set the migrate flag and dirty
                 * the parent IN.  The evictor or checkpointer will migrate the
                 * LN later.  If lazyMigration is false, migrate the LN now.
                 *
                 * We have a lock on the LN if we are going to migrate it now,
                 * but not if we will set the migrate flag.
                 *
                 * When setting the migrate flag, also populate the target node
                 * so it does not have to be fetched when it is migrated, if
                 * the tree and log LSNs are equal and the target is not
                 * resident.  We must call postFetchInit to initialize MapLNs
                 * that have not been fully initialized yet [#13191].
                 *
                 * For temporary databases, do not rely on the LN migration
                 * mechanism because temporary databases are not checkpointed
                 * or recovered.  Instead, dirty the LN to ensure it is
                 * flushed before its parent is written.  Because we do not
                 * attempt to lock temporary database LNs (see above) we know
                 * that if it is non-obsolete, the tree and log LSNs are equal.
                 * We will always restore the LN to the BIN slot here, and
                 * always log the dirty LN when logging the BIN.
                 *
                 * Also for temporary databases, make both the target LN and
                 * the BIN or IN parent dirty. Otherwise, when the BIN or IN is
                 * evicted in the future, it will be written to disk without
                 * flushing its dirty, migrated LNs.  [#18227]
                 */
                if (bin.getTarget(index) == null) {
                    lnFromLog.postFetchInit(db, logLsn);
                    /* Ensure keys are transactionally correct. [#15704] */
                    bin.updateNode(index, lnFromLog, key /*lnSlotKey*/);
                }

                if (isTemporary) {
                    ((LN) bin.getTarget(index)).setDirty();
                    bin.setDirty(true);
                } else if (cleaner.lazyMigration) {
                    bin.setMigrate(index, true);
                    bin.setDirty(true);
                } else {
                    LN targetLn = (LN) bin.getTarget(index);
                    assert targetLn != null;
                    long newLNLsn = targetLn.log
                        (env, db, bin.getKey(index), logLsn,
                         true /*backgroundIO*/,
                         Cleaner.getMigrationRepContext(targetLn));
                    bin.updateEntry(index, newLNLsn);
                    /* Evict LN if we populated it with the log LN. */
                    if (lnFromLog == targetLn) {
                        bin.updateNode(index, null, null);
                    }
                    /* Lock new LSN on behalf of existing lockers. */
                    CursorImpl.lockAfterLsnChange
                        (db, logLsn, newLNLsn, locker /*excludeLocker*/);
                }

                /*
                 * If the generation is zero, we fetched this BIN just for
                 * cleaning.
                 */
                if (PROHIBIT_DELTAS_WHEN_FETCHING &&
                    bin.getGeneration() == 0) {
                    bin.setProhibitNextDelta();
                }

                /*
                 * Update the generation so that the BIN is not evicted
                 * immediately.  This allows the cleaner to fill in as many
                 * entries as possible before eviction, as to-be-cleaned
                 * files are processed.
                 */
                bin.setGeneration(CacheMode.DEFAULT);

                nLNsMarkedThisRun++;
                migrated = true;
            }
            completed = true;
        } finally {
            if (locker != null) {
                locker.operationEnd();
            }

            /*
             * If a write lock is held, it is likely that the log LSN will
             * become obsolete.  It is more efficient to process this via the
             * pending list than to set the MIGRATE flag, dirty the BIN, and
             * cause the BIN to be logged unnecessarily.
             */
            if (completed && lockDenied) {
                assert !isTemporary;

                /*
                 * We could associate the pending LN with either treeLsn or
                 * logLsn, we just need a convention to follow.  When
                 * processing the pending LN, we always check to see if the LSN
                 * has changed after we latch the BIN.  For consistency with
                 * other places that call addPendingLN, we use treeLsn here.
                 */
                fileSelector.addPendingLN(treeLsn, lnFromLog, db.getId(), key);
            }

            cleaner.logFine(Cleaner.CLEAN_LN, lnFromLog, logLsn, completed,
                            obsolete, migrated);
        }
View Full Code Here

               
            }
            nIterated++;
            scanInfo.numNodesScanned++;

            DatabaseImpl db = in.getDatabase();

            /*
             * Ignore the IN if its database is deleted.  We have not called
             * getDb, so we can't guarantee that the DB is valid; get Db is
             * called and this is checked again after an IN is selected for
             * eviction.
             */
            if (db == null || db.isDeleted()) {
                continue;
            }

            /*
             * If this is a read-only environment, skip any dirty INs (recovery
             * dirties INs even in a read-only environment).
             */
            if (db.getDbEnvironment().isReadOnly() &&
                in.getDirty()) {
                continue;
            }

            /*
 
View Full Code Here

     * Returns the duplicate key for a given BIN entry.
     */
    private byte[] getLNDupKey(BIN bin, int index, LN ln)
        throws DatabaseException {

        DatabaseImpl db = bin.getDatabase();

        if (!db.getSortedDuplicates()) {

            /* The dup key is not needed for a non-duplicate DB. */
            return null;

        } else if (bin.containsDuplicates()) {
View Full Code Here

                /* The entry is not known to be obsolete -- process it now. */
                if (reader.isLN()) {

                    LN targetLN = reader.getLN();
                    DatabaseId dbId = reader.getDatabaseId();
                    DatabaseImpl db = dbMapTree.getDb(dbId, lockTimeout);

                    processLN
                        (targetLN, db, reader.getKey(),
                         reader.getDupTreeKey(), lsn, location);


                } else if (reader.isIN()) {

                    IN targetIN = reader.getIN();
                    DatabaseId dbId = reader.getDatabaseId();
                    DatabaseImpl db = dbMapTree.getDb(dbId, lockTimeout);
                    targetIN.setDatabase(db);
                   
                    processIN(targetIN, db, lsn);
                   
                } else if (reader.isRoot()) {
View Full Code Here

     * for performance reasons.
     */
    public void handleNoMigrationLogging(BIN bin)
        throws DatabaseException {

        DatabaseImpl db = bin.getDatabase();

        /*
         * We must fetch the node here in order to obtain enough information to
         * look up the entry later.  This is not desirable during a split, but
         * in fact the node is rarely non-resident.  The migrate flag prevents
         * LN stripping, so the only time the node is null is after an abort.
         */
        for (int index = 0; index < bin.getNEntries(); index++) {

            if (bin.getMigrate(index)) {

                /*
                 * fetchTarget should never return null if the MIGRATE flag is
                 * set, since the LN is not yet cleaned.
                 */
                LN ln = (LN) bin.fetchTarget(index);
                assert ln != null;

                byte[] key = getLNMainKey(bin, index);
                byte[] dupKey = getLNDupKey(bin, index, ln);

                fileSelector.addPendingLN(ln, db.getId(), key, dupKey);

                bin.setMigrate(index, false);
            }
        }
    }
View Full Code Here

        for (int i = 0; i < pendingLNs.length; i += 1) {
            LNInfo info = pendingLNs[i];

            DatabaseId dbId = info.getDbId();
            DatabaseImpl db = dbMapTree.getDb(dbId, lockTimeout);

            byte[] key = info.getKey();
            byte[] dupKey = info.getDupKey();
            LN ln = info.getLN();
View Full Code Here

     * method.
     */
    public void migrateLNs(BIN bin)
        throws DatabaseException {

        DatabaseImpl db = bin.getDatabase();

        boolean isBinInDupDb = db.getSortedDuplicates() &&
                               !bin.containsDuplicates();

        for (int index = 0; index < bin.getNEntries(); index += 1) {

            long childLsn = bin.getLsn(index);
View Full Code Here

    public void testEntryData()
        throws Throwable {

        try {
            ByteBuffer buffer = ByteBuffer.allocate(1000);
            database = new DatabaseImpl("foo", new DatabaseId(1),
                                        env, new DatabaseConfig());

            /*
             * For each loggable object, can we write the entry data out?
             */
 
View Full Code Here

    public BIN reconstituteBIN(EnvironmentImpl env)
        throws DatabaseException {
               
        /* Get the last full version of this BIN. */
        BIN fullBIN = (BIN) env.getLogManager().get(lastFullLsn);
        DatabaseImpl db = env.getDbMapTree().getDb(dbId);

  /*
   * In effect, call fullBIN.postFetchInit(db) here.  But we don't want
   * to do that since it will put fullBIN on the INList.  Since this is
   * either recovery or during the Cleaner run, we don't want it on the
View Full Code Here

TOP

Related Classes of com.sleepycat.je.dbi.DatabaseImpl

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.