Esempio n. 1
0
    void CollectionMap::update_ns(const StringData& ns, const BSONObj &serialized, bool overwrite) {
        if (!Lock::isWriteLocked(ns)) {
            throw RetryWithWriteLock();
        }

        init();
        dassert(allocated()); // cannot update a non-existent metadb

        // Note this ns in the rollback, even though we aren't modifying
        // _collections directly. But we know this operation is part of
        // a scheme to create this namespace or change something about it.
        CollectionMapRollback &rollback = cc().txn().collectionMapRollback();
        rollback.noteNs(ns);

        BSONObj nsobj = BSON("ns" << ns);
        storage::Key sKey(nsobj, NULL);
        DBT ndbt = sKey.dbt();
        DBT ddbt = storage::dbt_make(serialized.objdata(), serialized.objsize());
        DB *db = _metadb->db();
        const int flags = overwrite ? 0 : DB_NOOVERWRITE;
        const int r = db->put(db, cc().txn().db_txn(), &ndbt, &ddbt, flags);
        if (r != 0) {
            storage::handle_ydb_error(r);
        }
    }
Esempio n. 2
0
    void CollectionMap::kill_ns(const StringData& ns) {
        init();
        if (!allocated()) { // that's ok, may dropping something that doesn't exist
            return;
        }
        if (!Lock::isWriteLocked(ns)) {
            throw RetryWithWriteLock();
        }

        // Must copy ns before we delete the collection, otherwise ns will be pointing to freed
        // memory.
        BSONObj nsobj = BSON("ns" << ns);

        CollectionStringMap::const_iterator it = _collections.find(ns);
        if (it != _collections.end()) {
            // Might not be in the _collections map if the ns exists but is closed.
            // Note this ns in the rollback, since we are about to modify its entry.
            CollectionMapRollback &rollback = cc().txn().collectionMapRollback();
            rollback.noteNs(ns);
            shared_ptr<Collection> cl = it->second;
            const int r = _collections.erase(ns);
            verify(r == 1);
            cl->close();
        }

        storage::Key sKey(nsobj, NULL);
        DBT ndbt = sKey.dbt();
        DB *db = _metadb->db();
        int r = db->del(db, cc().txn().db_txn(), &ndbt, 0);
        if (r != 0) {
            storage::handle_ydb_error_fatal(r);
        }
    }
Esempio n. 3
0
    void getMe(BSONObj& me) {
        const string myname = getHostName();
        Client::Transaction transaction(0);            

        // local.me is an identifier for a server for getLastError w:2+
        if (!Collection::findOne("local.me", BSONObj(), me) ||
                !me.hasField("host") || me["host"].String() != myname) {
        
            // cleaning out local.me requires write
            // lock. This is a rare operation, so it should
            // be ok
            if (!Lock::isWriteLocked("local")) {
                throw RetryWithWriteLock();
            }

            // clean out local.me
            deleteObjects("local.me", BSONObj(), false, false);
        
            // repopulate
            BSONObjBuilder b;
            b.appendOID( "_id" , 0 , true );
            b.append( "host", myname );
            me = b.obj();
            updateObjects("local.me", me, BSONObj(), true, false);
        }
        transaction.commit(0);
    }
Esempio n. 4
0
    void NamespaceIndex::kill_ns(const StringData& ns) {
        init();
        if (!allocated()) { // that's ok, may dropping something that doesn't exist
            return;
        }
        if (!Lock::isWriteLocked(ns)) {
            throw RetryWithWriteLock();
        }

        NamespaceDetailsMap::const_iterator it = _namespaces.find(ns);
        if (it != _namespaces.end()) {
            // Might not be in the _namespaces map if the ns exists but is closed.
            // Note this ns in the rollback, since we are about to modify its entry.
            NamespaceIndexRollback &rollback = cc().txn().nsIndexRollback();
            rollback.noteNs(ns);
            shared_ptr<NamespaceDetails> d = it->second;
            const int r = _namespaces.erase(ns);
            verify(r == 1);
            d->close();
        }

        BSONObj nsobj = BSON("ns" << ns);
        storage::Key sKey(nsobj, NULL);
        DBT ndbt = sKey.dbt();
        DB *db = _nsdb->db();
        int r = db->del(db, cc().txn().db_txn(), &ndbt, 0);
        if (r != 0) {
            storage::handle_ydb_error_fatal(r);
        }
    }
Esempio n. 5
0
    void CollectionMap::add_ns(const StringData& ns, shared_ptr<Collection> cl) {
        if (!Lock::isWriteLocked(ns)) {
            throw RetryWithWriteLock();
        }

        init();
        dassert(allocated()); // cannot add to a non-existent metadb

        // Note this ns in the rollback, since we are about to modify its entry.
        CollectionMapRollback &rollback = cc().txn().collectionMapRollback();
        rollback.noteNs(ns);

        verify(!_collections[ns]);
        _collections[ns] = cl;
    }
Esempio n. 6
0
    void NamespaceIndex::add_ns(const StringData& ns, shared_ptr<NamespaceDetails> details) {
        if (!Lock::isWriteLocked(ns)) {
            throw RetryWithWriteLock();
        }

        init();
        dassert(allocated()); // cannot add to a non-existent nsdb

        // Note this ns in the rollback, since we are about to modify its entry.
        NamespaceIndexRollback &rollback = cc().txn().nsIndexRollback();
        rollback.noteNs(ns);

        verify(!_namespaces[ns]);
        _namespaces[ns] = details;
    }
Esempio n. 7
0
    NOINLINE_DECL void CollectionMap::_init(bool may_create) {
        const BSONObj keyPattern = BSON("ns" << 1 );
        const BSONObj info = BSON("key" << keyPattern);
        Descriptor descriptor(keyPattern);

        try {
            // Try first without the create flag, because we're not sure if we
            // have a write lock just yet. It won't matter if the metadb exists.
            _metadb.reset(new storage::Dictionary(_metadname, info, descriptor, false, false));
        } catch (storage::Dictionary::NeedsCreate) {
            if (!may_create) {
                // didn't find on disk and we can't create it
                return;
            } else if (!Lock::isWriteLocked(_database)) {
                // We would create it, but we're not write locked. Retry.
                throw RetryWithWriteLock("creating new database " + _database);
            }
            CollectionMapRollback &rollback = cc().txn().collectionMapRollback();
            rollback.noteCreate(_database);
            _metadb.reset(new storage::Dictionary(_metadname, info, descriptor, true, false));
        }
    }