Beispiel #1
0
    // This free function is used by the initial sync writer threads to apply each op
    void multiInitialSyncApply(const std::vector<BSONObj>& ops, SyncTail* st) {
        initializeWriterThread();
        for (std::vector<BSONObj>::const_iterator it = ops.begin();
             it != ops.end();
             ++it) {
            try {
                OperationContextImpl txn;

                if (!st->syncApply(&txn, *it)) {
                    bool status;
                    {
                        Lock::GlobalWrite lk(txn.lockState());
                        status = st->shouldRetry(&txn, *it);
                    }

                    if (status) {
                        // retry
                        if (!st->syncApply(&txn, *it)) {
                            fassertFailedNoTrace(15915);
                        }
                    }
                    // If shouldRetry() returns false, fall through.
                    // This can happen if the document that was moved and missed by Cloner
                    // subsequently got deleted and no longer exists on the Sync Target at all
                }
            }
            catch (const DBException& e) {
                error() << "exception: " << causedBy(e) << " on: " << it->toString() << endl;
                fassertFailedNoTrace(16361);
            }
        }
    }
Beispiel #2
0
    void ReplSetImpl::_assumePrimary() {
        LOG(1) << "replSet assuming primary" << endl;
        verify(iAmPotentiallyHot());

        // Wait for replication to stop and buffer to be consumed
        LOG(1) << "replSet waiting for replication to finish before becoming primary" << endl;
        BackgroundSync::get()->stopReplicationAndFlushBuffer();

        // Lock here to prevent stepping down & becoming primary from getting interleaved
        LOG(1) << "replSet waiting for global write lock";

        OperationContextImpl txn;   // XXX?
        Lock::GlobalWrite lk(txn.lockState());

        initOpTimeFromOplog(&txn, "local.oplog.rs");

        // Generate new election unique id
        elect.setElectionId(OID::gen());
        LOG(1) << "replSet truly becoming primary";
        changeState(MemberState::RS_PRIMARY);

        // This must be done after becoming primary but before releasing the write lock. This adds
        // the dropCollection entries for every temp collection to the opLog since we want it to be
        // replicated to secondaries.
        dropAllTempCollections(&txn);
    }
Beispiel #3
0
static void replMasterThread() {
    sleepsecs(4);
    Client::initThread("replmaster");
    int toSleep = 10;
    while (1) {
        sleepsecs(toSleep);

        // Write a keep-alive like entry to the log. This will make things like
        // printReplicationStatus() and printSlaveReplicationStatus() stay up-to-date even
        // when things are idle.
        OperationContextImpl txn;
        txn.getClient()->getAuthorizationSession()->grantInternalAuthorization();

        Lock::GlobalWrite globalWrite(txn.lockState(), 1);
        if (globalWrite.isLocked()) {
            toSleep = 10;

            try {
                WriteUnitOfWork wuow(&txn);
                logKeepalive(&txn);
                wuow.commit();
            } catch (...) {
                log() << "caught exception in replMasterThread()" << endl;
            }
        } else {
            LOG(5) << "couldn't logKeepalive" << endl;
            toSleep = 1;
        }
    }
}
Beispiel #4
0
    void run() {
        OperationContextImpl txn;
        DBDirectClient client(&txn);

        for ( int i = 0; i < 10; ++i ) {
            client.insert( ns, BSON( "_id" << i ) );
        }

        {
            // Remove _id range [_min, _max).
            Lock::DBWrite lk(txn.lockState(), ns);
            WriteUnitOfWork wunit(txn.recoveryUnit());
            Client::Context ctx(&txn,  ns );

            KeyRange range( ns,
                            BSON( "_id" << _min ),
                            BSON( "_id" << _max ),
                            BSON( "_id" << 1 ) );
            mongo::WriteConcernOptions dummyWriteConcern;
            Helpers::removeRange(&txn, range, false, dummyWriteConcern);
            wunit.commit();
        }

        // Check that the expected documents remain.
        ASSERT_EQUALS( expected(), docs(&txn) );
    }
Beispiel #5
0
    TEST(DBHelperTests, FindDiskLocsNoIndex) {
        OperationContextImpl txn;
        DBDirectClient client(&txn);

        client.remove( ns, BSONObj() );
        client.insert( ns, BSON( "_id" << OID::gen() ) );

        long long maxSizeBytes = 1024 * 1024 * 1024;

        set<DiskLoc> locs;
        long long numDocsFound;
        long long estSizeBytes;
        {
            Lock::DBRead lk(txn.lockState(), ns);

            // search invalid index range
            KeyRange range( ns,
                            BSON( "badIndex" << 0 ),
                            BSON( "badIndex" << 10 ),
                            BSON( "badIndex" << 1 ) );

            Status result = Helpers::getLocsInRange( &txn,
                                                     range,
                                                     maxSizeBytes,
                                                     &locs,
                                                     &numDocsFound,
                                                     &estSizeBytes );

            // Make sure we get the right error code
            ASSERT_EQUALS( result.code(), ErrorCodes::IndexNotFound );
            ASSERT_EQUALS( static_cast<long long>( locs.size() ), 0 );
            ASSERT_EQUALS( numDocsFound, 0 );
            ASSERT_EQUALS( estSizeBytes, 0 );
        }
    }
// This free function is used by the writer threads to apply each op
void multiSyncApply(const std::vector<BSONObj>& ops, SyncTail* st) {
    initializeWriterThread();

    OperationContextImpl txn;
    txn.setReplicatedWrites(false);
    DisableDocumentValidation validationDisabler(&txn);

    // allow us to get through the magic barrier
    txn.lockState()->setIsBatchWriter(true);

    bool convertUpdatesToUpserts = true;

    for (std::vector<BSONObj>::const_iterator it = ops.begin(); it != ops.end(); ++it) {
        try {
            const Status s = SyncTail::syncApply(&txn, *it, convertUpdatesToUpserts);
            if (!s.isOK()) {
                severe() << "Error applying operation (" << it->toString() << "): " << s;
                fassertFailedNoTrace(16359);
            }
        } catch (const DBException& e) {
            severe() << "writer worker caught exception: " << causedBy(e)
                     << " on: " << it->toString();

            if (inShutdown()) {
                return;
            }

            fassertFailedNoTrace(16360);
        }
    }
}
Beispiel #7
0
    static void logStartup() {
        BSONObjBuilder toLog;
        stringstream id;
        id << getHostNameCached() << "-" << jsTime();
        toLog.append( "_id", id.str() );
        toLog.append( "hostname", getHostNameCached() );

        toLog.appendTimeT( "startTime", time(0) );
        toLog.append( "startTimeLocal", dateToCtimeString(curTimeMillis64()) );

        toLog.append("cmdLine", serverGlobalParams.parsedOpts);
        toLog.append( "pid", ProcessId::getCurrent().asLongLong() );


        BSONObjBuilder buildinfo( toLog.subobjStart("buildinfo"));
        appendBuildInfo(buildinfo);
        buildinfo.doneFast();

        BSONObj o = toLog.obj();

        OperationContextImpl txn;

        Lock::GlobalWrite lk(txn.lockState());
        DBDirectClient c(&txn);

        static const char* name = "local.startup_log";
        c.createCollection( name, 10 * 1024 * 1024, true );
        c.insert( name, o);
    }
Beispiel #8
0
 OpTime ReplSetImpl::getEarliestOpTimeWritten() const {
     OperationContextImpl txn; // XXX?
     Lock::DBRead lk(txn.lockState(), rsoplog);
     BSONObj o;
     uassert(17347, "Problem reading earliest entry from oplog",
             Helpers::getFirst(&txn, rsoplog, o));
     return o["ts"]._opTime();
 }
Beispiel #9
0
 OpTime ReplSetImpl::getMinValid() {
     OperationContextImpl txn; // XXX?
     Lock::DBRead lk(txn.lockState(), "local.replset.minvalid");
     BSONObj mv;
     if (Helpers::getSingleton(&txn, "local.replset.minvalid", mv)) {
         return mv["ts"]._opTime();
     }
     return OpTime();
 }
Beispiel #10
0
        void run() {
            OperationContextImpl txn;
            Lock::DBWrite lk(txn.lockState(), _cappedNs);

            BSONObj op = updateFail();

            Sync s("");
            verify(!s.shouldRetry(&txn, op));
        }
Beispiel #11
0
 bool ReplSetImpl::getInitialSyncFlag() {
     OperationContextImpl txn; // XXX?
     Lock::DBRead lk (txn.lockState(), "local");
     BSONObj mv;
     if (Helpers::getSingleton(&txn, minvalidNS, mv)) {
         return mv[_initialSyncFlagString].trueValue();
     }
     return false;
 }
Beispiel #12
0
        ~IndexIteratorTests() {
            OperationContextImpl txn;
            Lock::DBLock lk(txn.lockState(), nsToDatabaseSubstring(_ns), MODE_X);
            Client::Context ctx(&txn, _ns);
            WriteUnitOfWork wuow(&txn);

            _db->dropCollection(&txn, _ns);
            wuow.commit();
        }
Beispiel #13
0
    void ReplSetImpl::setMinValid(BSONObj obj) {
        BSONObjBuilder builder;
        BSONObjBuilder subobj(builder.subobjStart("$set"));
        subobj.appendTimestamp("ts", obj["ts"].date());
        subobj.done();

        OperationContextImpl txn; // XXX?
        Lock::DBWrite lk(txn.lockState(), "local");
        Helpers::putSingleton(&txn, "local.replset.minvalid", builder.obj());
    }
Beispiel #14
0
 void ReplSetImpl::loadLastOpTimeWritten(bool quiet) {
     OperationContextImpl txn; // XXX?
     Lock::DBRead lk(txn.lockState(), rsoplog);
     BSONObj o;
     if (Helpers::getLast(&txn, rsoplog, o)) {
         lastH = o["h"].numberLong();
         lastOpTimeWritten = o["ts"]._opTime();
         uassert(13290, "bad replSet oplog entry?", quiet || !lastOpTimeWritten.isNull());
     }
 }
    void NetworkInterfaceImpl::runCallbackWithGlobalExclusiveLock(
            const stdx::function<void (OperationContext*)>& callback) {

        std::ostringstream sb;
        sb << "repl" << boost::this_thread::get_id();
        Client::initThreadIfNotAlready(sb.str().c_str());
        OperationContextImpl txn;
        Lock::GlobalWrite lk(txn.lockState());
        callback(&txn);
    }
Beispiel #16
0
        IndexIteratorTests() {
            OperationContextImpl txn;
            Lock::DBLock lk(txn.lockState(), nsToDatabaseSubstring(_ns), MODE_X);
            Client::Context ctx(&txn, _ns);
            WriteUnitOfWork wuow(&txn);

            _db = ctx.db();
            _coll = _db->createCollection(&txn, _ns);
            _catalog = _coll->getIndexCatalog();
            wuow.commit();
        }
Beispiel #17
0
        void run() {
            OperationContextImpl txn;
            Lock::GlobalWrite lk(txn.lockState());

            Database db( &txn, "dbtests_basictests_ownsns", NULL );

            ASSERT( db.ownsNS( "dbtests_basictests_ownsns.x" ) );
            ASSERT( db.ownsNS( "dbtests_basictests_ownsns.x.y" ) );
            ASSERT( !db.ownsNS( "dbtests_basictests_ownsn.x.y" ) );
            ASSERT( !db.ownsNS( "dbtests_basictests_ownsnsa.x.y" ) );
        }
Beispiel #18
0
    /**
     * Checks if this server was started without --replset but has a config in local.system.replset
     * (meaning that this is probably a replica set member started in stand-alone mode).
     *
     * @returns the number of documents in local.system.replset or 0 if this was started with
     *          --replset.
     */
    static unsigned long long checkIfReplMissingFromCommandLine() {
        OperationContextImpl txn;

        // This is helpful for the query below to work as you can't open files when readlocked
        Lock::GlobalWrite lk(txn.lockState());
        if (!repl::replSettings.usingReplSets()) {
            DBDirectClient c(&txn);
            return c.count("local.system.replset");
        }
        return 0;
    }
Beispiel #19
0
    TEST(DBHelperTests, FindDiskLocs) {

        DBDirectClient client;
        OperationContextImpl txn;

        // Some unique tag we can use to make sure we're pulling back the right data
        OID tag = OID::gen();
        client.remove( ns, BSONObj() );

        int numDocsInserted = 10;
        for ( int i = 0; i < numDocsInserted; ++i ) {
            client.insert( ns, BSON( "_id" << i << "tag" << tag ) );
        }

        long long maxSizeBytes = 1024 * 1024 * 1024;

        set<DiskLoc> locs;
        long long numDocsFound;
        long long estSizeBytes;
        {
            // search _id range (0, 10)
            Lock::DBRead lk(txn.lockState(), ns);

            KeyRange range( ns,
                            BSON( "_id" << 0 ),
                            BSON( "_id" << numDocsInserted ),
                            BSON( "_id" << 1 ) );

            Status result = Helpers::getLocsInRange( &txn,
                                                     range,
                                                     maxSizeBytes,
                                                     &locs,
                                                     &numDocsFound,
                                                     &estSizeBytes );

            ASSERT_EQUALS( result, Status::OK() );
            ASSERT_EQUALS( numDocsFound, numDocsInserted );
            ASSERT_NOT_EQUALS( estSizeBytes, 0 );
            ASSERT_LESS_THAN( estSizeBytes, maxSizeBytes );

            Database* db = dbHolder().get(
                                    &txn, nsToDatabase(range.ns), storageGlobalParams.dbpath);
            const Collection* collection = db->getCollection(&txn, ns);

            // Make sure all the disklocs actually correspond to the right info
            for ( set<DiskLoc>::const_iterator it = locs.begin(); it != locs.end(); ++it ) {
                const BSONObj obj = collection->docFor(*it);
                ASSERT_EQUALS(obj["tag"].OID(), tag);
            }
        }
    }
Beispiel #20
0
bool getInitialSyncFlag() {
    OperationContextImpl txn;
    MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
        ScopedTransaction transaction(&txn, MODE_IX);
        Lock::DBLock lk(txn.lockState(), "local", MODE_X);
        BSONObj mv;
        bool found = Helpers::getSingleton(&txn, minvalidNS, mv);
        if (found) {
            return mv[initialSyncFlagString].trueValue();
        }
        return false;
    }
    MONGO_WRITE_CONFLICT_RETRY_LOOP_END(&txn, "getInitialSyncFlags", minvalidNS);
}
Beispiel #21
0
    void FSyncLockThread::doRealWork() {
        SimpleMutex::scoped_lock lkf(filesLockedFsync);

        OperationContextImpl txn;   // XXX?
        Lock::GlobalWrite global(txn.lockState()); // No WriteUnitOfWork needed

        SimpleMutex::scoped_lock lk(fsyncCmd.m);
        
        verify( ! fsyncCmd.locked ); // impossible to get here if locked is true
        try { 
            getDur().syncDataAndTruncateJournal(&txn);
        } 
        catch( std::exception& e ) { 
            error() << "error doing syncDataAndTruncateJournal: " << e.what() << endl;
            fsyncCmd.err = e.what();
            fsyncCmd._threadSync.notify_one();
            fsyncCmd.locked = false;
            return;
        }
        
        global.downgrade();
        
        try {
            StorageEngine* storageEngine = getGlobalEnvironment()->getGlobalStorageEngine();
            storageEngine->flushAllFiles(true);
        }
        catch( std::exception& e ) { 
            error() << "error doing flushAll: " << e.what() << endl;
            fsyncCmd.err = e.what();
            fsyncCmd._threadSync.notify_one();
            fsyncCmd.locked = false;
            return;
        }

        verify( ! fsyncCmd.locked );
        fsyncCmd.locked = true;
        
        fsyncCmd._threadSync.notify_one();

        while ( ! fsyncCmd.pendingUnlock ) {
            fsyncCmd._unlockSync.wait(fsyncCmd.m);
        }
        fsyncCmd.pendingUnlock = false;
        
        fsyncCmd.locked = false;
        fsyncCmd.err = "unlocked";

        fsyncCmd._unlockSync.notify_one();
    }
Beispiel #22
0
    void IndexBuilder::run() {
        Client::initThread(name().c_str());
        LOG(2) << "IndexBuilder building index " << _index;

        OperationContextImpl txn;
        txn.lockState()->setIsBatchWriter(true);

        AuthorizationSession::get(txn.getClient())->grantInternalAuthorization();

        txn.getCurOp()->reset(HostAndPort(), dbInsert);
        NamespaceString ns(_index["ns"].String());

        ScopedTransaction transaction(&txn, MODE_IX);
        Lock::DBLock dlk(txn.lockState(), ns.db(), MODE_X);
        OldClientContext ctx(&txn, ns.getSystemIndexesCollection());

        Database* db = dbHolder().get(&txn, ns.db().toString());

        Status status = _build(&txn, db, true, &dlk);
        if ( !status.isOK() ) {
            error() << "IndexBuilder could not build index: " << status.toString();
            fassert(28555, ErrorCodes::isInterruption(status.code()));
        }
    }
void ServiceContextMongoDTest::_dropAllDBs() {
    OperationContextImpl txn;
    dropAllDatabasesExceptLocal(&txn);

    ScopedTransaction transaction(&txn, MODE_X);
    Lock::GlobalWrite lk(txn.lockState());
    AutoGetDb autoDBLocal(&txn, "local", MODE_X);
    const auto localDB = autoDBLocal.getDb();
    if (localDB) {
        MONGO_WRITE_CONFLICT_RETRY_LOOP_BEGIN {
            // Do not wrap in a WriteUnitOfWork until SERVER-17103 is addressed.
            autoDBLocal.getDb()->dropDatabase(&txn, localDB);
        }
        MONGO_WRITE_CONFLICT_RETRY_LOOP_END(&txn, "_dropAllDBs", "local");
    }
}
Beispiel #24
0
    /** write an op to the oplog that is already built.
        todo : make _logOpRS() call this so we don't repeat ourself?
        */
    void _logOpObjRS(const BSONObj& op) {
        OperationContextImpl txn;
        Lock::DBWrite lk(txn.lockState(), "local");

        const OpTime ts = op["ts"]._opTime();
        long long h = op["h"].numberLong();

        {
            if ( localOplogRSCollection == 0 ) {
                Client::Context ctx(rsoplog, storageGlobalParams.dbpath);
                localDB = ctx.db();
                verify( localDB );
                localOplogRSCollection = localDB->getCollection( &txn, rsoplog );
                massert(13389,
                        "local.oplog.rs missing. did you drop it? if so restart server",
                        localOplogRSCollection);
            }
            Client::Context ctx(rsoplog, localDB);
            checkOplogInsert( localOplogRSCollection->insertDocument( &txn, op, false ) );

            /* todo: now() has code to handle clock skew.  but if the skew server to server is large it will get unhappy.
                     this code (or code in now() maybe) should be improved.
                     */
            if( theReplSet ) {
                if( !(theReplSet->lastOpTimeWritten<ts) ) {
                    log() << "replication oplog stream went back in time. previous timestamp: "
                          << theReplSet->lastOpTimeWritten << " newest timestamp: " << ts
                          << ". attempting to sync directly from primary." << endl;
                    std::string errmsg;
                    BSONObjBuilder result;
                    if (!theReplSet->forceSyncFrom(theReplSet->box.getPrimary()->fullName(),
                                                   errmsg, result)) {
                        log() << "Can't sync from primary: " << errmsg << endl;
                    }
                }
                theReplSet->lastOpTimeWritten = ts;
                theReplSet->lastH = h;
                ctx.getClient()->setLastOp( ts );

                BackgroundSync::notify();
            }
        }

        setNewOptime(ts);
    }
Beispiel #25
0
            void run() {
                const string dbName = "rollback_drop_collection";
                const string droppedName = dbName + ".dropped";
                const string rolledBackName = dbName + ".rolled_back";

                OperationContextImpl txn;

                ScopedTransaction transaction(&txn, MODE_IX);
                Lock::DBLock lk(txn.lockState(), dbName, MODE_X);

                bool justCreated;
                Database* db = dbHolder().openDb(&txn, dbName, &justCreated);
                ASSERT(justCreated);

                {
                    WriteUnitOfWork wunit(&txn);
                    ASSERT_FALSE(db->getCollection(droppedName));
                    Collection* droppedColl;
                    droppedColl = db->createCollection(&txn, droppedName);
                    ASSERT_EQUALS(db->getCollection(droppedName), droppedColl);
                    db->dropCollection(&txn, droppedName);
                    wunit.commit();
                }

                //  Should have been really dropped
                ASSERT_FALSE(db->getCollection(droppedName));

                {
                    WriteUnitOfWork wunit(&txn);
                    ASSERT_FALSE(db->getCollection(rolledBackName));
                    Collection* rolledBackColl = db->createCollection(&txn, rolledBackName);
                    wunit.commit();
                    ASSERT_EQUALS(db->getCollection(rolledBackName), rolledBackColl);
                    db->dropCollection(&txn, rolledBackName);
                    // not committing so dropping should be rolled back
                }

                // The rolledBackCollection dropping should have been rolled back.
                // Original Collection pointers are no longer valid.
                ASSERT(db->getCollection(rolledBackName));

                // The droppedCollection should not have been restored by the rollback.
                ASSERT_FALSE(db->getCollection(droppedName));
            }
Beispiel #26
0
static void logStartup() {
    BSONObjBuilder toLog;
    stringstream id;
    id << getHostNameCached() << "-" << jsTime().asInt64();
    toLog.append("_id", id.str());
    toLog.append("hostname", getHostNameCached());

    toLog.appendTimeT("startTime", time(0));
    toLog.append("startTimeLocal", dateToCtimeString(Date_t::now()));

    toLog.append("cmdLine", serverGlobalParams.parsedOpts);
    toLog.append("pid", ProcessId::getCurrent().asLongLong());


    BSONObjBuilder buildinfo(toLog.subobjStart("buildinfo"));
    appendBuildInfo(buildinfo);
    appendStorageEngineList(&buildinfo);
    buildinfo.doneFast();

    BSONObj o = toLog.obj();

    OperationContextImpl txn;

    ScopedTransaction transaction(&txn, MODE_X);
    Lock::GlobalWrite lk(txn.lockState());
    AutoGetOrCreateDb autoDb(&txn, "local", mongo::MODE_X);
    Database* db = autoDb.getDb();
    const std::string ns = "local.startup_log";
    Collection* collection = db->getCollection(ns);
    WriteUnitOfWork wunit(&txn);
    if (!collection) {
        BSONObj options = BSON("capped" << true << "size" << 10 * 1024 * 1024);
        bool shouldReplicateWrites = txn.writesAreReplicated();
        txn.setReplicatedWrites(false);
        ON_BLOCK_EXIT(&OperationContext::setReplicatedWrites, &txn, shouldReplicateWrites);
        uassertStatusOK(userCreateNS(&txn, db, ns, options));
        collection = db->getCollection(ns);
    }
    invariant(collection);
    uassertStatusOK(collection->insertDocument(&txn, o, false).getStatus());
    wunit.commit();
}
Beispiel #27
0
    void SyncTail::applyOpsToOplog(std::deque<BSONObj>* ops) {
        {
            OperationContextImpl txn; // XXX?
            Lock::DBWrite lk(txn.lockState(), "local");

            while (!ops->empty()) {
                const BSONObj& op = ops->front();
                // this updates theReplSet->lastOpTimeWritten
                _logOpObjRS(op);
                ops->pop_front();
             }
        }

        if (BackgroundSync::get()->isAssumingPrimary()) {
            LOG(1) << "notifying BackgroundSync";
        }
            
        // Update write concern on primary
        BackgroundSync::notify();
    }
Beispiel #28
0
    OpTime SyncTail::applyOpsToOplog(std::deque<BSONObj>* ops) {
        OpTime lastOpTime;
        {
            OperationContextImpl txn; // XXX?
            Lock::DBLock lk(txn.lockState(), "local", MODE_X);
            WriteUnitOfWork wunit(&txn);

            while (!ops->empty()) {
                const BSONObj& op = ops->front();
                // this updates lastOpTimeApplied
                lastOpTime = _logOpObjRS(&txn, op);
                ops->pop_front();
             }
            wunit.commit();
        }

        // Update write concern on primary
        BackgroundSync::get()->notify();
        return lastOpTime;
    }
Beispiel #29
0
void pretouchN(vector<BSONObj>& v, unsigned a, unsigned b) {
    Client* c = currentClient.get();
    if (c == 0) {
        Client::initThread("pretouchN");
        c = &cc();
    }

    OperationContextImpl txn;  // XXX
    ScopedTransaction transaction(&txn, MODE_S);
    Lock::GlobalRead lk(txn.lockState());

    for (unsigned i = a; i <= b; i++) {
        const BSONObj& op = v[i];
        const char* which = "o";
        const char* opType = op.getStringField("op");
        if (*opType == 'i')
            ;
        else if (*opType == 'u')
            which = "o2";
        else
            continue;
        /* todo : other operations */

        try {
            BSONObj o = op.getObjectField(which);
            BSONElement _id;
            if (o.getObjectID(_id)) {
                const char* ns = op.getStringField("ns");
                BSONObjBuilder b;
                b.append(_id);
                BSONObj result;
                Client::Context ctx(&txn, ns);
                if (Helpers::findById(&txn, ctx.db(), ns, b.done(), result))
                    _dummy_z += result.objsize();  // touch
            }
        } catch (DBException& e) {
            log() << "ignoring assertion in pretouchN() " << a << ' ' << b << ' ' << i << ' '
                  << e.toString() << endl;
        }
    }
}
Beispiel #30
0
        void run() {
            for ( int i = 0; i < 10; ++i ) {
                client.insert( ns, BSON( "_id" << i ) );
            }

            {
                // Remove _id range [_min, _max).
                OperationContextImpl txn;
                Lock::DBWrite lk(txn.lockState(), ns);
                Client::Context ctx( ns );

                KeyRange range( ns,
                                BSON( "_id" << _min ),
                                BSON( "_id" << _max ),
                                BSON( "_id" << 1 ) );
                Helpers::removeRange( &txn, range );
            }

            // Check that the expected documents remain.
            ASSERT_EQUALS( expected(), docs() );
        }