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); } }
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); } }
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); }
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); } }
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; }
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; }
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)); } }